summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2014-08-22 16:59:46 +0200
committerLennart Poettering <lennart@poettering.net>2014-08-22 18:10:31 +0200
commitf07756bfe25c64119704c93a634162d6c88b5c89 (patch)
tree56478a2737270497ecb199d63804823967ac5a97
parentc4147df156835513c43260a14fc9f7af177f737f (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.xml2
-rw-r--r--man/systemd.service.xml31
-rw-r--r--src/core/failure-action.c46
-rw-r--r--src/core/failure-action.h3
-rw-r--r--src/core/main.c2
-rw-r--r--src/core/manager.c2
-rw-r--r--src/core/shutdown.c3
-rw-r--r--src/core/system.conf2
8 files changed, 70 insertions, 21 deletions
diff --git a/man/systemd-system.conf.xml b/man/systemd-system.conf.xml
index 48690024f..1fad1dba8 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 20d2a0d75..8b17f857c 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 ca807b68d..941747429 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 5353192f3..1af4dd987 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 ed690162b..bd148b1b3 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 7508fefae..7639aeef1 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 1abc140e7..0e2ea5754 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, &param) >= 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 45448de32..5a723bb20 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