KillUserProcesses=yes by default
Set the default policy to terminate processes in session scope when the user logs out. Specifically, systemd-logind's KillUserProcesses setting, which currently is set to "no" to override the upstream default, will be removed to follow the upstream default of "yes".
- Name: Zbigniew Jędrzejewski-Szmek
- Email: email@example.com
- Release notes owner:
- Targeted release: Fedora 25
- Last updated: 2016-07-05
- Tracker bug: <will be assigned by the Wrangler>
Since the introduction of systemd-logind a few years back, when a session is created, systemd hooks into the PAM session creation step to move the process that starts the session into a separate cgroup. This means that processes which are started as part of the session can be reliably tracked, even if they detach from the terminal and daemonize. When a user session terminates, various processes started as part of the user session (initally) remain alive. When the session is terminated, remaining processes receive a HUP signal (*), which can be and often is ignored.
Under the proposed setting of KillUserProcesses=yes, systemd will forcibly terminate (using SIGTERM and then SIGKILL) all processes which are part of the session scope (the cgroup created for the login session) when the user logs out. In order for a process to avoid being killed it has to be part of a different systemd unit. For user processes this can be achieved in two primary ways: by starting the unit as a service (e.g. 'systemd-run --user /usr/bin/foo', or creating a dedicated user service unit), or by telling systemd to create a new scope unit to encompass a specific process (e.g. 'systemd-run --user --scope /usr/bin/foo', or making a dbus call to create a scope unit directly). This step can be integrated directly into programs when this makes sense for their primary use case, e.g. screen.
(*) Whether SIGHUP is sent depends on a few factors: bash sends it children, tcsh does not, and the kernel also sends SIGHUP to processes which have a terminal open.
Benefit to Fedora
Left-over processes cause various issues: the most obvious is the waste of resources that happens when a user thinks they have logged out, but confused processes continue to consume memory and processor cycles. A second type of issues is when those processes hold onto locks and devices, for example a pulse audio processes holding a sound card, preventing other users, or even the same user who logs in again from using those resources. A third type of issues is caused by the fact that left-over processes can keep other services active. In particular, with the change to use a single dbus instance per user, usually left-over session processes will keep this dbus instance around, potentially including other services which would go away if it was terminated. Finally, the session with left-over user processes stays around in "lingering" state, which can be confusing for users and administrators, for example if they want to identify who is actually logged in.
The downside of the proposed change is that simply ignoring SIGHUP or daemonizing is not enough for a process to remain when the login session is terminated. This breaks a long-standing UNIX tradition. Arguably, this tradition arose because of the technical limitation — before sessions could be reliably tracked, it was simply impossible to terminate all children when this session ended. Nevertheless, we argue that terminating all the children of a login session, unless an explicit step is taken, is a better default for a majority of users. While there are always exceptions, in general it is the most advanced users who know that processes can implicitly survive the login session and will take use of it. For "naïve" users, it is unexpected for some processes to remain past the login session. This is true both for those who use a graphical user session, and usually expect that logging-out and logging-in gives them a clean slate, and for users of a multi-tenant system, who do not want stuff remaining after logged-out users. So we want the default to be to terminate processes, and to allow users who want and need to be able to opt-out of this default.
An additional advantage of forcing users to go through an explicit step to create a user service or scope is that this processes is explicit and is logged and can be controlled and through polkit policy, giving a lot of freedom to the admin. When all processes are implicitly allowed to stay around, it is much harder to implement such policy.
- Proposal owners:
- remove the compile-time override
- update the documentation with more explanations and examples, as we learn what people find confusing in the current scheme of things
- evaluate a "permissive" mode for KillUserProcesses, to make it easier to debug processes which stay around after a session terminates.
- work with upstream authors and Fedora maintainers of programs like screen and tmux to implement the ability to automatically start them in a way that survives a user session, and if the system policy does not allow that, to warn the user.
- Other developers:
- cooperate on the last item from previous point
- identify additional services which need to adapt to the changed default.
Different services might merit different handling here: some might be updated them to start through the non-session-specific dbus instance, some might need documentation changes, while others possibly should be handled like tmux and screen.
- Release engineering: N/A
- List of deliverables: N/A (not a System Wide Change)
- Policies and guidelines: a Fedora Magazine article or similar to publicize the change
- Trademark approval: N/A (not needed for this Change)
Explicit configuration for KillUserProcesses= will be honoured. Systems which were using the compiled-in default will get the new behaviour. It is always possible to keep current behaviour by adding 'KillUserProcesses=no' to /etc/systemd/logind.conf or /etc/systemd/logind.conf.d/whatever.conf.
Additional changes will be required to existing programs like screen, tmux, nohup. Without some changes to such programs, or the way that they are called, they will stop functioning as expected.
How To Test
User processes should be terminated when a user session ends. Services which take the steps to stay around should stay around.
When a user logs out no left-over processes remain unexpectedly.
- Contingency mechanism: return to the current status quo of KillUserProcesses=no.
- Contingency deadline: N/A (can be done at any time)
- Blocks release? Yes (?).
- Blocks product? No.