Apparently user specific systemd instances only exist while there is a session for a specific user. If the last session exits, then the user specific systemd instance exits as well.
There's a way to make a user specific systemd instance persistent, so that users can run unattended long running services: https://wiki.archlinux.org/index.php/Systemd/User#Automatic_start-up_of_systemd_user_instances
Basically you need to activate this option: http://www.freedesktop.org/software/systemd/man/loginctl.html#enable-linger%20USER...
loginctl enable-linger username
However this option is not available in NixOS or NixPkgs, I searched the repo. Also the logind extraConfig doesn't cover it.
I think there might need to be a new option as part of the user management that makes the user instance systemd persistent, and run the above command on bootup and the opposite if the setting changes?
It should of course only run once if it has already ran, even though it is idempotent. I wonder how you can do this?
Right now I'm simply running it during when I pack the image.
There seems to be no option in logind.conf to enable this.
Basically, lingering is enabled in systemd at boot if it finds a file /var/lib/systemd/linger/
We could use a system.activationScript.loginctl-linger
script to call loginctl enable-linger <username>
for each user in the list for which logind show-user <username>
does not return "Linger=yes".
This would work just like user management in https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/config/users-groups.nix#L504-510, except that that script handles much more cases, and optionally handles the deletion of unspecified users.
To go further, you could too remove lingering for users not in the list, but this requires more work and should depend on some option equivalent to users.mutableUsers
or you may surprise some users.
This bit me today, as I _forgot_ to MANUALLY run sudo loginctl enable-linger m
on a new machine running _declarative_ NixOS… :confused: And my multiplexer was killed.
@layus, nb., one should not link to master
, as master
is mutable and your link doesn’t make sense anymore. :smiley_cat:
If anyone’s interested, right now, you can use something along the lines of https://github.com/michalrus/dotfiles/commit/455c18a81c1fcaaccb99625c2f88402ebd08ac23.
Actually, you can effectively 'enable lingering globally' with KillUserProcesses=no
in logind.conf
.
That said, it would probably be better to just compile systemd --without-kill-user-processes
to disable this behavior by default, as this is already being done in e.g. Arch and Debian (I think?).
Killing daemonized user processes on logout breaks user expectations pretty hugely, and is really only beneficial on deliberately very locked down systems (e.g. lan cafe PCs, kiosks), where it could be manually enabled if required. It would be good to have an option to explicitly enable this behavior, as well as options for per-user lingering for those who want to use them, though.
On a more general note, I'm not sure why systemd needs a new way for a program to express the desire to run beyond the lifespan of the current session, in the form of systemd-run
. We already have daemon()
.
FYI, NixOS has KillUserProcesses=no
in logind.conf
since 93c160fabc0e3b5fb3d997c840ef86a68f4bce00.
@CMCDragonkai As bjornfor stated, this issue is now solved in master. Would you mind closing this issue ?
I see the solution provided, but that now always forces lingering. The whole point of this is so that its optional and can be specific to the user session instead of a global setting. Anyway if that global setting, how would people turn off it now?
As I understand it, systemd requires services tout declare somehow their intent to linger after user sessions. The current fix is not a solution. It is required to give some time to upstream packages (like gnu screen where the discussion is tough) to adapt to systemd. Afterwards, we will probably return to systemd default.
For override, see comment in https://github.com/NixOS/nixpkgs/commit/93c160fabc0e3b5fb3d997c840ef86a68f4bce00#commitcomment-18503557
That being said, my personal opinion is that user processes should terminate nicely when the user logs out. It feels like systemd trying to fix the task of the login manager here.
@globin Can you reopen?
If anyone’s interested, right now, you can use something along the lines of https://github.com/michalrus/dotfiles/commit/455c18a81c1fcaaccb99625c2f88402ebd08ac23.
A bit more polished version (now you can do users.users.somebody.linger = true
and disabling/enabling will work): https://github.com/michalrus/dotfiles/commit/ebd5fa9583f82589f23531647aa677feb3f8d344#diff-4d353005ef5b3e37f33c07332b8523edR1
Is it possible to make the setting immutable after it is set using your method @michalrus
@CMCDragonkai, what do you mean by immutable? In your configuration.nix
, after adding my loginctl-linger.nix
to imports = []
, you can do:
{
imports = [
(pkgs.fetchurl { src = "https://raw.githubusercontent.com/michalrus/dotfiles/ebd5fa9583f82589f23531647aa677feb3f8d344/.nixos-config.symlink/modules/loginctl-linger.nix"; sha256 = "…"; })
];
users.extraUsers.cmcdragonkai = {
description = "Roger Qiu";
isNormalUser = true;
linger = true;
};
}
And this is quite immutable. :smiley:
Or do you mean immutable wrt. manually running sudo loginctl enable-linger cmcdragonkai
? =P That would require patching loginctl
. BUT. If you mess up manually, and rerun sudo nixos-rebuild switch
, all will be fixed.
N.b., I’ve opened a feature quest in systemd for the functionality of listing users with lingering enabled → https://github.com/systemd/systemd/issues/3907.
Yep, I was interested in whether the setting can be made immutable in the live environment thus preventing configuration drift. (I usually make /etc readonly). But this is a better solution than the previous one. Is it possible to simplify to just an activation script? A PR to nixpkgs proper would be great.
@CMCDragonkai, sure, I was thinking where that code should go… and dunno.
As for making lingering immutable, I don’t know. The simple and good way would be to patch systemd to check whether the user is allowed to linger not in /var/lib/systemd/linger/
, but somewhere in the /nix/store/
. Then sudo loginctl enable-linger someone
would fail on the syscall level, as the /nix/store/
location would be immutable.
@joachifm, @globin, do you think my current solution is enough for nixpkgs? It’s in https://github.com/michalrus/dotfiles/commit/ebd5fa9583f82589f23531647aa677feb3f8d344#diff-4d353005ef5b3e37f33c07332b8523edR1 I’d rather have patched systemd, but all mentions of /var/lib/systemd/linger
should be replaced in systemd’s runtime with some configurable directory in /nix/store
. Makes it more complicated…
WDYT?
If we do your loginctl PR, then I think this commit should be reversed in the same PR, as otherwise users are lingering by default anyway.
https://github.com/NixOS/nixpkgs/commit/93c160fabc0e3b5fb3d997c840ef86a68f4bce00#commitcomment-18503557
Forgot to add the commit.
Ping @globin this issue is not solved. The best solution that is available at the moment is @michalrus script: https://github.com/michalrus/dotfiles/commit/ebd5fa9583f82589f23531647aa677feb3f8d344#diff-4d353005ef5b3e37f33c07332b8523edR1
Also the currently merged patch which makes processes not killed by default can be overridden: https://github.com/NixOS/nixpkgs/commit/93c160fabc0e3b5fb3d997c840ef86a68f4bce00#commitcomment-18503557
The better future solution is to for systemd to make this declaratively configurable.
(triage) what’s the status?
This is still a problem.
We could fix it in a variety of ways, for example by creating files in /var/lib/systemd/linger based on a user setting, but that would have to be a tristate; by default users can create/remove those using loginctl (enable|disable)-linger
.
I spend about three hours each time I get a new machine debugging it, eventually rediscovering this bug.
This doesn't help with lingering but here's a PR to make it more obvious that killUserProcesses
is something one can toggle: https://github.com/NixOS/nixpkgs/pull/51426
This shouldn't be a global option. Instead this can be part of each individual user's configuration in the declarative fashion. But I think there should always be a simultaneous imperative way of doing it as well.
users = {
users = {
"..." = {
linger = true;
};
};
It shouldn’t be up to the user whether to enable lingering, it’s system/root policy. We can remove a lot of complexity if we only allow this from declarative user configs (aka just generate the linger directory and symlink it based on the config).
If you only allow declarative, a simple implementation like I used in our config should be fine:
# This enables “lingering” for the CI user.
# Inspired by the discussion (and linked code)
# in https://github.com/NixOS/nixpkgs/issues/3702
# This should just be a NixOS option really.
system.activationScripts = {
enableLingering = ''
# remove all existing lingering users
rm -r /var/lib/systemd/linger
mkdir /var/lib/systemd/linger
# enable for the subset of declared users
touch /var/lib/systemd/linger/${constants.ci-user-name}
'';
};
It could be a global policy, but then specific to each to each user?
Hello, I'm a bot and I thank you in the name of the community for opening this issue.
To help our human contributors focus on the most-relevant reports, I check up on old issues to see if they're still relevant. This issue has had no activity for 180 days, and so I marked it as stale, but you can rest assured it will never be closed by a non-human.
The community would appreciate your effort in checking if the issue is still valid. If it isn't, please close it.
If the issue persists, and you'd like to remove the stale label, you simply need to leave a comment. Your comment can be as simple as "still important to me". If you'd like it to get more attention, you can ask for help by searching for maintainers and people that previously touched related code and @ mention them in a comment. You can use Git blame or GitHub's web interface on the relevant files to find them.
Lastly, you can always ask for help at our Discourse Forum or at #nixos' IRC channel.
To the best of my knowledge, this problem persists.
Most helpful comment
This is still a problem.
We could fix it in a variety of ways, for example by creating files in /var/lib/systemd/linger based on a user setting, but that would have to be a tristate; by default users can create/remove those using
loginctl (enable|disable)-linger
.I spend about three hours each time I get a new machine debugging it, eventually rediscovering this bug.