1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 Copyright © 2017 Felipe Sateler
12 #include "bus-error.h"
16 #include "process-util.h"
17 #include "signal-util.h"
20 static int reload_manager(sd_bus
*bus
) {
21 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
22 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
25 log_info("Reloading system manager configuration");
27 r
= sd_bus_message_new_method_call(
30 "org.freedesktop.systemd1",
31 "/org/freedesktop/systemd1",
32 "org.freedesktop.systemd1.Manager",
35 return bus_log_create_error(r
);
37 /* Note we use an extra-long timeout here. This is because a reload or reexec means generators are rerun which
38 * are timed out after DEFAULT_TIMEOUT_USEC. Let's use twice that time here, so that the generators can have
39 * their timeout, and for everything else there's the same time budget in place. */
41 r
= sd_bus_call(bus
, m
, DEFAULT_TIMEOUT_USEC
* 2, &error
, NULL
);
43 return log_error_errno(r
, "Failed to reload daemon: %s", bus_error_message(&error
, r
));
48 static int start_default_target(sd_bus
*bus
) {
49 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
52 log_info("Starting default target");
54 /* Start these units only if we can replace base.target with it */
55 r
= sd_bus_call_method(bus
,
56 "org.freedesktop.systemd1",
57 "/org/freedesktop/systemd1",
58 "org.freedesktop.systemd1.Manager",
62 "ss", SPECIAL_DEFAULT_TARGET
, "isolate");
65 return log_error_errno(r
, "Failed to start default target: %s", bus_error_message(&error
, r
));
70 static int fork_wait(const char* const cmdline
[]) {
74 r
= safe_fork("(sulogin)", FORK_RESET_SIGNALS
|FORK_DEATHSIG
|FORK_RLIMIT_NOFILE_SAFE
|FORK_LOG
, &pid
);
79 execv(cmdline
[0], (char**) cmdline
);
80 log_error_errno(errno
, "Failed to execute %s: %m", cmdline
[0]);
81 _exit(EXIT_FAILURE
); /* Operational error */
84 return wait_for_terminate_and_check(cmdline
[0], pid
, WAIT_LOG_ABNORMAL
);
87 static void print_mode(const char* mode
) {
88 printf("You are in %s mode. After logging in, type \"journalctl -xb\" to view\n"
89 "system logs, \"systemctl reboot\" to reboot, \"systemctl default\" or \"exit\"\n"
90 "to boot into default mode.\n", mode
);
94 int main(int argc
, char *argv
[]) {
95 const char* sulogin_cmdline
[] = {
100 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*bus
= NULL
;
105 print_mode(argc
> 1 ? argv
[1] : "");
107 if (getenv_bool("SYSTEMD_SULOGIN_FORCE") > 0)
108 /* allows passwordless logins if root account is locked. */
109 sulogin_cmdline
[1] = "--force";
111 (void) fork_wait(sulogin_cmdline
);
113 r
= bus_connect_system_systemd(&bus
);
115 log_warning_errno(r
, "Failed to get D-Bus connection: %m");
118 (void) reload_manager(bus
);
120 r
= start_default_target(bus
);
123 return r
>= 0 ? EXIT_SUCCESS
: EXIT_FAILURE
;