mirror of
https://github.com/systemd/systemd.git
synced 2025-03-22 06:50:18 +03:00
Merge pull request #28104 from DaanDeMeyer/emergency-kexec-halt
core: Add halt and kexec emergency actions
This commit is contained in:
commit
58373cebb8
@ -1004,10 +1004,12 @@
|
||||
inactive state. Takes one of <option>none</option>, <option>reboot</option>,
|
||||
<option>reboot-force</option>, <option>reboot-immediate</option>, <option>poweroff</option>,
|
||||
<option>poweroff-force</option>, <option>poweroff-immediate</option>, <option>exit</option>,
|
||||
<option>exit-force</option>, <option>soft-reboot</option> and <option>soft-reboot-force</option>. In
|
||||
system mode, all options are allowed. In user mode, only <option>none</option>,
|
||||
<option>exit</option>, <option>exit-force</option>, <option>soft-reboot</option> and
|
||||
<option>soft-reboot-force</option> are allowed. Both options default to <option>none</option>.</para>
|
||||
<option>exit-force</option>, <option>soft-reboot</option>, <option>soft-reboot-force</option>,
|
||||
<option>kexec</option>, <option>kexec-force</option>, <option>halt</option>,
|
||||
<option>halt-force</option> and <option>halt-immediate</option>. In system mode, all options are
|
||||
allowed. In user mode, only <option>none</option>, <option>exit</option>,
|
||||
<option>exit-force</option>, <option>soft-reboot</option> and <option>soft-reboot-force</option> are
|
||||
allowed. Both options default to <option>none</option>.</para>
|
||||
|
||||
<para>If <option>none</option> is set, no action will be triggered. <option>reboot</option> causes a
|
||||
reboot following the normal shutdown procedure (i.e. equivalent to <command>systemctl
|
||||
@ -1016,18 +1018,20 @@
|
||||
<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 (i.e. equivalent to <command>systemctl reboot
|
||||
-ff</command>). Similarly, <option>poweroff</option>, <option>poweroff-force</option>,
|
||||
<option>poweroff-immediate</option> have the effect of powering down the system with similar
|
||||
call, which might result in data loss (i.e. equivalent to <command>systemctl reboot -ff</command>).
|
||||
Similarly, <option>poweroff</option>, <option>poweroff-force</option>,
|
||||
<option>poweroff-immediate</option>, <option>kexec</option>, <option>kexec-force</option>,
|
||||
<option>halt</option>, <option>halt-force</option> and <option>halt-immediate</option> have the
|
||||
effect of powering down the system, executing kexec, and halting the system respectively with similar
|
||||
semantics. <option>exit</option> causes the manager to exit following the normal shutdown procedure,
|
||||
and <option>exit-force</option> causes it terminate without shutting down services. When
|
||||
<option>exit</option> or <option>exit-force</option> is used by default the exit status of the main
|
||||
process of the unit (if this applies) is returned from the service manager. However, this may be
|
||||
overridden with
|
||||
<varname>FailureActionExitStatus=</varname>/<varname>SuccessActionExitStatus=</varname>, see
|
||||
below. <option>soft-reboot</option> will trigger a userspace reboot
|
||||
operation. <option>soft-reboot-force</option> does that too, but does not go through the shutdown
|
||||
transaction beforehand.</para></listitem>
|
||||
<varname>FailureActionExitStatus=</varname>/<varname>SuccessActionExitStatus=</varname>, see below.
|
||||
<option>soft-reboot</option> will trigger a userspace reboot operation.
|
||||
<option>soft-reboot-force</option> does that too, but does not go through the shutdown transaction
|
||||
beforehand.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
|
@ -24,6 +24,11 @@ static const char* const emergency_action_table[_EMERGENCY_ACTION_MAX] = {
|
||||
[EMERGENCY_ACTION_EXIT_FORCE] = "exit-force",
|
||||
[EMERGENCY_ACTION_SOFT_REBOOT] = "soft-reboot",
|
||||
[EMERGENCY_ACTION_SOFT_REBOOT_FORCE] = "soft-reboot-force",
|
||||
[EMERGENCY_ACTION_KEXEC] = "kexec",
|
||||
[EMERGENCY_ACTION_KEXEC_FORCE] = "kexec-force",
|
||||
[EMERGENCY_ACTION_HALT] = "halt",
|
||||
[EMERGENCY_ACTION_HALT_FORCE] = "halt-force",
|
||||
[EMERGENCY_ACTION_HALT_IMMEDIATE] = "halt-immediate",
|
||||
};
|
||||
|
||||
static void log_and_status(Manager *m, bool warn, const char *message, const char *reason) {
|
||||
@ -49,7 +54,13 @@ void emergency_action(
|
||||
assert(action < _EMERGENCY_ACTION_MAX);
|
||||
|
||||
/* Is the special shutdown target active or queued? If so, we are in shutdown state */
|
||||
if (IN_SET(action, EMERGENCY_ACTION_REBOOT, EMERGENCY_ACTION_SOFT_REBOOT, EMERGENCY_ACTION_POWEROFF, EMERGENCY_ACTION_EXIT)) {
|
||||
if (IN_SET(action,
|
||||
EMERGENCY_ACTION_REBOOT,
|
||||
EMERGENCY_ACTION_SOFT_REBOOT,
|
||||
EMERGENCY_ACTION_POWEROFF,
|
||||
EMERGENCY_ACTION_EXIT,
|
||||
EMERGENCY_ACTION_KEXEC,
|
||||
EMERGENCY_ACTION_HALT)) {
|
||||
u = manager_get_unit(m, SPECIAL_SHUTDOWN_TARGET);
|
||||
if (u && unit_active_or_pending(u)) {
|
||||
log_notice("Shutdown is already active. Skipping emergency action request %s.",
|
||||
@ -158,6 +169,35 @@ void emergency_action(
|
||||
(void) reboot(RB_POWER_OFF);
|
||||
break;
|
||||
|
||||
case EMERGENCY_ACTION_KEXEC:
|
||||
log_and_status(m, warn, "Executing kexec", reason);
|
||||
(void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_KEXEC_TARGET, JOB_REPLACE_IRREVERSIBLY, NULL, NULL);
|
||||
break;
|
||||
|
||||
case EMERGENCY_ACTION_KEXEC_FORCE:
|
||||
log_and_status(m, warn, "Forcibly executing kexec", reason);
|
||||
m->objective = MANAGER_KEXEC;
|
||||
break;
|
||||
|
||||
case EMERGENCY_ACTION_HALT:
|
||||
log_and_status(m, warn, "Halting", reason);
|
||||
(void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_HALT_TARGET, JOB_REPLACE_IRREVERSIBLY, NULL, NULL);
|
||||
break;
|
||||
|
||||
case EMERGENCY_ACTION_HALT_FORCE:
|
||||
log_and_status(m, warn, "Forcibly halting", reason);
|
||||
m->objective = MANAGER_HALT;
|
||||
break;
|
||||
|
||||
case EMERGENCY_ACTION_HALT_IMMEDIATE:
|
||||
log_and_status(m, warn, "Halting immediately", reason);
|
||||
|
||||
sync();
|
||||
|
||||
log_info("Halting.");
|
||||
(void) reboot(RB_HALT_SYSTEM);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert_not_reached();
|
||||
}
|
||||
|
@ -18,6 +18,11 @@ typedef enum EmergencyAction {
|
||||
EMERGENCY_ACTION_EXIT_FORCE,
|
||||
EMERGENCY_ACTION_SOFT_REBOOT,
|
||||
EMERGENCY_ACTION_SOFT_REBOOT_FORCE,
|
||||
EMERGENCY_ACTION_KEXEC,
|
||||
EMERGENCY_ACTION_KEXEC_FORCE,
|
||||
EMERGENCY_ACTION_HALT,
|
||||
EMERGENCY_ACTION_HALT_FORCE,
|
||||
EMERGENCY_ACTION_HALT_IMMEDIATE,
|
||||
_EMERGENCY_ACTION_MAX,
|
||||
_EMERGENCY_ACTION_INVALID = -EINVAL,
|
||||
} EmergencyAction;
|
||||
|
@ -38,6 +38,14 @@ TEST(parse_emergency_action) {
|
||||
assert_se(parse_emergency_action("exit-force", RUNTIME_SCOPE_SYSTEM, &x) == 0);
|
||||
assert_se(parse_emergency_action("exit-forcee", RUNTIME_SCOPE_SYSTEM, &x) == -EINVAL);
|
||||
assert_se(x == EMERGENCY_ACTION_EXIT_FORCE);
|
||||
assert_se(parse_emergency_action("kexec", RUNTIME_SCOPE_SYSTEM, &x) == 0);
|
||||
assert_se(parse_emergency_action("kexec-force", RUNTIME_SCOPE_SYSTEM, &x) == 0);
|
||||
assert_se(parse_emergency_action("kexec-forcee", RUNTIME_SCOPE_SYSTEM, &x) == -EINVAL);
|
||||
assert_se(x == EMERGENCY_ACTION_KEXEC_FORCE);
|
||||
assert_se(parse_emergency_action("halt", RUNTIME_SCOPE_SYSTEM, &x) == 0);
|
||||
assert_se(parse_emergency_action("halt-force", RUNTIME_SCOPE_SYSTEM, &x) == 0);
|
||||
assert_se(parse_emergency_action("halt-forcee", RUNTIME_SCOPE_SYSTEM, &x) == -EINVAL);
|
||||
assert_se(x == EMERGENCY_ACTION_HALT_FORCE);
|
||||
}
|
||||
|
||||
DEFINE_TEST_MAIN(LOG_INFO);
|
||||
|
@ -13,7 +13,4 @@ Documentation=man:systemd-halt.service(8)
|
||||
DefaultDependencies=no
|
||||
Requires=shutdown.target umount.target final.target
|
||||
After=shutdown.target umount.target final.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=systemctl --force halt
|
||||
SuccessAction=halt-force
|
||||
|
@ -13,7 +13,4 @@ Documentation=man:systemd-kexec.service(8)
|
||||
DefaultDependencies=no
|
||||
Requires=shutdown.target umount.target final.target
|
||||
After=shutdown.target umount.target final.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=systemctl --force kexec
|
||||
SuccessAction=kexec-force
|
||||
|
Loading…
x
Reference in New Issue
Block a user