220 lines
10 KiB
Diff
220 lines
10 KiB
Diff
From f07756bfe25c64119704c93a634162d6c88b5c89 Mon Sep 17 00:00:00 2001
|
|
From: Lennart Poettering <lennart@poettering.net>
|
|
Date: Fri, 22 Aug 2014 16:59:46 +0200
|
|
Subject: [PATCH] core: introduce "poweroff" as new failure action types
|
|
|
|
Also, change the default action on a system start-up timeout to powering off.
|
|
---
|
|
man/systemd-system.conf.xml | 2 +-
|
|
man/systemd.service.xml | 31 +++++++++++++++++++-----------
|
|
src/core/failure-action.c | 46 +++++++++++++++++++++++++++++++++++++++++----
|
|
src/core/failure-action.h | 3 +++
|
|
src/core/main.c | 2 +-
|
|
src/core/manager.c | 2 +-
|
|
src/core/shutdown.c | 3 +--
|
|
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
|