-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
Fixes for the systemd mount generator #9611
Conversation
Codecov Report
@@ Coverage Diff @@
## master #9611 +/- ##
==========================================
+ Coverage 79.19% 79.26% +0.07%
==========================================
Files 418 418
Lines 123531 123531
==========================================
+ Hits 97828 97923 +95
+ Misses 25703 25608 -95
Continue to review full report at Codecov.
|
So I've started looking deeper into this generator and I've noticed it not only creates .mount units for all auto-mountable datasets (which is fine), it also symlinks them into local-fs.target.wants, which makes systemd try to mount them all and query you for all encryption roots' passphrases. I'm not sure if this is intended behaviour, I will admit it is similar to how I've prepared such a commit in a different branch. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The PR, as written, looks good to me. I haven't tested it, but the changes seem correct in principle.
I think that getting the system running with a minimum of mounts and keyloads coming from systemd itself and the rest through zfs mount -a might be more desirable
No, absolutely not. That defeats the entire purpose of the mount generator. systemd needs to be aware of the individual mounts, as this fixes/avoids all sorts of problems. If people do not want the generator, they don't have to use it. But when using the generator, it needs to make mount units for everything that is to be mounted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wait, I may have spoken too soon. These changes are fine for the use case presented, but what if there are encryption roots that are intentionally not being mounted? For example, imagine I had per-user encryption for each home directory. In that case, the system administrator is not going to be able to provide the passphrase for each user's home directory.
I think we want to generate the load-key unit for an encryption root if it is to be automounted or if one of its children is to be automounted. We probably need to do this by going through all the mountpoints and making a (uniqued) list of encryption roots, then have a second loop over those encryption roots to write the load-key units.
@aerusso Can you look at this too? |
Ok, so I'm happy with the typo fix, and the change to the path for I agree with @rlaager: the purpose of this generator is to fully emulate the behavior of having things in There's also the whole This brings me to the core of this change: unconditionally creating the unit. As @rlaager also correctly points out, we don't want to accidentally start the I'd say to squash |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, so I'm happy with the typo fix, and the change to the path for
sh
(which is a whole other can of worms---the documentation for systemd was pretty clear on this issue, but---hey---what works works).
It's quite possible that this behavior changed over time (i.e. systemd versions).
This brings me to the core of this change: unconditionally creating the unit. As @rlaager also correctly points out, we don't want to accidentally start the
zfs-load-key-.service
.
I think you're giving me too much credit, and you have just mentioned a critical point! :) I was worried about creating the load-key unit, but you're right, it's only starting it that is a problem. This simplifies the problem space, as we can simply delegate this to systemd. Specifically, we can always create the load-key unit, but it will only get pulled in when one of the mount units Wants it. That appears to be what this change is doing. So yeah, this should be good.
However, my quick re-read of the code is that nothing automatically creates a dependency on
$keyloadunit
. Can you, @InsanePrawn, please confirm, by testing, this behavior?
It looks like the mount units will get a wants on it, as the wants variable is modified at line 126.
Yeah, and grepping the source shows this is only ever mentioned in
So, yeah, just double check it and squash the |
As I tried to express earlier: Removing the As I've said, I've tested it works correctly in my setup. Only the required minimum of mounts and their key-load units get started. I'll do some more testing in different setups in VMs. You can manually blacklist individual key-load units from boot with So the consensus is that I should pull in the commit from the other branch? I'd still argue in favour of a 'symlink all the mounts like in older versions' switch somewhere, effectively making a systemd implementation of |
As I said, that sounds wrong. If I create a dataset at /srv/backup and no systemd unit explicitly depends on it, what mounts it? What mounts it if the zfs-mount.service goes away in the future (or is masked)? It is correct for all local mountpoints to be pulled in by local-fs. That is its point. This is consistent with what happens in /etc/fstab. The load-key units should NOT be pulled-in by local-fs, but by the mount units. That is what this PR does, right?
No. |
Signed-off-by: InsanePrawn <insane.prawny@gmail.com>
Systemd will ignore units that try to execute programs from non-absolute paths. Use hardcoded /bin/sh instead. Signed-off-by: InsanePrawn <insane.prawny@gmail.com>
fcb36c5
to
4687b43
Compare
I did some git wizardry and think/hope i got the path commit right. :)
I've got my dependencies down, they're minimal and my system boots fine with my other branch's patch. The problem is that ALL MOUNTABLE ZFS DATASETS are a requirement for local-fs.target without said patch.
Also: What if your /srv/backup dataset is an encryption root with a passphrase? What if it's actually /home/tony and that damn tony guy doesn't give you his passphrase? Do you really want systemd to prompt you for all encryption root passphrases that are relevant to any dataset that can be mounted?
This appears to drift into a philosophical question. I have large-ish dataset hierarchies (as in: a lot of datasets with a lot of nesting) and I'd much prefer if [after setting a config value] systemd did the pure minimum explicitly required and let something else handle the rest a little bit later. If nothing else, it means way less spam on my screen when [re]booting :D
Yes and no. The load-key units are only referenced by the .mount units, so only .mount units that get depended on (either through a unit requirement or a symlink) pull in their key-load units. That was always the case, I didn't change the unit definitions at all (except for the /bin/sh fix). Before the commits in this pr, the generator would skip processing lines of datasets that can't be mounted automatically. This would lead to also skipping generating key-load units for such datasets, which might be required to mount a different dataset. I reordered the code so the key-load unit is generated anyway.
Meh, as I said, I'd be strongly in favour of having this behaviour available, even if it's not the default. |
Unfortunately, I think your last rebase (or at least what's pushed) clobbered the removal half of the moving of the code (it just duplicates it now).
The point I'm trying to make is: either those datasets are to be mounted (and
No. Those datasets should be
Well, you have to decide whether you want the units to try to be mounted automatically, and whether or not they should try to load the keys. If you want the keys automatically loaded, then if you mount a dataset automatically, that's what happens. You should be able to mask mount units, though, to get the special case behavior you're asking for here.
I'm sorry, this is a really special case you're asking for: mounting local filesystems after |
6a5cc53
to
0bddd62
Compare
pathdep="RequiresMountsFor='${p_keyloc#file://}'" | ||
keyloadcmd="@sbindir@/zfs load-key '${dataset}'" | ||
elif [ "${p_keyloc}" = "prompt" ] ; then | ||
keyloadcmd="@bindir@/sh -c 'set -eu;"\ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be /bin/sh
now, right?
Previously the generator would skip a dataset if it wasn't mountable by 'zfs mount -a' (legacy/none mountpoint, canmount off/noauto). This also skipped the generation of key-load units for such datasets, breaking the dependency handling for mountable child datasets. Signed-off-by: InsanePrawn <insane.prawny@gmail.com>
@InsanePrawn Up to my one comment (the rebase clobbered the Also, there's an argument for making the mount units for |
0bddd62
to
6f29f7f
Compare
We should ideally create units for noauto and not Wants them, as this sounds like it is the behavior of the stock fstab generator. I was going to suggest that as a separate change. However, if we have two datasets with the same mountpoint and one is noauto and one is “on”, we would have a problem. The unit name comes from the mountpoint (and AFAIK this is required). We would need to give precedence to the auto one. The current code handles this by skipping all noauto mounts. But once we lift that, it will be a problem. The code currently refuses to overwrite existing mount files. If we changed that to only apply for noauto, then the auto one would overwrite if it came later, but would not be overwritten if it came first. This would achieve the right result without making the generator take two passes. @aerusso, do you see any problem with this change? Was there a good reason to not overwrite existing mountfiles? |
I didn't overwrite existing units out of an abundance of caution. I'm happy with the PR as is. If we start talking about multiple datasets with the same mountpoint, I'm starting to think that we should figure out if there is any consensus in the larger community. As a ZFS-user I think in terms of "<dataset> mounted at <mountpoint>," but most Linux users probably think of "the filesystem mounted at <mountpoint>", and the systemd interface is built around that. I vote LGTM as is, and then have a more thorough discussion for a follow-up patch. |
@aerusso Agreed on merging this PR as is. Can you change your review to approved? Also, I did check (now that I'm not on a cell phone), and the systemd.mount documentation says, "Mount units must be named after the mount point directories they control." So when we have multiple datasets with the same mountpoint (e.g. in root-on-ZFS scenarios, with multiple root filesystems), we can only write out one mount unit. Clearly we need the auto to override the noauto one(s) in that case. |
Systemd will ignore units that try to execute programs from non-absolute paths. Use hardcoded /bin/sh instead. Reviewed-by: Antonio Russo <antonio.e.russo@gmail.com> Reviewed-by: Richard Laager <rlaager@wiktel.com> Signed-off-by: InsanePrawn <insane.prawny@gmail.com> Closes #9611
Previously the generator would skip a dataset if it wasn't mountable by 'zfs mount -a' (legacy/none mountpoint, canmount off/noauto). This also skipped the generation of key-load units for such datasets, breaking the dependency handling for mountable child datasets. Reviewed-by: Antonio Russo <antonio.e.russo@gmail.com> Reviewed-by: Richard Laager <rlaager@wiktel.com> Signed-off-by: InsanePrawn <insane.prawny@gmail.com> Closes #9611
Merged. Thanks for sorting this out. |
Reviewed-by: Antonio Russo <antonio.e.russo@gmail.com> Reviewed-by: Richard Laager <rlaager@wiktel.com> Signed-off-by: InsanePrawn <insane.prawny@gmail.com> Closes openzfs#9611
Systemd will ignore units that try to execute programs from non-absolute paths. Use hardcoded /bin/sh instead. Reviewed-by: Antonio Russo <antonio.e.russo@gmail.com> Reviewed-by: Richard Laager <rlaager@wiktel.com> Signed-off-by: InsanePrawn <insane.prawny@gmail.com> Closes openzfs#9611
Previously the generator would skip a dataset if it wasn't mountable by 'zfs mount -a' (legacy/none mountpoint, canmount off/noauto). This also skipped the generation of key-load units for such datasets, breaking the dependency handling for mountable child datasets. Reviewed-by: Antonio Russo <antonio.e.russo@gmail.com> Reviewed-by: Richard Laager <rlaager@wiktel.com> Signed-off-by: InsanePrawn <insane.prawny@gmail.com> Closes openzfs#9611
Reviewed-by: Antonio Russo <antonio.e.russo@gmail.com> Reviewed-by: Richard Laager <rlaager@wiktel.com> Signed-off-by: InsanePrawn <insane.prawny@gmail.com> Closes openzfs#9611
Systemd will ignore units that try to execute programs from non-absolute paths. Use hardcoded /bin/sh instead. Reviewed-by: Antonio Russo <antonio.e.russo@gmail.com> Reviewed-by: Richard Laager <rlaager@wiktel.com> Signed-off-by: InsanePrawn <insane.prawny@gmail.com> Closes openzfs#9611
Previously the generator would skip a dataset if it wasn't mountable by 'zfs mount -a' (legacy/none mountpoint, canmount off/noauto). This also skipped the generation of key-load units for such datasets, breaking the dependency handling for mountable child datasets. Reviewed-by: Antonio Russo <antonio.e.russo@gmail.com> Reviewed-by: Richard Laager <rlaager@wiktel.com> Signed-off-by: InsanePrawn <insane.prawny@gmail.com> Closes openzfs#9611
Reviewed-by: Antonio Russo <antonio.e.russo@gmail.com> Reviewed-by: Richard Laager <rlaager@wiktel.com> Signed-off-by: InsanePrawn <insane.prawny@gmail.com> Closes #9611
Systemd will ignore units that try to execute programs from non-absolute paths. Use hardcoded /bin/sh instead. Reviewed-by: Antonio Russo <antonio.e.russo@gmail.com> Reviewed-by: Richard Laager <rlaager@wiktel.com> Signed-off-by: InsanePrawn <insane.prawny@gmail.com> Closes #9611
Previously the generator would skip a dataset if it wasn't mountable by 'zfs mount -a' (legacy/none mountpoint, canmount off/noauto). This also skipped the generation of key-load units for such datasets, breaking the dependency handling for mountable child datasets. Reviewed-by: Antonio Russo <antonio.e.russo@gmail.com> Reviewed-by: Richard Laager <rlaager@wiktel.com> Signed-off-by: InsanePrawn <insane.prawny@gmail.com> Closes #9611
Fixes a typo and two bigger problems with the systemd mount generator:
sh -c ...
directly, which systemd on my Debian 9(!) doesn't allow. It wants an absolute path, so I replaced it with@bindir@/sh -c ...
. On my system,@bindir@
correctly resolves to/usr/bin
, although/bin
works just as well since it's a symlink to/usr/bin
.Do we want
@bindir@
or a hardcoded/bin
?Motivation and Context
Consider a pool with an unmountable (canmount=off) root dataset as the encryption root and mountable children. To mount the children, one has to load the key for the root dataset. The old generator implementation would not generate a load-key unit for the root dataset, as it has canmount=off set. Therefore, the user would never be prompted for the password (or whatever keysource they selected) on boot, the depending dataset mounts fail, boot continues but it's obviously not functional.
Description
Change summary:
sh
as@bindir@/sh
.How Has This Been Tested?
Locally on my machine. Anybody else willing to write tests for this?
Types of changes
Checklist:
Signed-off-by
.