[systemd-devel] shutdown: how to tell systemd to stop a service before killing other processes
Lennart Poettering
lennart at poettering.net
Tue Aug 27 11:34:35 UTC 2019
On So, 25.08.19 18:57, Hans-Dieter Doll (Hans-Dieter.Doll at drb.insel.de) wrote:
> On shutdown we need to stop a service before systemd begins to kill
> all processes it does not know.
All processes on the system are indirectly "known" by systemd. All
processes (except kernel threads) belong to a unit that systemd
manages. Use "systemd-cgls" to determine which units a specific PID is
considered belonging to by systemd.
Whenever systemd stops a unit it will terminate its contained
processes, but this behaviour can be tweaked via KillMode= of the
specific unit. If a process belongs to a unit that has KillMode=none
set for example it is never killed by systemd until the very last
phase of shutdown.
Hence, if you have processes that are killed too early for your
requirements, relative to some other processes figure out which units
they belong to, then add an After= dependency between them. Keep in
mind though that shutdown order between two units is always the
inverse of the start-up order between them, and the After=
dependencies defines the start-up order. Hence if you want A.service
go down before B.service you need to add After=B.service to A.service
(or Before=A.service to B.service), but not the reverse!
> The problem is: aside from background processes started by the
> supervisor, we have applications started in a user session, but
> which are also controlled by the supervisor.
User sessions are managed as "scope" units. You need to thus make sure
you order your services relative to these scope units. That's not
trivial since these scope units are named after their session IDs, and
those are assigned dynamically, at the time of login. However, these
scopes are collectively ordered after the special
systemd-user-session.service (which is a service that manages
/run/nologin and thus decides when users can and cannot login). You
might be able to make use of that — but of course only if your
fake-session-services are supposed to die before the clean system
services, if you follow what I mean, not the rother way round. If you
need the opposite order, i.e. start your real system services down
*before* the fake services that run as login sessions, then you might
be able to get away with adding a drop-in to
/etc/systemd/system/session-.scope.d/50-order.conf or so which just
says:
<snip>
[Unit]
Before=myservice.service
</snip>
That way you order *all* scope sessions on your system before your
system service and thus enforce that the system service gets
terminated before the scopes are terminated. But this is ugly as fuck,
ymmv. This makes use "-.d/" drop-ins, which were added in systemd
v239.
That all said, this design is deeply flawed, system services should
*not* be login sessions. System services are one thing, login sessions
another, and intermixing them is just calling from trouble. Clean up
your system and make each system service an actual system service, it
will make you much happier in the long run.
Lennart
--
Lennart Poettering, Berlin
More information about the systemd-devel
mailing list