manager: reexecute on SIGRTMIN+25, user instances only

Before this patch, there was no way to request all running user instances for
reexecuting. However this can be useful especially during package updates
otherwise user instances are never updated and keep running a potentially very
old version of the binaries.

Now assuming that we have enough priviledge, it's possible to request
reexecution of all user instances:

  systemctl kill --signal=SIGRTMIN+25 "user@*.service"

Note that this request is obviously asynchronous as it relies on a
signal. Keeping "systemctl kill" as the only interface should be good enough to
make this obvious and that's the reason why another interface, such as
"systemctl --global daemon-reexec" has not been considered.

PID1 already uses SIGTERM for reexecuting hence sending it SIGRTMIN+25 is a
nop.
This commit is contained in:
Franck Bui 2021-07-23 11:12:03 +02:00 committed by Lennart Poettering
parent fac5588944
commit 463aef23a7
2 changed files with 16 additions and 2 deletions

View file

@ -585,6 +585,17 @@
for --user instances).</para></listitem>
</varlistentry>
<varlistentry>
<term><constant>SIGRTMIN+25</constant></term>
<listitem><para>Upon receiving this signal the systemd manager will reexecute itself. This
is mostly equivalent to <command>systemctl daemon-reexec</command> except that it will be
done asynchronously.</para>
<para>The systemd system manager treats this signal the same way as
<constant>SIGTERM</constant>.</para></listitem>
</varlistentry>
<varlistentry>
<term><constant>SIGRTMIN+26</constant></term>

View file

@ -578,8 +578,7 @@ static int manager_setup_signals(Manager *m) {
SIGRTMIN+22, /* systemd: set log level to LOG_DEBUG */
SIGRTMIN+23, /* systemd: set log level to LOG_INFO */
SIGRTMIN+24, /* systemd: Immediate exit (--user only) */
/* .. one free signal here ... */
SIGRTMIN+25, /* systemd: reexecute manager */
/* Apparently Linux on hppa had fewer RT signals until v3.18,
* SIGRTMAX was SIGRTMIN+25, and then SIGRTMIN was lowered,
@ -2846,6 +2845,10 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t
/* This is a nop on init */
break;
case 25:
m->objective = MANAGER_REEXECUTE;
break;
case 26:
case 29: /* compatibility: used to be mapped to LOG_TARGET_SYSLOG_OR_KMSG */
manager_restore_original_log_target(m);