From: Franck Bui Date: Mon, 27 Apr 2020 09:06:34 +0000 (+0200) Subject: pid1: rework handling of m->show_status X-Git-Tag: v246-rc1~130^2~3 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=44a419540e262c46bcd841a49ac8c59ac4149dc1;p=thirdparty%2Fsystemd.git pid1: rework handling of m->show_status The fact that m->show_status was serialized/deserialized made impossible any further customisation of this setting via system.conf. IOW the value was basically always locked unless it was changed via signals. This patch reworks the handling of m->show_status but also makes sure that if a new value was changed via the signal API then this value is kept and preserved accross PID1 reexecuting or reloading. Note: this effectively means that once the value is set via the signal interface, it can be changed again only through the signal API. --- diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index 4fd49960303..6763c195907 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -234,14 +234,12 @@ static int property_get_show_status( sd_bus_error *error) { Manager *m = userdata; - int b; + assert(m); assert(bus); assert(reply); - assert(m); - b = show_status_on(m->show_status); - return sd_bus_message_append_basic(reply, 'b', &b); + return sd_bus_message_append(reply, "b", manager_get_show_status_on(m)); } static int property_get_runtime_watchdog( diff --git a/src/core/manager.c b/src/core/manager.c index e3dc658cee6..ecca2f71978 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -779,6 +779,8 @@ int manager_new(UnitFileScope scope, ManagerTestRunFlags test_run_flags, Manager .watchdog_overridden[WATCHDOG_REBOOT] = USEC_INFINITY, .watchdog_overridden[WATCHDOG_KEXEC] = USEC_INFINITY, + .show_status_overridden = _SHOW_STATUS_INVALID, + .notify_fd = -1, .cgroups_agent_fd = -1, .signal_fd = -1, @@ -2759,11 +2761,11 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t switch (sfsi.ssi_signo - SIGRTMIN) { case 20: - manager_set_show_status(m, SHOW_STATUS_YES, "signal"); + manager_set_show_status_overridden(m, SHOW_STATUS_YES, "signal"); break; case 21: - manager_set_show_status(m, SHOW_STATUS_NO, "signal"); + manager_set_show_status_overridden(m, SHOW_STATUS_NO, "signal"); break; case 22: @@ -3219,9 +3221,9 @@ int manager_serialize( /* After switching root, udevd has not been started yet. So, enumeration results should not be emitted. */ (void) serialize_bool(f, "honor-device-enumeration", !switching_root); - t = show_status_to_string(m->show_status); - if (t) - (void) serialize_item(f, "show-status", t); + if (m->show_status_overridden != _SHOW_STATUS_INVALID) + (void) serialize_item(f, "show-status-overridden", + show_status_to_string(m->show_status_overridden)); if (m->log_level_overridden) (void) serialize_item_format(f, "log-level-override", "%i", log_get_max_level()); @@ -3568,14 +3570,14 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) { else m->honor_device_enumeration = b; - } else if ((val = startswith(l, "show-status="))) { + } else if ((val = startswith(l, "show-status-overridden="))) { ShowStatus s; s = show_status_from_string(val); if (s < 0) - log_notice("Failed to parse show-status flag '%s', ignoring.", val); + log_notice("Failed to parse show-status-overridden flag '%s', ignoring.", val); else - manager_set_show_status(m, s, "deserialization"); + manager_set_show_status_overridden(m, s, "deserialize"); } else if ((val = startswith(l, "log-level-override="))) { int level; @@ -4264,30 +4266,78 @@ void manager_recheck_journal(Manager *m) { log_open(); } -void manager_set_show_status(Manager *m, ShowStatus mode, const char *reason) { - bool enabled; +static ShowStatus manager_get_show_status(Manager *m) { + assert(m); + + if (MANAGER_IS_USER(m)) + return _SHOW_STATUS_INVALID; + + if (m->show_status_overridden != _SHOW_STATUS_INVALID) + return m->show_status_overridden; + + return m->show_status; +} + +bool manager_get_show_status_on(Manager *m) { + assert(m); + + return show_status_on(manager_get_show_status(m)); +} +void manager_set_show_status(Manager *m, ShowStatus mode, const char *reason) { assert(m); + assert(reason); assert(mode >= 0 && mode < _SHOW_STATUS_MAX); - if (!MANAGER_IS_SYSTEM(m)) + if (MANAGER_IS_USER(m)) return; if (mode == m->show_status) return; - enabled = show_status_on(mode); + if (m->show_status_overridden == _SHOW_STATUS_INVALID) { + bool enabled; + + enabled = show_status_on(mode); + log_debug("%s (%s) showing of status (%s).", + enabled ? "Enabling" : "Disabling", + strna(show_status_to_string(mode)), + reason); + + if (enabled) + (void) touch("/run/systemd/show-status"); + else + (void) unlink("/run/systemd/show-status"); + } + + m->show_status = mode; +} + +void manager_set_show_status_overridden(Manager *m, ShowStatus mode, const char *reason) { + assert(m); + assert(mode < _SHOW_STATUS_MAX); + + if (MANAGER_IS_USER(m)) + return; + + if (mode == m->show_status_overridden) + return; + + m->show_status_overridden = mode; + + if (mode == _SHOW_STATUS_INVALID) + mode = m->show_status; + log_debug("%s (%s) showing of status (%s).", - enabled ? "Enabling" : "Disabling", + m->show_status_overridden != _SHOW_STATUS_INVALID ? "Overriding" : "Restoring", strna(show_status_to_string(mode)), reason); - m->show_status = mode; - - if (enabled) + if (show_status_on(mode)) (void) touch("/run/systemd/show-status"); else (void) unlink("/run/systemd/show-status"); + } const char *manager_get_confirm_spawn(Manager *m) { @@ -4381,7 +4431,7 @@ static bool manager_should_show_status(Manager *m, StatusType type) { if (type == STATUS_TYPE_NOTICE && m->show_status != SHOW_STATUS_NO) return true; - return show_status_on(m->show_status); + return manager_get_show_status_on(m); } void manager_status_printf(Manager *m, StatusType type, const char *status, const char *format, ...) { diff --git a/src/core/manager.h b/src/core/manager.h index a29d976eae5..259548e241c 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -335,6 +335,7 @@ struct Manager { uint8_t return_value; ShowStatus show_status; + ShowStatus show_status_overridden; StatusUnitFormat status_unit_format; char *confirm_spawn; bool no_console_output; @@ -512,7 +513,10 @@ void disable_printk_ratelimit(void); void manager_recheck_dbus(Manager *m); void manager_recheck_journal(Manager *m); +bool manager_get_show_status_on(Manager *m); void manager_set_show_status(Manager *m, ShowStatus mode, const char *reason); +void manager_set_show_status_overridden(Manager *m, ShowStatus mode, const char *reason); + void manager_set_first_boot(Manager *m, bool b); void manager_status_printf(Manager *m, StatusType type, const char *status, const char *format, ...) _printf_(4,5);