]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
pid1: rework handling of m->show_status
authorFranck Bui <fbui@suse.com>
Mon, 27 Apr 2020 09:06:34 +0000 (11:06 +0200)
committerFranck Bui <fbui@suse.com>
Tue, 9 Jun 2020 07:16:54 +0000 (09:16 +0200)
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.

src/core/dbus-manager.c
src/core/manager.c
src/core/manager.h

index 4fd499603035a7a0d92285f7548dced580f14197..6763c1959079acddb40a568589946eccbe18d5c4 100644 (file)
@@ -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(
index e3dc658cee6c269ee3f53af3d55374143c94dbb8..ecca2f719785462fafcaf34c2f0088a8a55f8321 100644 (file)
@@ -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, ...) {
index a29d976eae531cab80715d9cebb77bf906f514ac..259548e241c0e20da3c802429bcb707cdbd6b871 100644 (file)
@@ -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);