Change:
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: Basically you need to activate this option: 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 to enable this. Basically, lingering is enabled in systemd at boot if it finds a file /var/lib/systemd/linger/<username. We could use a script to call for each user in the list for which does not return "Linger=yes". This would work just like user management in , 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 or you may surprise some users.
This bit me today, as I forgot to MANUALLY run on a new machine running declarative NixOS… :confused: And my multiplexer was killed. nb., one should not link to , as 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
Actually, you can effectively 'enable lingering globally' with in . That said, it would probably be better to just compile systemd 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 . We already have .
FYI, NixOS has in since .
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 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.
Can you reopen?
A bit more polished version (now you can do and disabling/enabling will work):
Is it possible to make the setting immutable after it is set using your method
what do you mean by immutable? In your , after adding my to , you can do: And this is quite immutable. :smiley: Or do you mean immutable wrt. manually running ? =P That would require patching . BUT. If you mess up manually, and rerun , all will be fixed. N.b., I’ve opened a feature quest in systemd for the functionality of listing users with lingering enabled →
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.
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 , but somewhere in the . Then would fail on the syscall level, as the location would be immutable. do you think my current solution is enough for nixpkgs? It’s in I’d rather have patched systemd, but all mentions of should be replaced in systemd’s runtime with some configurable directory in . 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.
Forgot to add the commit.
Ping this issue is not solved. The best solution that is available at the moment is script: Also the currently merged patch which makes processes not killed by default can be overridden: 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 . 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 is something one can toggle:
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.
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:
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 or on the relevant files to find them. Lastly, you can always ask for help at or at .
To the best of my knowledge, this problem persists.
I marked this as stale due to inactivity. &rarr;
Still an issue
I marked this as stale due to inactivity. &rarr;
Still an issue
: sorry about pinging you, but would it be possible to add a setting for this? Much appreciated! The from the comment above works, but that's kinda against Nix principles.
Ping because it's still relevant.
Maybe something similar to ↓ would feel cleaner (no lingering processes, everything still under systemd’s control) / acceptable to some:
I think in logind's design it is the options KillUserProcesses, KillOnlyUsers and KillExcludeUsers which are system / root policy. A regular user is able to enable lingering for him/herself using loginctl enable-linger
Is there anything major that actually speaks against adding this option to ?
It looks like subsequently stopped using his module and deleted it. I updated it slightly to work with recent NixOS: I agree with that this seems like it's good enough to just add as a regular user option. Happy to make a PR if that helps?
I am trying to clean up my nixpkgs and this is one of the commits I've been carrying for some time. I think we should get something in and iterate if need be. I suspect a number of people are carrying some variant of this anyway. If you send a PR, I'll review it!
That would be great.
This issue has been mentioned on NixOS Discourse. There might be relevant details there:
I'm waiting for an "official solution" (something like ). But in the meantime, I am using the following config: Keeping it here for future NixOS newbies like me, but hopefully this has been resolved by then. Do check the module on the stable NixOS before you use this!
I tested on two other nixos machines and it worked fine there, and looking at /proc/logind/mounts it looks like the logind on the first system I tested on was using an old configuration for some reason. put everything in order and I'll try to get the PR up later today. Sorry for the red herring.
I cannot believe this is now fixed :party: ! Thanks to everybody involved over the years, this is amazing !
Hooray.
It is amazing that this option exists, thank you! I noticed, however, that it is not persistent when using a temporal root file system. Other options related to users are persistent. Is this behavior desired? Can it even be changed? I can restore on boot, and all is fine, but just wanted to bring up this thought. Cheers!
Given that this was achieved via an activation script, I don't understand why this would matter?
Yeah, it shouldn't matter if persists -- it'll get recreated on activate, and should also make sure the user's slice starts. So maybe it doesn't start exactly on boot but it should start on activate at the latest. Something that I think may be worth addressing, raised by SuperSandro2000 , is that this change makes it impossible to mutably manage linger even if is set. We could make it contingent on , or we could make the default value rather than and only enable/disable-linger for users where it's explicitly set -- I think the latter would make the activation script a bit more complicated, but I prefer it.
Hm, maybe I missed something but if I do not persist the folder , lingering does not persist either on my setup. As far as I understand your replies, this behavior is unexpected because activation scripts are run during boot. If you want, I can do more tests or create a separate issue.
I noticed this as well. I created a tmpfiles rule to automatically create my file, but it seems like that rule should already be in there. Is there any reason we would expect linger to be set to true and that file should not exist?

Discussion:
administrator before being able to use the system again. ''; }; <ins> linger = mkOption { type = types.bool; default = false; description = lib.mdDoc '' Whether to enable lingering for this user. If true, systemd user units will start at boot, rather than starting at login and stopping at logout. This is the declarative equivalent of running `loginctl enable-linger` for this user. If false, user units will not be started until the user logs in, and may be stopped on logout depending on the settings in `logind.conf`. ''; }; </ins> }; config = mkMerge

''; }; <ins> system.activationScripts.update-lingering = let lingerDir = "/var/lib/systemd/linger"; lingeringUsers = map (u: u.name) (attrValues (flip filterAttrs cfg.users (n: u: u.linger))); lingeringUsersFile = builtins.toFile "lingering-users" (concatStrings (map (s: "${s}n") (sort (a: b: a < b) lingeringUsers)));  # this sorting is important for `comm` to work correctly in stringAfter [ "users" ] '' if [ -e ${lingerDir} ] ; then cd ${lingerDir} ls ${lingerDir} | sort | comm -3 -1 ${lingeringUsersFile} - | xargs -r ${pkgs.systemd}/bin/loginctl disable-linger ls ${lingerDir} | sort | comm -3 -2 ${lingeringUsersFile} - | xargs -r ${pkgs.systemd}/bin/loginctl  enable-linger fi ''; </ins> # Warn about user accounts with deprecated password hashing schemes system.activationScripts.hashes = { deps = [ "users" ];