Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HM module: bind mounts not working with HM xsession #20

Closed
sareyko opened this issue Oct 8, 2020 · 5 comments
Closed

HM module: bind mounts not working with HM xsession #20

sareyko opened this issue Oct 8, 2020 · 5 comments

Comments

@sareyko
Copy link

sareyko commented Oct 8, 2020

While playing with the Home Manager module of impermanence I ran into an issue with the systemd user services used by impermanence to do the bind mounts where the mounts seemingly do not work in a graphical session.

After further investigation I noticed that the mounts actually work fine but the systemd services immediately get stopped after a graphical login using HM's xsession module.

Home Manager creates two files that are involved in starting an X session: ~/.xsession and ~/.xprofile.

(Depending on the system configuration) the display manager executes .xsession which in turn sources .xprofile.

.xsession:

if [ -z "$HM_XPROFILE_SOURCED" ]; then
  . ~/.xprofile
fi
unset HM_XPROFILE_SOURCED

systemctl --user start hm-graphical-session.target

[...]

.xprofile:

[...]
if [ -e "$HOME/.profile" ]; then
  . "$HOME/.profile"
fi

# If there are any running services from a previous session.
# Need to run this in xprofile because the NixOS xsession
# script starts up graphical-session.target.
systemctl --user stop graphical-session.target graphical-session-pre.target
[...]

So upon login using a display manager HM actually stops the user services graphical-session.target and graphical-session-pre.target.
According to my research this leads to the following systemd user targets being reached in this order when doing a graphical login:

  1. default.target
  2. graphical-session-pre.target
  3. graphical-session.target

impermanence generates systemd user service descriptions that are:

  • WantedBy=default.target
  • PartOf=graphical-session-pre.target

From what I understand this means that those services get executed to reach default.target and get stopped when graphical-session-pre.target ist stopped.

So in combination this leads to the observed behavior of the bind mounts immediately getting unmounted upon graphical login.

In my opinion HM doing the systemctl --user stop thing in .xprofile is questionable.
I'm posting the issue with the impermanence project nonetheless because I'm not sure using PartOf=graphical-session-pre.target is the correct way to handle the unmounting.

Since I don't know much about systemd I'm not even sure what an alternative would be. But I wonder why the mount services are not stopped with default.target?

@sareyko
Copy link
Author

sareyko commented Oct 8, 2020

So I just did a quick test and did some reading on systemd.

For me changing the PartOf of the bind mount units to default.target or removing it alltogether seems to work just fine. On login the services get started and when I close the last user session they get stopped and the bind mounts get unmounted. This works no matter what way I login (graphical, console or remote).

Since I don't quite understand why PartOf=graphical-session-pre.target is there in the first place I have to ask what the intention of that is? Is this needed to make some part of Home Manager (switching) work correctly?

@talyz
Copy link
Collaborator

talyz commented Oct 17, 2020

The reasoning behind PartOf=graphical-session-pre.target is to have them start as early as possible and before the rest of the graphical user session is started. The user could, for example, have autostart programs which rely on directories being bind mounted. On my installations, which don't use the home-manager xsession, this works fine. I don't really see a reason why the graphical-session-pre.target should be stopped when the session has started; in fact it seems to contradict the upstream description of its use.

@rycee Do you know if there's a reason graphical-session-pre.target is stopped here?

@sareyko
Copy link
Author

sareyko commented Oct 17, 2020

From what I understand making the unit PartOf=graphical-session-pre.target is not the correct way of achieving that behavior since PartOf only affects the unit when the given units are stopped or restarted.

Here's what systemd.unit(5) has to say:

PartOf=
Configures dependencies similar to Requires=, but limited to stopping and restarting of units. When systemd stops or restarts the units listed here, the action is propagated to this unit. Note that this is a one-way dependency — changes to this unit do not affect the listed units.

Also I don't feel like impermanence should depend on a graphical-session at all.
On the other hand I don't see any targets in the various systemd manpages that we could attach to to make sure the bind mount units get started before any other units that might depend on the mounts being present already.
I'm running impermanence with the bind mount units just WantedBy=default.target for a week now without any issues though.

@talyz
Copy link
Collaborator

talyz commented Oct 17, 2020

Oh, right, I got it confused with Requires - they currently start because WantedBy=default.target gets added by default. The correct option would probably be WantedBy=graphical-session-pre.target, though.

@talyz
Copy link
Collaborator

talyz commented Oct 17, 2020

Um, wait, no Install.WantedBy = [ "default.target" ] is in the definition of the unit, so never mind. As it's been working fine so far I guess we could just remove the PartOf and keep the WantedBy as is for now; that way it won't depend on a graphical session either.

@talyz talyz closed this as completed in 4b3000b Oct 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants