manager: fix job mode when signalled to shutdown etc
The irreversible job mode is required to ensure that shutdown is not interrupted by the activation of a unit with a conflict. We already used the correct job mode for `ctrl-alt-del.target`. But not for `exit.target` (SIGINT of user manager). The SIGRT shutdown signals also needed fixing. Also change SIGRTMIN+0 to isolate default.target, instead of starting it. The previous behaviour was documented. However there was no reason given for it, nor can we provide one. The problem that isolate is too aggressive anywhere outside of emergency.target (#2607) is orthogonal. This feature is "accessible by different means and only really a safety net"; it is confusing for it to differ from `systemctl default` without explanation. `AllowIsolate=yes` is retained on poweroff.target etc. for backwards compatibility. `sigpwr.target` is also an obvious candidate for linking to a shutdown target. Unforunately it is also a possible hook for implementing some logic like system V init did, reading `/etc/powerstatus`. If we switched to starting `sigpwr.target` with REPLACE_IRREVERSIBLY, attempts to run `systemctl shutdown` from it would fail, if they had not thought to set `DefaultDependencies=no`. We had provided no examples for `sigpwr`, and the whole idea is cruft to keep legacy people happy. For the moment, I leave `sigpwr` alone, with no risk of disrupting anyone's previously-working, half-working, or untested setup. Fixes #6484. See also #6471
This commit is contained in:
parent
c75fbadac6
commit
d60cb656fc
|
@ -295,7 +295,8 @@
|
||||||
transactions from replacing these jobs (or even being enqueued
|
transactions from replacing these jobs (or even being enqueued
|
||||||
while the irreversible jobs are still pending). Irreversible
|
while the irreversible jobs are still pending). Irreversible
|
||||||
jobs can still be cancelled using the <command>cancel</command>
|
jobs can still be cancelled using the <command>cancel</command>
|
||||||
command.</para>
|
command. This job mode should be used on any transaction which
|
||||||
|
pulls in <filename>shutdown.target</filename>.</para>
|
||||||
|
|
||||||
<para><literal>isolate</literal> is only valid for start
|
<para><literal>isolate</literal> is only valid for start
|
||||||
operations and causes all other units to be stopped when the
|
operations and causes all other units to be stopped when the
|
||||||
|
|
|
@ -561,7 +561,8 @@
|
||||||
<para>systemd user managers will start the
|
<para>systemd user managers will start the
|
||||||
<filename>exit.target</filename> unit when this signal is
|
<filename>exit.target</filename> unit when this signal is
|
||||||
received. This is mostly equivalent to <command>systemctl
|
received. This is mostly equivalent to <command>systemctl
|
||||||
--user start exit.target</command>.</para></listitem>
|
--user start exit.target
|
||||||
|
--job-mode=replace-irreversible</command>.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
|
@ -570,13 +571,13 @@
|
||||||
<listitem><para>Upon receiving this signal the systemd system
|
<listitem><para>Upon receiving this signal the systemd system
|
||||||
manager will start the
|
manager will start the
|
||||||
<filename>ctrl-alt-del.target</filename> unit. This is mostly
|
<filename>ctrl-alt-del.target</filename> unit. This is mostly
|
||||||
equivalent to <command>systemctl start
|
equivalent to <command>systemctl start ctl-alt-del.target
|
||||||
ctl-alt-del.target</command>. If this signal is received more
|
--job-mode=replace-irreversible</command>. If this signal is
|
||||||
than 7 times per 2s, an immediate reboot is triggered.
|
received more than 7 times per 2s, an immediate reboot is
|
||||||
Note that pressing Ctrl-Alt-Del on the console will trigger
|
triggered. Note that pressing Ctrl-Alt-Del on the console
|
||||||
this signal. Hence, if a reboot is hanging, pressing
|
will trigger this signal. Hence, if a reboot is hanging,
|
||||||
Ctrl-Alt-Del more than 7 times in 2s is a relatively safe way
|
pressing Ctrl-Alt-Del more than 7 times in 2s is a relatively
|
||||||
to trigger an immediate reboot.</para>
|
safe way to trigger an immediate reboot.</para>
|
||||||
|
|
||||||
<para>systemd user managers treat this signal the same way as
|
<para>systemd user managers treat this signal the same way as
|
||||||
<constant>SIGTERM</constant>.</para></listitem>
|
<constant>SIGTERM</constant>.</para></listitem>
|
||||||
|
@ -634,7 +635,7 @@
|
||||||
|
|
||||||
<listitem><para>Enters default mode, starts the
|
<listitem><para>Enters default mode, starts the
|
||||||
<filename>default.target</filename> unit. This is mostly
|
<filename>default.target</filename> unit. This is mostly
|
||||||
equivalent to <command>systemctl start
|
equivalent to <command>systemctl isolate
|
||||||
default.target</command>.</para></listitem>
|
default.target</command>.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
@ -661,8 +662,9 @@
|
||||||
|
|
||||||
<listitem><para>Halts the machine, starts the
|
<listitem><para>Halts the machine, starts the
|
||||||
<filename>halt.target</filename> unit. This is mostly
|
<filename>halt.target</filename> unit. This is mostly
|
||||||
equivalent to <command>systemctl start
|
equivalent to <command>systemctl start halt.target
|
||||||
halt.target</command>.</para></listitem>
|
--job-mode=replace-irreversible</command>.</para>
|
||||||
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
|
@ -670,8 +672,9 @@
|
||||||
|
|
||||||
<listitem><para>Powers off the machine, starts the
|
<listitem><para>Powers off the machine, starts the
|
||||||
<filename>poweroff.target</filename> unit. This is mostly
|
<filename>poweroff.target</filename> unit. This is mostly
|
||||||
equivalent to <command>systemctl start
|
equivalent to <command>systemctl start poweroff.target
|
||||||
poweroff.target</command>.</para></listitem>
|
--job-mode=replace-irreversible</command>.</para>
|
||||||
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
|
@ -679,8 +682,9 @@
|
||||||
|
|
||||||
<listitem><para>Reboots the machine, starts the
|
<listitem><para>Reboots the machine, starts the
|
||||||
<filename>reboot.target</filename> unit. This is mostly
|
<filename>reboot.target</filename> unit. This is mostly
|
||||||
equivalent to <command>systemctl start
|
equivalent to <command>systemctl start reboot.target
|
||||||
reboot.target</command>.</para></listitem>
|
--job-mode=replace-irreversible</command>.</para>
|
||||||
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
|
@ -688,8 +692,9 @@
|
||||||
|
|
||||||
<listitem><para>Reboots the machine via kexec, starts the
|
<listitem><para>Reboots the machine via kexec, starts the
|
||||||
<filename>kexec.target</filename> unit. This is mostly
|
<filename>kexec.target</filename> unit. This is mostly
|
||||||
equivalent to <command>systemctl start
|
equivalent to <command>systemctl start kexec.target
|
||||||
kexec.target</command>.</para></listitem>
|
--job-mode=replace-irreversible</command>.</para>
|
||||||
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
|
|
|
@ -2093,7 +2093,8 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t
|
||||||
if (MANAGER_IS_SYSTEM(m))
|
if (MANAGER_IS_SYSTEM(m))
|
||||||
manager_handle_ctrl_alt_del(m);
|
manager_handle_ctrl_alt_del(m);
|
||||||
else
|
else
|
||||||
manager_start_target(m, SPECIAL_EXIT_TARGET, JOB_REPLACE);
|
manager_start_target(m, SPECIAL_EXIT_TARGET,
|
||||||
|
JOB_REPLACE_IRREVERSIBLY);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SIGWINCH:
|
case SIGWINCH:
|
||||||
|
@ -2161,14 +2162,17 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t
|
||||||
default: {
|
default: {
|
||||||
|
|
||||||
/* Starting SIGRTMIN+0 */
|
/* Starting SIGRTMIN+0 */
|
||||||
static const char * const target_table[] = {
|
static const struct {
|
||||||
[0] = SPECIAL_DEFAULT_TARGET,
|
const char *target;
|
||||||
[1] = SPECIAL_RESCUE_TARGET,
|
JobMode mode;
|
||||||
[2] = SPECIAL_EMERGENCY_TARGET,
|
} target_table[] = {
|
||||||
[3] = SPECIAL_HALT_TARGET,
|
[0] = { SPECIAL_DEFAULT_TARGET, JOB_ISOLATE },
|
||||||
[4] = SPECIAL_POWEROFF_TARGET,
|
[1] = { SPECIAL_RESCUE_TARGET, JOB_ISOLATE },
|
||||||
[5] = SPECIAL_REBOOT_TARGET,
|
[2] = { SPECIAL_EMERGENCY_TARGET, JOB_ISOLATE },
|
||||||
[6] = SPECIAL_KEXEC_TARGET
|
[3] = { SPECIAL_HALT_TARGET, JOB_REPLACE_IRREVERSIBLY },
|
||||||
|
[4] = { SPECIAL_POWEROFF_TARGET, JOB_REPLACE_IRREVERSIBLY },
|
||||||
|
[5] = { SPECIAL_REBOOT_TARGET, JOB_REPLACE_IRREVERSIBLY },
|
||||||
|
[6] = { SPECIAL_KEXEC_TARGET, JOB_REPLACE_IRREVERSIBLY }
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Starting SIGRTMIN+13, so that target halt and system halt are 10 apart */
|
/* Starting SIGRTMIN+13, so that target halt and system halt are 10 apart */
|
||||||
|
@ -2182,8 +2186,8 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t
|
||||||
if ((int) sfsi.ssi_signo >= SIGRTMIN+0 &&
|
if ((int) sfsi.ssi_signo >= SIGRTMIN+0 &&
|
||||||
(int) sfsi.ssi_signo < SIGRTMIN+(int) ELEMENTSOF(target_table)) {
|
(int) sfsi.ssi_signo < SIGRTMIN+(int) ELEMENTSOF(target_table)) {
|
||||||
int idx = (int) sfsi.ssi_signo - SIGRTMIN;
|
int idx = (int) sfsi.ssi_signo - SIGRTMIN;
|
||||||
manager_start_target(m, target_table[idx],
|
manager_start_target(m, target_table[idx].target,
|
||||||
(idx == 1 || idx == 2) ? JOB_ISOLATE : JOB_REPLACE);
|
target_table[idx].mode);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue