diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2023-02-17 06:52:03 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-02-17 06:52:03 +0900 |
commit | b038a44d440a67d82cebec5eb40e6369e4c9f613 (patch) | |
tree | 7b752c9a4e1dc11d8a45dd41beb5a32160c0fd69 /src | |
parent | f92428eae53685f372775e8cb0f0f4c249f02724 (diff) | |
parent | 937ca8330d11e406b8ef343bead6f4f6244e39c7 (diff) | |
download | systemd-b038a44d440a67d82cebec5eb40e6369e4c9f613.tar.gz |
Merge pull request #26271 from d-hatayama/fix_sulogin_shell
sulogin: fix control lost of the current terminal when default.target…
Diffstat (limited to 'src')
-rw-r--r-- | src/sulogin-shell/sulogin-shell.c | 64 |
1 files changed, 53 insertions, 11 deletions
diff --git a/src/sulogin-shell/sulogin-shell.c b/src/sulogin-shell/sulogin-shell.c index 6161e134e1..dd80d6f7c9 100644 --- a/src/sulogin-shell/sulogin-shell.c +++ b/src/sulogin-shell/sulogin-shell.c @@ -14,9 +14,11 @@ #include "constants.h" #include "env-util.h" #include "log.h" +#include "main-func.h" #include "process-util.h" #include "signal-util.h" #include "special.h" +#include "unit-def.h" static int reload_manager(sd_bus *bus) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; @@ -41,6 +43,28 @@ static int reload_manager(sd_bus *bus) { return 0; } +static int default_target_is_inactive(sd_bus *bus) { + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_free_ char *path = NULL, *state = NULL; + int r; + + path = unit_dbus_path_from_name(SPECIAL_DEFAULT_TARGET); + if (!path) + return log_oom(); + + r = sd_bus_get_property_string(bus, + "org.freedesktop.systemd1", + path, + "org.freedesktop.systemd1.Unit", + "ActiveState", + &error, + &state); + if (r < 0) + return log_error_errno(r, "Failed to retrieve unit state: %s", bus_error_message(&error, r)); + + return streq_ptr(state, "inactive"); +} + static int start_default_target(sd_bus *bus) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; int r; @@ -86,13 +110,12 @@ static void print_mode(const char* mode) { fflush(stdout); } -int main(int argc, char *argv[]) { +static int run(int argc, char *argv[]) { const char* sulogin_cmdline[] = { SULOGIN, NULL, /* --force */ NULL }; - _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; int r; log_setup(); @@ -103,17 +126,36 @@ int main(int argc, char *argv[]) { /* allows passwordless logins if root account is locked. */ sulogin_cmdline[1] = "--force"; - (void) fork_wait(sulogin_cmdline); + for (;;) { + _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; - 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); + (void) fork_wait(sulogin_cmdline); - r = start_default_target(bus); + r = bus_connect_system_systemd(&bus); + if (r < 0) { + log_warning_errno(r, "Failed to get D-Bus connection: %m"); + goto fallback; + } + + if (reload_manager(bus) < 0) + goto fallback; + + r = default_target_is_inactive(bus); + if (r < 0) + goto fallback; + if (!r) { + log_warning(SPECIAL_DEFAULT_TARGET" is not inactive. Please review the "SPECIAL_DEFAULT_TARGET" setting.\n"); + goto fallback; + } + + if (start_default_target(bus) >= 0) + break; + + fallback: + log_warning("Fallback to the single-user shell.\n"); } - return r >= 0 ? EXIT_SUCCESS : EXIT_FAILURE; + return 0; } + +DEFINE_MAIN_FUNCTION(run); |