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"
18 static int reload_manager(sd_bus
*bus
) {
19 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
20 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
23 log_info("Reloading system manager configuration");
25 r
= sd_bus_message_new_method_call(
28 "org.freedesktop.systemd1",
29 "/org/freedesktop/systemd1",
30 "org.freedesktop.systemd1.Manager",
33 return bus_log_create_error(r
);
35 /* Note we use an extra-long timeout here. This is because a reload or reexec means generators are rerun which
36 * are timed out after DEFAULT_TIMEOUT_USEC. Let's use twice that time here, so that the generators can have
37 * their timeout, and for everything else there's the same time budget in place. */
39 r
= sd_bus_call(bus
, m
, DEFAULT_TIMEOUT_USEC
* 2, &error
, NULL
);
41 return log_error_errno(r
, "Failed to reload daemon: %s", bus_error_message(&error
, r
));
46 static int start_default_target(sd_bus
*bus
) {
47 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
50 log_info("Starting default target");
52 /* Start these units only if we can replace base.target with it */
53 r
= sd_bus_call_method(bus
,
54 "org.freedesktop.systemd1",
55 "/org/freedesktop/systemd1",
56 "org.freedesktop.systemd1.Manager",
60 "ss", "default.target", "isolate");
63 return log_error_errno(r
, "Failed to start default target: %s", bus_error_message(&error
, r
));
68 static int fork_wait(const char* const cmdline
[]) {
72 r
= safe_fork("(sulogin)", FORK_RESET_SIGNALS
|FORK_DEATHSIG
|FORK_RLIMIT_NOFILE_SAFE
|FORK_LOG
, &pid
);
77 execv(cmdline
[0], (char**) cmdline
);
78 log_error_errno(errno
, "Failed to execute %s: %m", cmdline
[0]);
79 _exit(EXIT_FAILURE
); /* Operational error */
82 return wait_for_terminate_and_check(cmdline
[0], pid
, WAIT_LOG_ABNORMAL
);
85 static void print_mode(const char* mode
) {
86 printf("You are in %s mode. After logging in, type \"journalctl -xb\" to view\n"
87 "system logs, \"systemctl reboot\" to reboot, \"systemctl default\" or \"exit\"\n"
88 "to boot into default mode.\n", mode
);
92 int main(int argc
, char *argv
[]) {
93 const char* sulogin_cmdline
[] = {
98 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*bus
= NULL
;
103 print_mode(argc
> 1 ? argv
[1] : "");
105 if (getenv_bool("SYSTEMD_SULOGIN_FORCE") > 0)
106 /* allows passwordless logins if root account is locked. */
107 sulogin_cmdline
[1] = "--force";
109 (void) fork_wait(sulogin_cmdline
);
111 r
= bus_connect_system_systemd(&bus
);
113 log_warning_errno(r
, "Failed to get D-Bus connection: %m");
116 (void) reload_manager(bus
);
118 r
= start_default_target(bus
);
121 return r
>= 0 ? EXIT_SUCCESS
: EXIT_FAILURE
;