Bug#825394: systemd kills background processes after user logs out
Jonathan de Boyne Pollard
J.deBoynePollard-newsgroups at NTLWorld.com
Wed Jun 1 22:15:59 BST 2016
Martin Pitt:
> The option has already be reverted in the packaging git.
> This isn't an exercise in "who shouts the loudest".
It should, however, be an exercise in fixing bugs properly. (-:
Turning off the enabling flag doesn't fix the underlying flawed
mechanism. There is still a logind bug to be fixed.
logind has invented its own systemd login session mechanism (as a "scope
unit") . It adds processes to a systemd login session. There's a moral
equivalent of session leadership. Systemd login sessions close. At
session closure, other processes in the session are sent a signal. So
far, this is reinventing the kernel's login session concept (as
augmented by some job control shells) quite straightforwardly.
The bug is a very simple one. systemd *sends the wrong signal* when it
is decided that the session is closing. It should send SIGHUP. It
instead sends SIGTERM and then sends SIGKILL. However, logind is the
locus of the bug because it is logind that is constructing the login
session and instructing systemd what to do, via the internal systemd
Desktop Bus protocol. It's as simple as that.
Send SIGHUP instead of SIGTERM+SIGKILL at systemd login session closure,
and systemd and logind will continue to interoperate with wget, deluged,
mosh-server, emacs --daemon, screen, tmux, and all of the rest —
including anything invoked via nohup. The DBUS server programs (in
Freedesktop bug #94508) that are staying alive in the systemd login
session because of a circular dependency receive a SIGHUP, which
terminates them and breaks the circle. The programs (in this bug and
bug #825941) that have masked/ignored SIGHUP, because that's been the
protocol for the past 37 years or more (since 7th Edition at minimum),
avoid termination as they desire.
There are two ways to fix this that I can see.
The first way is to fix the systemd login session so that systemd
terminates it with SIGHUP. systemd is told what the "stop" action is
for the session by logind. At the moment, in your manager_start_scope()
function, logind is creating the systemd login session with the
equivalent of
> KillSignal=SIGTERM
> SendSIGHUP=yes
> SendSIGKILL=yes
Modify that function to instead use the equivalent of
> KillSignal=SIGHUP
> SendSIGHUP=yes
> SendSIGKILL=no
This is an inferior route, in my view, to the second way of doing this.
The second way of doing this is for logind not to try to *stop* the
login session in the first place. Leave that to system shutdown and
suchlike, which can use "StopUnit" and the resultant SIGTERMs+SIGKILLs
in circumstances where those are actually appropriate even to nohupped
processes. Rather, modify your session_stop_scope() function to call a
new manager_hangup_scope() function, which invokes "KillUnit" on the
login session with a kill-who of "all" and a kill-signal of SIGHUP.
More information about the Pkg-systemd-maintainers
mailing list