From e821f6a916c19f148435038be21faeb49beac68c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 7 Dec 2017 10:44:43 +0100 Subject: [PATCH 1/4] meson: place systemd-sulogin-shell in build/ We do that will all executables so that it's easy to call them. --- meson.build | 10 +++++++++- src/sulogin-shell/meson.build | 25 ------------------------- 2 files changed, 9 insertions(+), 26 deletions(-) delete mode 100644 src/sulogin-shell/meson.build diff --git a/meson.build b/meson.build index 3bdd87fc6b3..c0b36a98f2e 100644 --- a/meson.build +++ b/meson.build @@ -1292,7 +1292,6 @@ subdir('src/resolve') subdir('src/timedate') subdir('src/timesync') subdir('src/vconsole') -subdir('src/sulogin-shell') subdir('src/boot/efi') subdir('src/test') @@ -2370,6 +2369,15 @@ if conf.get('ENABLE_NETWORKD') == 1 install_dir : rootbindir) public_programs += [exe] endif + +executable('systemd-sulogin-shell', + ['src/sulogin-shell/sulogin-shell.c'], + include_directories : includes, + link_with : [libshared], + install_rpath : rootlibexecdir, + install : true, + install_dir : rootlibexecdir) + ############################################################ foreach tuple : tests diff --git a/src/sulogin-shell/meson.build b/src/sulogin-shell/meson.build deleted file mode 100644 index 1617258b798..00000000000 --- a/src/sulogin-shell/meson.build +++ /dev/null @@ -1,25 +0,0 @@ -# SPDX-License-Identifier: LGPL-2.1+ -# -# Copyright 2017 Zbigniew Jędrzejewski-Szmek -# -# systemd is free software; you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation; either version 2.1 of the License, or -# (at your option) any later version. -# -# systemd is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with systemd; If not, see . - -executable('systemd-sulogin-shell', - ['sulogin-shell.c'], - include_directories : includes, - link_with : [libshared], - dependencies : [], - install_rpath : rootlibexecdir, - install : true, - install_dir : rootlibexecdir) From cccb78f09363140d873e8d26355593e22d0cfcea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 7 Dec 2017 10:51:03 +0100 Subject: [PATCH 2/4] sulogin-shell: simplify returns from a function This is actually slightly safer because it allows gcc to make sure that all code paths either call return or are noreturn. But the real motivation is just to follow the usual style and make it a bit shorter. --- src/sulogin-shell/sulogin-shell.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/sulogin-shell/sulogin-shell.c b/src/sulogin-shell/sulogin-shell.c index b21d61d3178..6dbe0935cbf 100644 --- a/src/sulogin-shell/sulogin-shell.c +++ b/src/sulogin-shell/sulogin-shell.c @@ -57,14 +57,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 */ @@ -78,7 +76,7 @@ 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) { @@ -98,7 +96,7 @@ 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(); From 375c3f6aae10a830d416f66dc766f3d6793670fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 7 Dec 2017 10:33:11 +0100 Subject: [PATCH 3/4] sulogin-shell: do daemon-reload before starting default target 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 | 47 +++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/src/sulogin-shell/sulogin-shell.c b/src/sulogin-shell/sulogin-shell.c index 6dbe0935cbf..82bb0e7f681 100644 --- a/src/sulogin-shell/sulogin-shell.c +++ b/src/sulogin-shell/sulogin-shell.c @@ -23,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"); @@ -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; } From 9db82fe3c25d2ecca8e774bc74c43c2f5fb2de75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 7 Dec 2017 12:42:06 +0100 Subject: [PATCH 4/4] sulogin-shell: replace "^D" by "exit" ^D is a bit cryptic, and advanced users will know that they can use ^D instead of typing exit anyway. --- src/sulogin-shell/sulogin-shell.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sulogin-shell/sulogin-shell.c b/src/sulogin-shell/sulogin-shell.c index 82bb0e7f681..70659df4170 100644 --- a/src/sulogin-shell/sulogin-shell.c +++ b/src/sulogin-shell/sulogin-shell.c @@ -103,8 +103,8 @@ static int fork_wait(const char* const cmdline[]) { 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); }