}
void manager_flip_auto_status(Manager *m, bool enable) {
+ assert(m);
+
if (enable) {
if (m->show_status == SHOW_STATUS_AUTO)
manager_set_show_status(m, SHOW_STATUS_TEMPORARY);
if (r < 0)
goto fail;
+ r = set_ensure_allocated(&m->failed_units, trivial_hash_func, trivial_compare_func);
+ if (r < 0)
+ goto fail;
+
r = sd_event_default(&m->event);
if (r < 0)
goto fail;
hashmap_free(m->watch_pids2);
hashmap_free(m->watch_bus);
+ set_free(m->failed_units);
+
sd_event_source_unref(m->signal_event_source);
sd_event_source_unref(m->notify_event_source);
sd_event_source_unref(m->time_change_event_source);
break;
}
+ if (fflush(f)) {
+ log_warning("Failed to flush status stream");
+ break;
+ }
+
log_dump(LOG_INFO, dump);
break;
}
RATELIMIT_DEFINE(rl, 1*USEC_PER_SEC, 50000);
assert(m);
- m->exit_code = MANAGER_RUNNING;
+ m->exit_code = MANAGER_OK;
/* Release the path cache */
set_free_free(m->unit_path_cache);
if (r < 0)
return r;
- while (m->exit_code == MANAGER_RUNNING) {
+ while (m->exit_code == MANAGER_OK) {
usec_t wait_usec;
if (m->runtime_watchdog > 0 && m->running_as == SYSTEMD_SYSTEM)
return r;
}
-static bool manager_is_booting_or_shutting_down(Manager *m) {
- Unit *u;
-
- assert(m);
-
- /* Is the initial job still around? */
- if (manager_get_job(m, m->default_unit_job_id))
- return true;
-
- /* Is there a job for the shutdown target? */
- u = manager_get_unit(m, SPECIAL_SHUTDOWN_TARGET);
- if (u)
- return !!u->job;
-
- return false;
-}
-
bool manager_is_reloading_or_reexecuting(Manager *m) {
assert(m);
m->jobs_in_progress_event_source = sd_event_source_unref(m->jobs_in_progress_event_source);
if (hashmap_size(m->jobs) > 0) {
+
if (m->jobs_in_progress_event_source) {
- uint64_t next = now(CLOCK_MONOTONIC) + JOBS_IN_PROGRESS_WAIT_USEC;
- sd_event_source_set_time(m->jobs_in_progress_event_source, next);
+ sd_event_source_set_time(m->jobs_in_progress_event_source,
+ now(CLOCK_MONOTONIC) + JOBS_IN_PROGRESS_WAIT_USEC);
}
+
return;
}
argv[4] = NULL;
RUN_WITH_UMASK(0022)
- execute_directory(generator_path, d, (char**) argv);
+ execute_directory(generator_path, d, DEFAULT_TIMEOUT_USEC, (char**) argv);
finish:
trim_generator_dir(m, &m->generator_unit_path);
if (m->no_console_output)
return false;
+ if (!IN_SET(manager_state(m), MANAGER_STARTING, MANAGER_STOPPING))
+ return false;
+
if (m->show_status > 0)
return true;
if (ephemeral && m->n_on_console > 0)
return;
- if (!manager_is_booting_or_shutting_down(m))
- return;
-
va_start(ap, format);
status_vprintf(status, true, ephemeral, format, ap);
va_end(ap);
}
const char *manager_get_runtime_prefix(Manager *m) {
+ assert(m);
return m->running_as == SYSTEMD_SYSTEM ?
"/run" :
getenv("XDG_RUNTIME_DIR");
}
+
+ManagerState manager_state(Manager *m) {
+ Unit *u;
+
+ assert(m);
+
+ /* Did we ever finish booting? If not then we are still starting up */
+ if (!dual_timestamp_is_set(&m->finish_timestamp))
+ return MANAGER_STARTING;
+
+ /* Is the special shutdown target queued? If so, we are in shutdown state */
+ u = manager_get_unit(m, SPECIAL_SHUTDOWN_TARGET);
+ if (u && u->job && IN_SET(u->job->type, JOB_START, JOB_RESTART, JOB_TRY_RESTART, JOB_RELOAD_OR_START))
+ return MANAGER_STOPPING;
+
+ /* Are the rescue or emergency targets active or queued? If so we are in maintenance state */
+ u = manager_get_unit(m, SPECIAL_RESCUE_TARGET);
+ if (u && (UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)) ||
+ (u->job && IN_SET(u->job->type, JOB_START, JOB_RESTART, JOB_TRY_RESTART, JOB_RELOAD_OR_START))))
+ return MANAGER_MAINTENANCE;
+
+ u = manager_get_unit(m, SPECIAL_EMERGENCY_TARGET);
+ if (u && (UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)) ||
+ (u->job && IN_SET(u->job->type, JOB_START, JOB_RESTART, JOB_TRY_RESTART, JOB_RELOAD_OR_START))))
+ return MANAGER_MAINTENANCE;
+
+ /* Are there any failed units? If so, we are in degraded mode */
+ if (set_size(m->failed_units) > 0)
+ return MANAGER_DEGRADED;
+
+ return MANAGER_RUNNING;
+}
+
+static const char *const manager_state_table[_MANAGER_STATE_MAX] = {
+ [MANAGER_STARTING] = "starting",
+ [MANAGER_RUNNING] = "running",
+ [MANAGER_DEGRADED] = "degraded",
+ [MANAGER_MAINTENANCE] = "maintenance",
+ [MANAGER_STOPPING] = "stopping",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(manager_state, ManagerState);