2 This file is part of elogind.
4 Copyright 2017 Sven Eden
6 elogind is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 elogind is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with elogind; If not, see <http://www.gnu.org/licenses/>.
21 #include "elogind-dbus.h"
22 #include "process-util.h"
23 #include "sd-messages.h"
25 #include "string-util.h"
27 #include "update-utmp.h"
30 static int bus_manager_log_shutdown(
33 HandleAction action) {
39 if (w != INHIBIT_SHUTDOWN)
44 p = "MESSAGE=System is powering down.";
45 q = "SHUTDOWN=power-off";
48 p = "MESSAGE=System is halting.";
52 p = "MESSAGE=System is rebooting.";
53 q = "SHUTDOWN=reboot";
56 p = "MESSAGE=System is rebooting with kexec.";
60 p = "MESSAGE=System is shutting down.";
64 if (isempty(m->wall_message))
67 p = strjoina(p, " (", m->wall_message, ").");
69 return log_struct(LOG_NOTICE,
70 "MESSAGE_ID=" SD_MESSAGE_SHUTDOWN_STR,
76 /* elogind specific helper to make HALT and REBOOT possible. */
77 static int run_helper(const char *helper) {
80 r = safe_fork_full(helper, NULL, 0, FORK_RESET_SIGNALS|FORK_REOPEN_LOG, NULL);
83 return log_error_errno(errno, "Failed to fork run %s: %m", helper);
87 execlp(helper, helper, NULL);
88 log_error_errno(errno, "Failed to execute %s: %m", helper);
95 /* elogind specific executor */
96 static int shutdown_or_sleep(Manager *m, HandleAction action) {
101 case HANDLE_POWEROFF:
102 return run_helper(POWEROFF);
104 return run_helper(REBOOT);
106 return run_helper(HALT);
108 return run_helper(KEXEC);
110 return do_sleep("suspend", m->suspend_mode, m->suspend_state);
111 case HANDLE_HIBERNATE:
112 return do_sleep("hibernate", m->hibernate_mode, m->hibernate_state);
113 case HANDLE_HYBRID_SLEEP:
114 return do_sleep("hybrid-sleep", m->hybrid_sleep_mode, m->hybrid_sleep_state);
120 int execute_shutdown_or_sleep(
124 sd_bus_error *error) {
126 char** argv_utmp = NULL;
131 assert(w < _INHIBIT_WHAT_MAX);
133 bus_manager_log_shutdown(m, w, action);
135 if (IN_SET(action, HANDLE_HALT, HANDLE_POWEROFF, HANDLE_REBOOT)) {
137 /* As we have no systemd update-utmp daemon running, we have to
138 * set the relevant utmp/wtmp entries ourselves.
141 if (strv_extend(&argv_utmp, "elogind") < 0)
144 if (HANDLE_REBOOT == action) {
145 if (strv_extend(&argv_utmp, "reboot") < 0)
148 if (strv_extend(&argv_utmp, "shutdown") < 0)
152 /* This comes from our patched update-utmp/update-utmp.c */
153 update_utmp(2, argv_utmp);
154 strv_free(argv_utmp);
157 /* Now perform the requested action */
158 r = shutdown_or_sleep(m, action);
160 /* no more pending actions, whether this failed or not */
161 m->pending_action = HANDLE_IGNORE;
163 /* As elogind can not rely on a systemd manager to call all
164 * sleeping processes to wake up, we have to tell them all
166 if (w == INHIBIT_SLEEP) {
167 (void) send_prepare_for(m, w, false);
175 /* Make sure the lid switch is ignored for a while */
176 manager_set_lid_switch_ignore(m, now(CLOCK_MONOTONIC) + m->holdoff_timeout_usec);
181 int manager_scheduled_shutdown_handler(
186 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
187 Manager *m = userdata;
193 if (isempty(m->scheduled_shutdown_type))
196 if (streq(m->scheduled_shutdown_type, "halt"))
197 action = HANDLE_HALT;
198 else if (streq(m->scheduled_shutdown_type, "poweroff"))
199 action = HANDLE_POWEROFF;
201 action = HANDLE_REBOOT;
203 /* Don't allow multiple jobs being executed at the same time */
204 if (m->action_what) {
206 log_error("Scheduled shutdown to %s failed: shutdown or sleep operation already in progress",
207 m->scheduled_shutdown_type);
211 if (m->shutdown_dry_run) {
212 /* We do not process delay inhibitors here. Otherwise, we
213 * would have to be considered "in progress" (like the check
214 * above) for some seconds after our admin has seen the final
217 bus_manager_log_shutdown(m, INHIBIT_SHUTDOWN, action);
218 log_info("Running in dry run, suppressing action.");
219 reset_scheduled_shutdown(m);
224 r = execute_shutdown_or_sleep(m, 0, action, &error);
226 log_error_errno(r, "Scheduled shutdown to %s failed: %m",
227 m->scheduled_shutdown_type);
234 reset_scheduled_shutdown(m);