X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Flogin%2Felogind-dbus.c;h=7f0f706763d6be240396b9a67d9b4a2b63e05d4f;hp=cf7f3dcb64443fc37684a2f02582e6f05cb663a2;hb=7d6db950f0175b36ce0c23e551d45ebbac8eaa26;hpb=3e6d9bb47a4f0f7b717de2691b1b962f65851869 diff --git a/src/login/elogind-dbus.c b/src/login/elogind-dbus.c index cf7f3dcb6..7f0f70676 100644 --- a/src/login/elogind-dbus.c +++ b/src/login/elogind-dbus.c @@ -22,8 +22,10 @@ #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" @@ -90,7 +92,7 @@ static int bus_manager_log_shutdown( 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); @@ -118,6 +120,51 @@ static int send_prepare_for(Manager *m, InhibitWhat w, bool _active) { 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, @@ -404,11 +451,13 @@ static int method_do_shutdown_or_sleep( 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)