#include "bus-error.h"
#include "bus-util.h"
#include "elogind-dbus.h"
+#include "fd-util.h"
#include "process-util.h"
#include "sd-messages.h"
+#include "sleep.h"
#include "sleep-config.h"
#include "string-util.h"
#include "strv.h"
p = strjoina(p, " (", m->wall_message, ").");
return log_struct(LOG_NOTICE,
- LOG_MESSAGE_ID(SD_MESSAGE_SHUTDOWN),
+ "MESSAGE_ID=" SD_MESSAGE_SHUTDOWN_STR,
p,
q,
NULL);
active);
}
+/* elogind specific helper to make HALT and REBOOT possible. */
+static int run_helper(const char *helper) {
+ int pid = fork();
+ if (pid < 0) {
+ return log_error_errno(errno, "Failed to fork: %m");
+ }
+
+ if (pid == 0) {
+ /* Child */
+
+ close_all_fds(NULL, 0);
+
+ execlp(helper, helper, NULL);
+ log_error_errno(errno, "Failed to execute %s: %m", helper);
+ _exit(EXIT_FAILURE);
+ }
+
+ return wait_for_terminate_and_warn(helper, pid, true);
+}
+
+/* elogind specific executor */
+static int shutdown_or_sleep(Manager *m, HandleAction action) {
+
+ assert(m);
+
+ switch (action) {
+ case HANDLE_POWEROFF:
+ return run_helper(HALT);
+ case HANDLE_REBOOT:
+ return run_helper(REBOOT);
+ case HANDLE_HALT:
+ return run_helper(HALT);
+ case HANDLE_KEXEC:
+ return run_helper(KEXEC);
+ case HANDLE_SUSPEND:
+ return do_sleep("suspend", m->suspend_mode, m->suspend_state);
+ case HANDLE_HIBERNATE:
+ return do_sleep("hibernate", m->hibernate_mode, m->hibernate_state);
+ case HANDLE_HYBRID_SLEEP:
+ return do_sleep("hybrid-sleep", m->hybrid_sleep_mode, m->hybrid_sleep_state);
+ default:
+ return -EINVAL;
+ }
+}
+
static int execute_shutdown_or_sleep(
Manager *m,
InhibitWhat w,
return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb not supported");
}
- r = verify_shutdown_creds(m, message, w, interactive, action, action_multiple_sessions,
- action_ignore_inhibit, error);
- log_debug_elogind("verify_shutdown_creds() returned %d", r);
- if (r != 0)
- return r;
+ if (IN_SET(sleep_action, HANDLE_HALT, HANDLE_POWEROFF, HANDLE_REBOOT)) {
+ r = verify_shutdown_creds(m, message, w, interactive, action, action_multiple_sessions,
+ action_ignore_inhibit, error);
+ log_debug_elogind("verify_shutdown_creds() returned %d", r);
+ if (r != 0)
+ return r;
+ }
r = bus_manager_shutdown_or_sleep_now_or_later(m, sleep_action, w, error);
if (r < 0)