diff --git a/src/core/dbus-job.c b/src/core/dbus-job.c index d5b50e85183..693efbbcbaf 100644 --- a/src/core/dbus-job.c +++ b/src/core/dbus-job.c @@ -54,7 +54,7 @@ int bus_job_method_cancel(sd_bus_message *message, void *userdata, sd_bus_error if (!sd_bus_track_contains(j->bus_track, sd_bus_message_get_sender(message))) { /* And for everybody else consult polkit */ - r = bus_verify_manage_units_async(j->unit->manager, message, error); + r = bus_verify_manage_units_async(j->manager, message, error); if (r < 0) return r; if (r == 0) @@ -263,7 +263,7 @@ void bus_job_send_pending_change_signal(Job *j, bool including_new) { if (!j->sent_dbus_new_signal && !including_new) return; - if (MANAGER_IS_RELOADING(j->unit->manager)) + if (MANAGER_IS_RELOADING(j->manager)) return; bus_job_send_change_signal(j); @@ -332,12 +332,12 @@ static int bus_job_allocate_bus_track(Job *j) { if (j->bus_track) return 0; - return sd_bus_track_new(j->unit->manager->api_bus, &j->bus_track, bus_job_track_handler, j); + return sd_bus_track_new(j->manager->api_bus, &j->bus_track, bus_job_track_handler, j); } int bus_job_coldplug_bus_track(Job *j) { - int r; _cleanup_strv_free_ char **deserialized_clients = NULL; + int r; assert(j); @@ -362,7 +362,7 @@ int bus_job_track_sender(Job *j, sd_bus_message *m) { assert(j); assert(m); - if (sd_bus_message_get_bus(m) != j->unit->manager->api_bus) { + if (sd_bus_message_get_bus(m) != j->manager->api_bus) { j->ref_by_private_bus = true; return 0; } diff --git a/src/core/job.c b/src/core/job.c index c6b48035a79..2f19468a954 100644 --- a/src/core/job.c +++ b/src/core/job.c @@ -133,6 +133,7 @@ Job* job_free(Job *j) { static void job_set_state(Job *j, JobState state) { assert(j); + assert(j->manager); assert(state >= 0); assert(state < _JOB_STATE_MAX); @@ -145,15 +146,15 @@ static void job_set_state(Job *j, JobState state) { return; if (j->state == JOB_RUNNING) - j->unit->manager->n_running_jobs++; + j->manager->n_running_jobs++; else { assert(j->state == JOB_WAITING); - assert(j->unit->manager->n_running_jobs > 0); + assert(j->manager->n_running_jobs > 0); - j->unit->manager->n_running_jobs--; + j->manager->n_running_jobs--; - if (j->unit->manager->n_running_jobs <= 0) - j->unit->manager->jobs_in_progress_event_source = sd_event_source_disable_unref(j->unit->manager->jobs_in_progress_event_source); + if (j->manager->n_running_jobs <= 0) + j->manager->jobs_in_progress_event_source = sd_event_source_disable_unref(j->manager->jobs_in_progress_event_source); } } @@ -281,6 +282,8 @@ int job_install_deserialized(Job *j) { Job **pj; int r; + assert(j); + assert(j->manager); assert(!j->installed); if (j->type < 0 || j->type >= _JOB_TYPE_MAX_IN_TRANSACTION) @@ -307,7 +310,7 @@ int job_install_deserialized(Job *j) { j->installed = true; if (j->state == JOB_RUNNING) - j->unit->manager->n_running_jobs++; + j->manager->n_running_jobs++; log_unit_debug(j->unit, "Reinstalled deserialized job %s/%s as %u", @@ -1375,6 +1378,7 @@ int job_coldplug(Job *j) { void job_shutdown_magic(Job *j) { assert(j); + assert(j->manager); /* The shutdown target gets some special treatment here: we * tell the kernel to begin with flushing its disk caches, to @@ -1391,15 +1395,15 @@ void job_shutdown_magic(Job *j) { return; /* This is the very beginning of the shutdown phase, so take the timestamp here */ - dual_timestamp_now(ASSERT_PTR(j->manager)->timestamps + MANAGER_TIMESTAMP_SHUTDOWN_START); + dual_timestamp_now(j->manager->timestamps + MANAGER_TIMESTAMP_SHUTDOWN_START); if (!MANAGER_IS_SYSTEM(j->manager)) return; /* In case messages on console has been disabled on boot */ - j->unit->manager->no_console_output = false; + j->manager->no_console_output = false; - manager_invalidate_startup_units(j->unit->manager); + manager_invalidate_startup_units(j->manager); if (detect_container() > 0) return; @@ -1439,6 +1443,7 @@ bool job_may_gc(Job *j) { Unit *other; assert(j); + assert(j->manager); /* Checks whether this job should be GC'ed away. We only do this for jobs of units that have no effect on their * own and just track external state. For now the only unit type that qualifies for this are .device units. @@ -1459,7 +1464,7 @@ bool job_may_gc(Job *j) { * referenced by one, and reset this whenever we notice that no private bus connections are around. This means * the GC is a bit too conservative when it comes to jobs created by private bus connections. */ if (j->ref_by_private_bus) { - if (set_isempty(j->unit->manager->private_buses)) + if (set_isempty(j->manager->private_buses)) j->ref_by_private_bus = false; else return false; @@ -1482,6 +1487,7 @@ bool job_may_gc(Job *j) { void job_add_to_gc_queue(Job *j) { assert(j); + assert(j->manager); if (j->in_gc_queue) return; @@ -1489,7 +1495,7 @@ void job_add_to_gc_queue(Job *j) { if (!job_may_gc(j)) return; - LIST_PREPEND(gc_queue, j->unit->manager->gc_job_queue, j); + LIST_PREPEND(gc_queue, j->manager->gc_job_queue, j); j->in_gc_queue = true; } diff --git a/src/core/manager-serialize.c b/src/core/manager-serialize.c index 6008e5655e8..3c647557433 100644 --- a/src/core/manager-serialize.c +++ b/src/core/manager-serialize.c @@ -109,6 +109,7 @@ int manager_serialize( (void) serialize_usec(f, "pretimeout-watchdog-overridden", m->watchdog_overridden[WATCHDOG_PRETIMEOUT]); (void) serialize_item(f, "pretimeout-watchdog-governor-overridden", m->watchdog_pretimeout_governor_overridden); + (void) serialize_item(f, "previous-objective", manager_objective_to_string(m->objective)); (void) serialize_item_format(f, "soft-reboots-count", "%u", m->soft_reboots_count); for (ManagerTimestamp q = 0; q < _MANAGER_TIMESTAMP_MAX; q++) { @@ -158,9 +159,6 @@ int manager_serialize( (void) serialize_ratelimit(f, "dump-ratelimit", &m->dump_ratelimit); (void) serialize_ratelimit(f, "reload-reexec-ratelimit", &m->reload_reexec_ratelimit); - if (m->objective >= 0 && m->objective < _MANAGER_OBJECTIVE_MAX) - (void) serialize_item_format(f, "previous-objective", "%u", (unsigned) m->objective); - bus_track_serialize(m->subscribed, f, "subscribed"); r = dynamic_user_serialize(m, f, fds); @@ -533,12 +531,13 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) { else m->soft_reboots_count = n; } else if ((val = startswith(l, "previous-objective="))) { - unsigned n; + ManagerObjective objective; - if (safe_atou(val, &n) < 0 || n >= _MANAGER_OBJECTIVE_MAX) - log_notice("Failed to parse objective '%s', ignoring.", val); + objective = manager_objective_from_string(val); + if (objective < 0) + log_notice("Failed to parse previous objective '%s', ignoring.", val); else - m->previous_objective = n; + m->previous_objective = objective; } else { ManagerTimestamp q; diff --git a/src/core/manager.c b/src/core/manager.c index 3ffe0f87c0c..d113089e3e3 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -1974,6 +1974,15 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds, const char *roo return log_error_errno(r, "Deserialization failed: %m"); } + if (m->previous_objective >= 0) { + if (IN_SET(m->previous_objective, MANAGER_REEXECUTE, MANAGER_SOFT_REBOOT, MANAGER_SWITCH_ROOT)) + log_debug("Launching as effect of a '%s' operation.", + manager_objective_to_string(m->previous_objective)); + else + log_warning("Got unexpected previous objective '%s', ignoring.", + manager_objective_to_string(m->previous_objective)); + } + /* If we are in a new soft-reboot iteration bump the counter now before starting units, so * that they can reliably read it. We get the previous objective from serialized state. */ if (m->previous_objective == MANAGER_SOFT_REBOOT) @@ -3698,13 +3707,15 @@ static void manager_notify_finished(Manager *m) { if (MANAGER_IS_SYSTEM(m) && m->soft_reboots_count > 0) { /* The soft-reboot case, where we only report data for the last reboot */ firmware_usec = loader_usec = initrd_usec = kernel_usec = 0; - total_usec = userspace_usec = usec_sub_unsigned(m->timestamps[MANAGER_TIMESTAMP_FINISH].monotonic, m->timestamps[MANAGER_TIMESTAMP_SHUTDOWN_START].monotonic); + total_usec = userspace_usec = usec_sub_unsigned(m->timestamps[MANAGER_TIMESTAMP_FINISH].monotonic, + m->timestamps[MANAGER_TIMESTAMP_SHUTDOWN_START].monotonic); log_struct(LOG_INFO, "MESSAGE_ID=" SD_MESSAGE_STARTUP_FINISHED_STR, "USERSPACE_USEC="USEC_FMT, userspace_usec, - LOG_MESSAGE("Soft-reboot finished in %s.", - FORMAT_TIMESPAN(total_usec, USEC_PER_MSEC))); + LOG_MESSAGE("Soft-reboot finished in %s, counter is now at %u.", + FORMAT_TIMESPAN(total_usec, USEC_PER_MSEC), + m->soft_reboots_count)); } else if (MANAGER_IS_SYSTEM(m) && detect_container() <= 0) { char buf[FORMAT_TIMESPAN_MAX + STRLEN(" (firmware) + ") + FORMAT_TIMESPAN_MAX + STRLEN(" (loader) + ")] = {}; @@ -4411,7 +4422,7 @@ void manager_override_show_status(Manager *m, ShowStatus mode, const char *reaso set_show_status_marker(show_status_on(mode)); } -const char *manager_get_confirm_spawn(Manager *m) { +const char* manager_get_confirm_spawn(Manager *m) { static int last_errno = 0; struct stat st; int r; @@ -5034,7 +5045,7 @@ LogTarget manager_get_executor_log_target(Manager *m) { return LOG_TARGET_KMSG; } -static const char *const manager_state_table[_MANAGER_STATE_MAX] = { +static const char* const manager_state_table[_MANAGER_STATE_MAX] = { [MANAGER_INITIALIZING] = "initializing", [MANAGER_STARTING] = "starting", [MANAGER_RUNNING] = "running", @@ -5045,7 +5056,22 @@ static const char *const manager_state_table[_MANAGER_STATE_MAX] = { DEFINE_STRING_TABLE_LOOKUP(manager_state, ManagerState); -static const char *const manager_timestamp_table[_MANAGER_TIMESTAMP_MAX] = { +static const char* const manager_objective_table[_MANAGER_OBJECTIVE_MAX] = { + [MANAGER_OK] = "ok", + [MANAGER_EXIT] = "exit", + [MANAGER_RELOAD] = "reload", + [MANAGER_REEXECUTE] = "reexecute", + [MANAGER_REBOOT] = "reboot", + [MANAGER_SOFT_REBOOT] = "soft-reboot", + [MANAGER_POWEROFF] = "poweroff", + [MANAGER_HALT] = "halt", + [MANAGER_KEXEC] = "kexec", + [MANAGER_SWITCH_ROOT] = "switch-root", +}; + +DEFINE_STRING_TABLE_LOOKUP(manager_objective, ManagerObjective); + +static const char* const manager_timestamp_table[_MANAGER_TIMESTAMP_MAX] = { [MANAGER_TIMESTAMP_FIRMWARE] = "firmware", [MANAGER_TIMESTAMP_LOADER] = "loader", [MANAGER_TIMESTAMP_KERNEL] = "kernel", diff --git a/src/core/manager.h b/src/core/manager.h index 70ae78aa849..c4ad42293e5 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -627,13 +627,16 @@ void manager_restore_original_log_level(Manager *m); void manager_override_log_target(Manager *m, LogTarget target); void manager_restore_original_log_target(Manager *m); -const char *manager_state_to_string(ManagerState m) _const_; -ManagerState manager_state_from_string(const char *s) _pure_; - -const char *manager_get_confirm_spawn(Manager *m); +const char* manager_get_confirm_spawn(Manager *m); void manager_disable_confirm_spawn(void); -const char *manager_timestamp_to_string(ManagerTimestamp m) _const_; +const char* manager_state_to_string(ManagerState m) _const_; +ManagerState manager_state_from_string(const char *s) _pure_; + +const char* manager_objective_to_string(ManagerObjective m) _const_; +ManagerObjective manager_objective_from_string(const char *s) _pure_; + +const char* manager_timestamp_to_string(ManagerTimestamp m) _const_; ManagerTimestamp manager_timestamp_from_string(const char *s) _pure_; ManagerTimestamp manager_timestamp_initrd_mangle(ManagerTimestamp s);