From 1389f4b95877f29cb357baee837d9c05e64df0c6 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Wed, 9 Sep 2015 17:05:03 +0200 Subject: logind: allow dry run variants for scheduled shutdowns Allow passing a "dry-" prefix to the action parameter passed to .ScheduleShutdown(). When strings with this prefix are passed, the scheduled action will not take place. Instead, an info message is logged. --- src/login/logind-dbus.c | 72 +++++++++++++++++++++++++++++-------------------- src/login/logind.h | 2 ++ 2 files changed, 45 insertions(+), 29 deletions(-) diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index 050d0252ad..22e37a1638 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -1423,6 +1423,20 @@ int manager_set_lid_switch_ignore(Manager *m, usec_t until) { return r; } +static void reset_scheduled_shutdown(Manager *m) { + m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source); + m->wall_message_timeout_source = sd_event_source_unref(m->wall_message_timeout_source); + m->nologin_timeout_source = sd_event_source_unref(m->nologin_timeout_source); + m->scheduled_shutdown_type = mfree(m->scheduled_shutdown_type); + m->scheduled_shutdown_timeout = 0; + m->shutdown_dry_run = false; + + if (m->unlink_nologin) { + (void) unlink("/run/nologin"); + m->unlink_nologin = false; + } +} + static int execute_shutdown_or_sleep( Manager *m, InhibitWhat w, @@ -1430,8 +1444,8 @@ static int execute_shutdown_or_sleep( sd_bus_error *error) { _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; + char *c = NULL; const char *p; - char *c; int r; assert(m); @@ -1441,25 +1455,30 @@ static int execute_shutdown_or_sleep( bus_manager_log_shutdown(m, w, unit_name); - r = sd_bus_call_method( - m->bus, - "org.freedesktop.systemd1", - "/org/freedesktop/systemd1", - "org.freedesktop.systemd1.Manager", - "StartUnit", - error, - &reply, - "ss", unit_name, "replace-irreversibly"); - if (r < 0) - return r; + if (m->shutdown_dry_run) { + log_info("Running in dry run, suppressing action."); + reset_scheduled_shutdown(m); + } else { + r = sd_bus_call_method( + m->bus, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "StartUnit", + error, + &reply, + "ss", unit_name, "replace-irreversibly"); + if (r < 0) + return r; - r = sd_bus_message_read(reply, "o", &p); - if (r < 0) - return r; + r = sd_bus_message_read(reply, "o", &p); + if (r < 0) + return r; - c = strdup(p); - if (!c) - return -ENOMEM; + c = strdup(p); + if (!c) + return -ENOMEM; + } m->action_unit = unit_name; free(m->action_job); @@ -1889,6 +1908,11 @@ static int method_schedule_shutdown(sd_bus_message *message, void *userdata, sd_ if (r < 0) return r; + if (startswith(type, "dry-")) { + type += 4; + m->shutdown_dry_run = true; + } + if (streq(type, "reboot")) { action = "org.freedesktop.login1.reboot"; action_multiple_sessions = "org.freedesktop.login1.reboot-multiple-sessions"; @@ -1983,17 +2007,7 @@ static int method_cancel_scheduled_shutdown(sd_bus_message *message, void *userd assert(message); cancelled = m->scheduled_shutdown_type != NULL; - - m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source); - m->wall_message_timeout_source = sd_event_source_unref(m->wall_message_timeout_source); - m->nologin_timeout_source = sd_event_source_unref(m->nologin_timeout_source); - m->scheduled_shutdown_type = mfree(m->scheduled_shutdown_type); - m->scheduled_shutdown_timeout = 0; - - if (m->unlink_nologin) { - (void) unlink("/run/nologin"); - m->unlink_nologin = false; - } + reset_scheduled_shutdown(m); if (cancelled) { _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL; diff --git a/src/login/logind.h b/src/login/logind.h index ce99d75bc1..7990da5a93 100644 --- a/src/login/logind.h +++ b/src/login/logind.h @@ -107,6 +107,8 @@ struct Manager { unsigned enable_wall_messages; sd_event_source *wall_message_timeout_source; + bool shutdown_dry_run; + sd_event_source *idle_action_event_source; usec_t idle_action_usec; usec_t idle_action_not_before_usec; -- cgit v1.2.3-54-g00ecf From 7681f5b88907f5bc01405ee7607d4c3702f1c65f Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Wed, 9 Sep 2015 17:10:49 +0200 Subject: systemctl: add dry-run support for scheduled shutdowns Prefix the action parameter with "dry-" in case the --dry-run command line switch was passed. --- src/systemctl/systemctl.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index a82b9b83a2..74d7fc2b3b 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -7358,7 +7358,6 @@ static int halt_main(sd_bus *bus) { * the machine. */ if (arg_when <= 0 && - !arg_dry && arg_force <= 0 && (arg_action == ACTION_POWEROFF || arg_action == ACTION_REBOOT)) { @@ -7375,6 +7374,7 @@ static int halt_main(sd_bus *bus) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_bus_flush_close_unref_ sd_bus *b = NULL; _cleanup_free_ char *m = NULL; + const char *action; if (avoid_bus()) { log_error("Unable to perform operation without bus connection."); @@ -7407,6 +7407,24 @@ static int halt_main(sd_bus *bus) { sd_bus_error_free(&error); } + switch (arg_action) { + case ACTION_HALT: + action = "halt"; + break; + case ACTION_POWEROFF: + action = "poweroff"; + break; + case ACTION_KEXEC: + action = "kexec"; + break; + default: + action = "reboot"; + break; + } + + if (arg_dry) + action = strjoina("dry-", action); + r = sd_bus_call_method( b, "org.freedesktop.login1", @@ -7416,10 +7434,7 @@ static int halt_main(sd_bus *bus) { &error, NULL, "st", - arg_action == ACTION_HALT ? "halt" : - arg_action == ACTION_POWEROFF ? "poweroff" : - arg_action == ACTION_KEXEC ? "kexec" : - "reboot", + action, arg_when); if (r < 0) log_warning_errno(r, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s", -- cgit v1.2.3-54-g00ecf