]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sulogin-shell: do daemon-reload before starting default target
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 7 Dec 2017 09:33:11 +0000 (10:33 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 7 Dec 2017 11:34:31 +0000 (12:34 +0100)
If the user modifies configuration, e.g. /etc/fstab, they might forget to tell
systemd about the changes. Let's do a reload for them.

Note that doing a reload should be safe, because emergency and rescue modes are
"single threaded" and nothing should be doing changes at the point where we are
exiting from the sushell. Also, daemon-reload can be implicitly called at
various moments, so we can ignore the case where the user did some incompatible
changes on disk and is counting on systemd never reloading and picking them up.

C.f. #7565.

src/sulogin-shell/sulogin-shell.c

index 6dbe0935cbfe899f9acc6a2023989e95bf2b1aea..82bb0e7f681ad0f5ad68adde50cb4b6235e933cb 100644 (file)
 
 #include "bus-util.h"
 #include "bus-error.h"
+#include "def.h"
 #include "log.h"
 #include "process-util.h"
 #include "sd-bus.h"
 #include "signal-util.h"
 
-static int start_default_target(void) {
+static int reload_manager(sd_bus *bus) {
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
-        _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
+        _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
         int r;
 
-        r = bus_connect_system_systemd(&bus);
-        if (r < 0) {
-                log_error_errno(r, "Failed to get D-Bus connection: %m");
-                return false;
-        }
+        log_info("Reloading system manager configuration");
+
+        r = sd_bus_message_new_method_call(
+                        bus,
+                        &m,
+                        "org.freedesktop.systemd1",
+                        "/org/freedesktop/systemd1",
+                        "org.freedesktop.systemd1.Manager",
+                        "Reload");
+        if (r < 0)
+                return bus_log_create_error(r);
+
+        /* Note we use an extra-long timeout here. This is because a reload or reexec means generators are rerun which
+         * are timed out after DEFAULT_TIMEOUT_USEC. Let's use twice that time here, so that the generators can have
+         * their timeout, and for everything else there's the same time budget in place. */
+
+        r = sd_bus_call(bus, m, DEFAULT_TIMEOUT_USEC * 2, &error, NULL);
+        if (r < 0)
+                return log_error_errno(r, "Failed to reload daemon: %s", bus_error_message(&error, r));
+
+        return 0;
+}
+
+static int start_default_target(sd_bus *bus) {
+        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+        int r;
 
         log_info("Starting default target");
 
@@ -88,6 +110,7 @@ static void print_mode(const char* mode) {
 
 int main(int argc, char *argv[]) {
         static const char* const sulogin_cmdline[] = {SULOGIN, NULL};
+        _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
         int r;
 
         log_set_target(LOG_TARGET_AUTO);
@@ -98,7 +121,15 @@ int main(int argc, char *argv[]) {
 
         (void) fork_wait(sulogin_cmdline);
 
-        r = start_default_target();
+        r = bus_connect_system_systemd(&bus);
+        if (r < 0) {
+                log_warning_errno(r, "Failed to get D-Bus connection: %m");
+                r = 0;
+        } else {
+                (void) reload_manager(bus);
+
+                r = start_default_target(bus);
+        }
 
         return r >= 0 ? EXIT_SUCCESS : EXIT_FAILURE;
 }