diff options
Diffstat (limited to 'src/sulogin-shell/sulogin-shell.c')
-rw-r--r-- | src/sulogin-shell/sulogin-shell.c | 64 |
1 files changed, 47 insertions, 17 deletions
diff --git a/src/sulogin-shell/sulogin-shell.c b/src/sulogin-shell/sulogin-shell.c index 7933ddcc21..70659df417 100644 --- a/src/sulogin-shell/sulogin-shell.c +++ b/src/sulogin-shell/sulogin-shell.c @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ /*** This file is part of systemd. @@ -22,21 +23,43 @@ #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"); @@ -56,14 +79,12 @@ static int start_default_target(void) { return r; } -static void fork_wait(const char* const cmdline[]) { +static int fork_wait(const char* const cmdline[]) { pid_t pid; pid = fork(); - if (pid < 0) { - log_error_errno(errno, "fork(): %m"); - return; - } + if (pid < 0) + return log_error_errno(errno, "fork(): %m"); if (pid == 0) { /* Child */ @@ -77,18 +98,19 @@ static void fork_wait(const char* const cmdline[]) { _exit(EXIT_FAILURE); /* Operational error */ } - wait_for_terminate_and_warn(cmdline[0], pid, false); + return wait_for_terminate_and_warn(cmdline[0], pid, false); } static void print_mode(const char* mode) { printf("You are in %s mode. After logging in, type \"journalctl -xb\" to view\n" - "system logs, \"systemctl reboot\" to reboot, \"systemctl default\" or ^D to boot\n" - "into default mode.\n", mode); + "system logs, \"systemctl reboot\" to reboot, \"systemctl default\" or \"exit\"\n" + "to boot into default mode.\n", mode); fflush(stdout); } 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); @@ -97,9 +119,17 @@ int main(int argc, char *argv[]) { print_mode(argc > 1 ? argv[1] : ""); - fork_wait(sulogin_cmdline); + (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; } |