diff options
author | Lennart Poettering <lennart@poettering.net> | 2014-08-22 16:59:46 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2014-08-22 18:10:31 +0200 |
commit | f07756bfe25c64119704c93a634162d6c88b5c89 (patch) | |
tree | 56478a2737270497ecb199d63804823967ac5a97 | |
parent | c4147df156835513c43260a14fc9f7af177f737f (diff) |
core: introduce "poweroff" as new failure action types
Also, change the default action on a system start-up timeout to powering off.
-rw-r--r-- | man/systemd-system.conf.xml | 2 | ||||
-rw-r--r-- | man/systemd.service.xml | 31 | ||||
-rw-r--r-- | src/core/failure-action.c | 46 | ||||
-rw-r--r-- | src/core/failure-action.h | 3 | ||||
-rw-r--r-- | src/core/main.c | 2 | ||||
-rw-r--r-- | src/core/manager.c | 2 | ||||
-rw-r--r-- | src/core/shutdown.c | 3 | ||||
-rw-r--r-- | src/core/system.conf | 2 |
8 files changed, 70 insertions, 21 deletions
diff --git a/man/systemd-system.conf.xml b/man/systemd-system.conf.xml index 48690024f4..1fad1dba80 100644 --- a/man/systemd-system.conf.xml +++ b/man/systemd-system.conf.xml @@ -298,7 +298,7 @@ setting, see <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry> for details. Defaults to - <option>reboot-force</option>. <varname>StartTimeoutRebootArgument=</varname> + <option>poweroff-force</option>. <varname>StartTimeoutRebootArgument=</varname> configures an optional reboot string to pass to the <citerefentry><refentrytitle>reboot</refentrytitle><manvolnum>2</manvolnum></citerefentry> diff --git a/man/systemd.service.xml b/man/systemd.service.xml index 20d2a0d755..8b17f857ce 100644 --- a/man/systemd.service.xml +++ b/man/systemd.service.xml @@ -1131,26 +1131,35 @@ ExecStart=/bin/echo $ONE $TWO ${TWO}</programlisting> hit. Takes one of <option>none</option>, <option>reboot</option>, - <option>reboot-force</option>, or - <option>reboot-immediate</option>. If - <option>none</option> is set, - hitting the rate limit will trigger no - action besides that the start will not - be permitted. <option>reboot</option> + <option>reboot-force</option>, + <option>reboot-immediate</option>, + <option>poweroff</option>, + <option>poweroff-force</option> or + <option>poweroff-immediate</option>. If + <option>none</option> is set, hitting + the rate limit will trigger no action + besides that the start will not be + permitted. <option>reboot</option> causes a reboot following the normal shutdown procedure (i.e. equivalent to <command>systemctl reboot</command>). - <option>reboot-force</option> causes - a forced reboot which will terminate - all processes forcibly but should - cause no dirty file systems on reboot + <option>reboot-force</option> causes a + forced reboot which will terminate all + processes forcibly but should cause no + dirty file systems on reboot (i.e. equivalent to <command>systemctl reboot -f</command>) and <option>reboot-immediate</option> causes immediate execution of the <citerefentry><refentrytitle>reboot</refentrytitle><manvolnum>2</manvolnum></citerefentry> system call, which might result in - data loss. Defaults to + data loss. Similar, + <option>poweroff</option>, + <option>poweroff-force</option>, + <option>poweroff-immediate</option> + have the effect of powering down the + system with similar + semantics. Defaults to <option>none</option>.</para></listitem> </varlistentry> diff --git a/src/core/failure-action.c b/src/core/failure-action.c index ca807b68da..941747429f 100644 --- a/src/core/failure-action.c +++ b/src/core/failure-action.c @@ -40,10 +40,19 @@ int failure_action( assert(action >= 0); assert(action < _FAILURE_ACTION_MAX); - switch (action) { + if (action == FAILURE_ACTION_NONE) + return -ECANCELED; - case FAILURE_ACTION_NONE: - break; + if (m->running_as == SYSTEMD_USER) { + /* Downgrade all options to simply exiting if we run + * in user mode */ + + log_warning("Exiting as result of failure."); + m->exit_code = MANAGER_EXIT; + return -ECANCELED; + } + + switch (action) { case FAILURE_ACTION_REBOOT: { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; @@ -78,6 +87,32 @@ int failure_action( reboot(RB_AUTOBOOT); break; + case FAILURE_ACTION_POWEROFF: { + _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + + log_warning("Powering off as result of failure."); + + r = manager_add_job_by_name(m, JOB_START, SPECIAL_POWEROFF_TARGET, JOB_REPLACE, true, &error, NULL); + if (r < 0) + log_error("Failed to poweroff: %s.", bus_error_message(&error, r)); + + break; + } + + case FAILURE_ACTION_POWEROFF_FORCE: + log_warning("Forcibly powering off as result of failure."); + m->exit_code = MANAGER_POWEROFF; + break; + + case FAILURE_ACTION_POWEROFF_IMMEDIATE: + log_warning("Powering off immediately as result of failure."); + + sync(); + + log_info("Powering off."); + reboot(RB_POWER_OFF); + break; + default: assert_not_reached("Unknown failure action"); } @@ -89,6 +124,9 @@ static const char* const failure_action_table[_FAILURE_ACTION_MAX] = { [FAILURE_ACTION_NONE] = "none", [FAILURE_ACTION_REBOOT] = "reboot", [FAILURE_ACTION_REBOOT_FORCE] = "reboot-force", - [FAILURE_ACTION_REBOOT_IMMEDIATE] = "reboot-immediate" + [FAILURE_ACTION_REBOOT_IMMEDIATE] = "reboot-immediate", + [FAILURE_ACTION_POWEROFF] = "poweroff", + [FAILURE_ACTION_POWEROFF_FORCE] = "poweroff-force", + [FAILURE_ACTION_POWEROFF_IMMEDIATE] = "poweroff-immediate" }; DEFINE_STRING_TABLE_LOOKUP(failure_action, FailureAction); diff --git a/src/core/failure-action.h b/src/core/failure-action.h index 5353192f31..1af4dd987b 100644 --- a/src/core/failure-action.h +++ b/src/core/failure-action.h @@ -27,6 +27,9 @@ typedef enum FailureAction { FAILURE_ACTION_REBOOT, FAILURE_ACTION_REBOOT_FORCE, FAILURE_ACTION_REBOOT_IMMEDIATE, + FAILURE_ACTION_POWEROFF, + FAILURE_ACTION_POWEROFF_FORCE, + FAILURE_ACTION_POWEROFF_IMMEDIATE, _FAILURE_ACTION_MAX, _FAILURE_ACTION_INVALID = -1 } FailureAction; diff --git a/src/core/main.c b/src/core/main.c index ed690162bf..bd148b1b33 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -117,7 +117,7 @@ static bool arg_default_cpu_accounting = false; static bool arg_default_blockio_accounting = false; static bool arg_default_memory_accounting = false; static usec_t arg_start_timeout_usec = DEFAULT_MANAGER_START_TIMEOUT_USEC; -static FailureAction arg_start_timeout_action = FAILURE_ACTION_REBOOT_FORCE; +static FailureAction arg_start_timeout_action = FAILURE_ACTION_POWEROFF_FORCE; static char *arg_start_timeout_reboot_arg = NULL; static void nop_handler(int sig) {} diff --git a/src/core/manager.c b/src/core/manager.c index 7508fefaef..7639aeef19 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -436,7 +436,7 @@ int manager_new(SystemdRunningAs running_as, bool test_run, Manager **_m) { m->exit_code = _MANAGER_EXIT_CODE_INVALID; m->default_timer_accuracy_usec = USEC_PER_MINUTE; m->start_timeout_usec = DEFAULT_MANAGER_START_TIMEOUT_USEC; - m->start_timeout_action = FAILURE_ACTION_REBOOT_FORCE; + m->start_timeout_action = FAILURE_ACTION_POWEROFF_FORCE; m->idle_pipe[0] = m->idle_pipe[1] = m->idle_pipe[2] = m->idle_pipe[3] = -1; diff --git a/src/core/shutdown.c b/src/core/shutdown.c index 1abc140e7d..0e2ea5754f 100644 --- a/src/core/shutdown.c +++ b/src/core/shutdown.c @@ -435,8 +435,7 @@ int main(int argc, char *argv[]) { if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) >= 0) { log_info("Rebooting with argument '%s'.", param); - syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, - LINUX_REBOOT_CMD_RESTART2, param); + syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, param); } } diff --git a/src/core/system.conf b/src/core/system.conf index 45448de328..5a723bb20e 100644 --- a/src/core/system.conf +++ b/src/core/system.conf @@ -24,7 +24,7 @@ #SystemCallArchitectures= #TimerSlackNSec= #StartTimeoutSec=15min -#StartTimeoutAction=reboot-force +#StartTimeoutAction=poweroff-force #StartTimeoutRebootArgument= #DefaultTimerAccuracySec=1min #DefaultStandardOutput=journal |