Branch data Line data Source code
1 : : /* SPDX-License-Identifier: LGPL-2.1+ */
2 : : /***
3 : : Copyright © 2017 Felipe Sateler
4 : : ***/
5 : :
6 : : #include <errno.h>
7 : : #include <sys/prctl.h>
8 : :
9 : : #include "bus-util.h"
10 : : #include "bus-error.h"
11 : : #include "def.h"
12 : : #include "env-util.h"
13 : : #include "log.h"
14 : : #include "process-util.h"
15 : : #include "sd-bus.h"
16 : : #include "signal-util.h"
17 : :
18 : 0 : static int reload_manager(sd_bus *bus) {
19 : 0 : _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
20 : 0 : _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
21 : : int r;
22 : :
23 [ # # ]: 0 : log_info("Reloading system manager configuration");
24 : :
25 : 0 : r = sd_bus_message_new_method_call(
26 : : bus,
27 : : &m,
28 : : "org.freedesktop.systemd1",
29 : : "/org/freedesktop/systemd1",
30 : : "org.freedesktop.systemd1.Manager",
31 : : "Reload");
32 [ # # ]: 0 : if (r < 0)
33 [ # # ]: 0 : return bus_log_create_error(r);
34 : :
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. */
38 : :
39 : 0 : r = sd_bus_call(bus, m, DEFAULT_TIMEOUT_USEC * 2, &error, NULL);
40 [ # # ]: 0 : if (r < 0)
41 [ # # ]: 0 : return log_error_errno(r, "Failed to reload daemon: %s", bus_error_message(&error, r));
42 : :
43 : 0 : return 0;
44 : : }
45 : :
46 : 0 : static int start_default_target(sd_bus *bus) {
47 : 0 : _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
48 : : int r;
49 : :
50 [ # # ]: 0 : log_info("Starting default target");
51 : :
52 : : /* Start these units only if we can replace base.target with it */
53 : 0 : r = sd_bus_call_method(bus,
54 : : "org.freedesktop.systemd1",
55 : : "/org/freedesktop/systemd1",
56 : : "org.freedesktop.systemd1.Manager",
57 : : "StartUnit",
58 : : &error,
59 : : NULL,
60 : : "ss", "default.target", "isolate");
61 : :
62 [ # # ]: 0 : if (r < 0)
63 [ # # ]: 0 : return log_error_errno(r, "Failed to start default target: %s", bus_error_message(&error, r));
64 : :
65 : 0 : return 0;
66 : : }
67 : :
68 : 0 : static int fork_wait(const char* const cmdline[]) {
69 : : pid_t pid;
70 : : int r;
71 : :
72 : 0 : r = safe_fork("(sulogin)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
73 [ # # ]: 0 : if (r < 0)
74 : 0 : return r;
75 [ # # ]: 0 : if (r == 0) {
76 : : /* Child */
77 : 0 : execv(cmdline[0], (char**) cmdline);
78 [ # # ]: 0 : log_error_errno(errno, "Failed to execute %s: %m", cmdline[0]);
79 : 0 : _exit(EXIT_FAILURE); /* Operational error */
80 : : }
81 : :
82 : 0 : return wait_for_terminate_and_check(cmdline[0], pid, WAIT_LOG_ABNORMAL);
83 : : }
84 : :
85 : 0 : static void print_mode(const char* mode) {
86 : 0 : 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);
89 : 0 : fflush(stdout);
90 : 0 : }
91 : :
92 : 0 : int main(int argc, char *argv[]) {
93 : 0 : const char* sulogin_cmdline[] = {
94 : : SULOGIN,
95 : : NULL, /* --force */
96 : : NULL
97 : : };
98 : 0 : _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
99 : : int r;
100 : :
101 : 0 : log_setup_service();
102 : :
103 [ # # ]: 0 : print_mode(argc > 1 ? argv[1] : "");
104 : :
105 [ # # ]: 0 : if (getenv_bool("SYSTEMD_SULOGIN_FORCE") > 0)
106 : : /* allows passwordless logins if root account is locked. */
107 : 0 : sulogin_cmdline[1] = "--force";
108 : :
109 : 0 : (void) fork_wait(sulogin_cmdline);
110 : :
111 : 0 : r = bus_connect_system_systemd(&bus);
112 [ # # ]: 0 : if (r < 0) {
113 [ # # ]: 0 : log_warning_errno(r, "Failed to get D-Bus connection: %m");
114 : 0 : r = 0;
115 : : } else {
116 : 0 : (void) reload_manager(bus);
117 : :
118 : 0 : r = start_default_target(bus);
119 : : }
120 : :
121 : 0 : return r >= 0 ? EXIT_SUCCESS : EXIT_FAILURE;
122 : : }
|