1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 Copyright © 2017 Felipe Sateler
10 #include "bus-error.h"
14 #include "process-util.h"
16 #include "signal-util.h"
19 static int reload_manager(sd_bus
*bus
) {
20 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
21 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
24 log_info("Reloading system manager configuration");
26 r
= sd_bus_message_new_method_call(
29 "org.freedesktop.systemd1",
30 "/org/freedesktop/systemd1",
31 "org.freedesktop.systemd1.Manager",
34 return bus_log_create_error(r
);
36 /* Note we use an extra-long timeout here. This is because a reload or reexec means generators are rerun which
37 * are timed out after DEFAULT_TIMEOUT_USEC. Let's use twice that time here, so that the generators can have
38 * their timeout, and for everything else there's the same time budget in place. */
40 r
= sd_bus_call(bus
, m
, DEFAULT_TIMEOUT_USEC
* 2, &error
, NULL
);
42 return log_error_errno(r
, "Failed to reload daemon: %s", bus_error_message(&error
, r
));
47 static int start_default_target(sd_bus
*bus
) {
48 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
51 log_info("Starting default target");
53 /* Start these units only if we can replace base.target with it */
54 r
= sd_bus_call_method(bus
,
55 "org.freedesktop.systemd1",
56 "/org/freedesktop/systemd1",
57 "org.freedesktop.systemd1.Manager",
61 "ss", SPECIAL_DEFAULT_TARGET
, "isolate");
64 return log_error_errno(r
, "Failed to start default target: %s", bus_error_message(&error
, r
));
69 static int fork_wait(const char* const cmdline
[]) {
73 r
= safe_fork("(sulogin)", FORK_RESET_SIGNALS
|FORK_DEATHSIG
|FORK_RLIMIT_NOFILE_SAFE
|FORK_LOG
, &pid
);
78 execv(cmdline
[0], (char**) cmdline
);
79 log_error_errno(errno
, "Failed to execute %s: %m", cmdline
[0]);
80 _exit(EXIT_FAILURE
); /* Operational error */
83 return wait_for_terminate_and_check(cmdline
[0], pid
, WAIT_LOG_ABNORMAL
);
86 static void print_mode(const char* mode
) {
87 printf("You are in %s mode. After logging in, type \"journalctl -xb\" to view\n"
88 "system logs, \"systemctl reboot\" to reboot, \"systemctl default\" or \"exit\"\n"
89 "to boot into default mode.\n", mode
);
93 int main(int argc
, char *argv
[]) {
94 const char* sulogin_cmdline
[] = {
99 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*bus
= NULL
;
104 print_mode(argc
> 1 ? argv
[1] : "");
106 if (getenv_bool("SYSTEMD_SULOGIN_FORCE") > 0)
107 /* allows passwordless logins if root account is locked. */
108 sulogin_cmdline
[1] = "--force";
110 (void) fork_wait(sulogin_cmdline
);
112 r
= bus_connect_system_systemd(&bus
);
114 log_warning_errno(r
, "Failed to get D-Bus connection: %m");
117 (void) reload_manager(bus
);
119 r
= start_default_target(bus
);
122 return r
>= 0 ? EXIT_SUCCESS
: EXIT_FAILURE
;