core: introduce "poweroff" as new failure action types

Also, change the default action on a system start-up timeout to powering off.
This commit is contained in:
Lennart Poettering 2014-08-22 16:59:46 +02:00
parent c4147df156
commit f07756bfe2
8 changed files with 70 additions and 21 deletions

View File

@ -298,7 +298,7 @@
setting, see setting, see
<citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry> <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for details. Defaults to for details. Defaults to
<option>reboot-force</option>. <varname>StartTimeoutRebootArgument=</varname> <option>poweroff-force</option>. <varname>StartTimeoutRebootArgument=</varname>
configures an optional reboot string configures an optional reboot string
to pass to the to pass to the
<citerefentry><refentrytitle>reboot</refentrytitle><manvolnum>2</manvolnum></citerefentry> <citerefentry><refentrytitle>reboot</refentrytitle><manvolnum>2</manvolnum></citerefentry>

View File

@ -1131,26 +1131,35 @@ ExecStart=/bin/echo $ONE $TWO ${TWO}</programlisting>
hit. Takes one of hit. Takes one of
<option>none</option>, <option>none</option>,
<option>reboot</option>, <option>reboot</option>,
<option>reboot-force</option>, or <option>reboot-force</option>,
<option>reboot-immediate</option>. If <option>reboot-immediate</option>,
<option>none</option> is set, <option>poweroff</option>,
hitting the rate limit will trigger no <option>poweroff-force</option> or
action besides that the start will not <option>poweroff-immediate</option>. If
be permitted. <option>reboot</option> <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 causes a reboot following the normal
shutdown procedure (i.e. equivalent to shutdown procedure (i.e. equivalent to
<command>systemctl reboot</command>). <command>systemctl reboot</command>).
<option>reboot-force</option> causes <option>reboot-force</option> causes a
a forced reboot which will terminate forced reboot which will terminate all
all processes forcibly but should processes forcibly but should cause no
cause no dirty file systems on reboot dirty file systems on reboot
(i.e. equivalent to <command>systemctl (i.e. equivalent to <command>systemctl
reboot -f</command>) and reboot -f</command>) and
<option>reboot-immediate</option> <option>reboot-immediate</option>
causes immediate execution of the causes immediate execution of the
<citerefentry><refentrytitle>reboot</refentrytitle><manvolnum>2</manvolnum></citerefentry> <citerefentry><refentrytitle>reboot</refentrytitle><manvolnum>2</manvolnum></citerefentry>
system call, which might result in 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> <option>none</option>.</para></listitem>
</varlistentry> </varlistentry>

View File

@ -40,10 +40,19 @@ int failure_action(
assert(action >= 0); assert(action >= 0);
assert(action < _FAILURE_ACTION_MAX); assert(action < _FAILURE_ACTION_MAX);
switch (action) { if (action == FAILURE_ACTION_NONE)
return -ECANCELED;
case FAILURE_ACTION_NONE: if (m->running_as == SYSTEMD_USER) {
break; /* 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: { case FAILURE_ACTION_REBOOT: {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
@ -78,6 +87,32 @@ int failure_action(
reboot(RB_AUTOBOOT); reboot(RB_AUTOBOOT);
break; 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: default:
assert_not_reached("Unknown failure action"); 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_NONE] = "none",
[FAILURE_ACTION_REBOOT] = "reboot", [FAILURE_ACTION_REBOOT] = "reboot",
[FAILURE_ACTION_REBOOT_FORCE] = "reboot-force", [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); DEFINE_STRING_TABLE_LOOKUP(failure_action, FailureAction);

View File

@ -27,6 +27,9 @@ typedef enum FailureAction {
FAILURE_ACTION_REBOOT, FAILURE_ACTION_REBOOT,
FAILURE_ACTION_REBOOT_FORCE, FAILURE_ACTION_REBOOT_FORCE,
FAILURE_ACTION_REBOOT_IMMEDIATE, FAILURE_ACTION_REBOOT_IMMEDIATE,
FAILURE_ACTION_POWEROFF,
FAILURE_ACTION_POWEROFF_FORCE,
FAILURE_ACTION_POWEROFF_IMMEDIATE,
_FAILURE_ACTION_MAX, _FAILURE_ACTION_MAX,
_FAILURE_ACTION_INVALID = -1 _FAILURE_ACTION_INVALID = -1
} FailureAction; } FailureAction;

View File

@ -117,7 +117,7 @@ static bool arg_default_cpu_accounting = false;
static bool arg_default_blockio_accounting = false; static bool arg_default_blockio_accounting = false;
static bool arg_default_memory_accounting = false; static bool arg_default_memory_accounting = false;
static usec_t arg_start_timeout_usec = DEFAULT_MANAGER_START_TIMEOUT_USEC; 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 char *arg_start_timeout_reboot_arg = NULL;
static void nop_handler(int sig) {} static void nop_handler(int sig) {}

View File

@ -436,7 +436,7 @@ int manager_new(SystemdRunningAs running_as, bool test_run, Manager **_m) {
m->exit_code = _MANAGER_EXIT_CODE_INVALID; m->exit_code = _MANAGER_EXIT_CODE_INVALID;
m->default_timer_accuracy_usec = USEC_PER_MINUTE; m->default_timer_accuracy_usec = USEC_PER_MINUTE;
m->start_timeout_usec = DEFAULT_MANAGER_START_TIMEOUT_USEC; 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; m->idle_pipe[0] = m->idle_pipe[1] = m->idle_pipe[2] = m->idle_pipe[3] = -1;

View File

@ -435,8 +435,7 @@ int main(int argc, char *argv[]) {
if (read_one_line_file(REBOOT_PARAM_FILE, &param) >= 0) { if (read_one_line_file(REBOOT_PARAM_FILE, &param) >= 0) {
log_info("Rebooting with argument '%s'.", param); log_info("Rebooting with argument '%s'.", param);
syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, param);
LINUX_REBOOT_CMD_RESTART2, param);
} }
} }

View File

@ -24,7 +24,7 @@
#SystemCallArchitectures= #SystemCallArchitectures=
#TimerSlackNSec= #TimerSlackNSec=
#StartTimeoutSec=15min #StartTimeoutSec=15min
#StartTimeoutAction=reboot-force #StartTimeoutAction=poweroff-force
#StartTimeoutRebootArgument= #StartTimeoutRebootArgument=
#DefaultTimerAccuracySec=1min #DefaultTimerAccuracySec=1min
#DefaultStandardOutput=journal #DefaultStandardOutput=journal