-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Drop path prefix workaround #11295
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
Drop path prefix workaround #11295
Conversation
Canonicalization, the source of the trouble, was disabled in 9000a9f. Signed-off-by: Sterling Jensen <[email protected]>
6333c4b
to
2729334
Compare
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.
Looks good. Thanks!
Canonicalization, the source of the trouble, was disabled in 9000a9f. Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Sterling Jensen <[email protected]> Closes #11295
This turned out to be breaking change in the end. If you have a pool named This is more common than it seems because cd /
mkdir foo
mount -t zfs foo /foo # will run `mount.zfs /foo /foo` internally because /foo exists Since this is a breaking change I think it should be reverted, what do you think? |
Thanks for reporting this. That sure does look like a case where we regressed. @sterlingjensen could you take a another look at this? This is something we'll want to extend the test case to cover. |
It seems to me that this is more a question of maintaining backwards compatibility for surprising broken behavior. If that is the objective than a back out may involve more than just this patch, because the only thing it does is remove an unnecessary check for unwanted behavior that has been fixed for years elsewhere in the code. I'm not even sure how far back we'd have to roll things to maintain compatibility with broken scripts... path canonicalization was disabled in 2017 in order to correct this very issue. |
@sterlingjensen is mounting This is also reproducible if you have the following systemd mount unit (this is how I found it actually): [Mount]
Where=/foo
What=foo
Type=zfs It is definitely not just broken scripts that will observe the breaking change. |
@petrosagg Yes mounting zfs volumes with # dd if=/dev/zero of=/tmp/vdev0 bs=1M count=64
64+0 records in
64+0 records out
67108864 bytes (67 MB, 64 MiB) copied, 0.055691 s, 1.2 GB/s
# zpool create foo /tmp/vdev0; stat -fc %T /foo
zfs
# zfs get type,mounted,mountpoint,canmount foo
NAME PROPERTY VALUE SOURCE
foo type filesystem -
foo mounted yes -
foo mountpoint /foo default
foo canmount on default
# zfs unmount foo; stat -fc %T /foo
xfs
# ### BIG HINT INCOMING! ###
# cd ~; mount -t zfs foo /foo
filesystem 'foo' cannot be mounted using 'mount'.
Use 'zfs set mountpoint=legacy' or 'zfs mount foo'.
See zfs(8) for more information.
# ### BIG HINT OUTGOING! ###
# zfs set mountpoint=legacy foo; mkdir /foo; stat -fc %T /foo
xfs
# mount -t zfs foo /foo; stat -fc %T /foo
zfs
# zfs get type,mounted,mountpoint,canmount foo
NAME PROPERTY VALUE SOURCE
foo type filesystem -
foo mounted yes -
foo mountpoint legacy local
foo canmount on default See? Oh, and using device paths instead of datasets for the # mount -t zfs /tmp/vdev0 /foo; stat -fc %T /foo
zfs Or have I completely misunderstood your problem? I can't tell you how to fix your systemd configs, because I don't use systemd. |
@sterlingjensen I think what you missed from the reproduction, which is also what caused me endless headaches before narrowing this bug down, is that you need to run the mount command while in the root directory. There is a
This doesn't sound right. You wouldn't say setting an encryption key is unsupported UNLESS you turn on encryption. Sure, it's named To give a bit more context of my situation, I have a NixOS box with ZFS set up as per their official guides which failed to boot after an upgrade.
Of course, I'm not looking for a systemd solution or a NixOS solution or anything like that. My point that this PR breaks at least two reasonable ways of interacting with ZFS, not some quirky script I wrote myself. Plus, the PR claimed to be a non-breaking change which shipped in a patch release but turns out it breaks real systems. Here is a complete script based on what you wrote above that reproduces the breakage: #!/usr/bin/env bash
set -o errexit
set -x
dd if=/dev/zero of=/tmp/vdev0 bs=1M count=64
zpool create foo /tmp/vdev0
zfs unmount foo
zfs set mountpoint=legacy foo;
# This is what triggers the edge case
# systemd will also run all mount commands with its cwd set to /
cd /
mkdir /foo;
mount -t zfs foo /foo If you run the above with version 2.0.0 it works as expected. I'm happy to PR a revert of the above plus the addition of this test case. |
Ah, I think I finally get it. I understood you to be asking for the very libmount path canonicalization that leads to this kind of unwanted path rewriting. Did you happen to spot from where in the stack this unwanted help was being inflicted, or did you stop at where I removed the otherwise redundant string manipulation? My memory is a little fuzzy, but I want to say that the entire point of the |
The problematic code in mount(8) can be found here. For local filesystems there will be an attempt to canonicalize the path. You can see there are already exceptions to prevent canonicalization for network filesystem sources (line 1786), known source tags (line 1797) and even pseudo filesystems (line 1806). Unfortunately, ZFS doesn't fall under any of the existing exceptions. It'd be ideal if we could get included under one of these exceptions in This is somewhat beside the point, but
The reason for this is that the zfs utilities need to be aware of which mount points they're actively managing to support things like
|
@behlendorf thanks, I opened an issue upstream (util-linux/util-linux#1231) as well to see if we can fix it there @sterlingjensen no, I haven't looked deeper into the ZFS code that triggers this |
@petrosagg The path is malformed before hitting the mount helper, so you correctly identified the problem. This is a very old problem with libmount, so I think your revert + test would be welcome. Or I can clean up my own mistake, dealers choice - let me know. |
@sterlingjensen thanks. Can you please open a new PR which adds back the needed prefix removal code with a test case. I think that'd be preferable to a straight revert. |
@sterlingjensen I think it's going to take me a fair amount of work to get the whole test suite working on my computer (NixOS is not great for ad-hoc things like that). I pushed a commit that I think is correct with the test case here |
Sorry for the delay, one of these days I'll become competent with kornshell - but not today. #11462 |
Oh guys, why do complain so late? ;-) This is something that is pretty simple to resolve in libmount. If I good understand the source is always "dataset" and never device name or path, right? In this case, add an exception to libmount will be pretty simple. I'll do it and I can also backport it to util-linux 2.36.2. |
Fixes: #1231 Addresses: systemd/systemd#18188 Addresses: openzfs/zfs#11295 Signed-off-by: Karel Zak <[email protected]>
This is awesome! Thank you so much!
…On Thu, Jan 14, 2021, 12:29 Karel Zak ***@***.***> wrote:
Oh guys, why do complain so late? ;-) This is something that is pretty
simple to resolve in libmount.
If I good understand the source is *always* "dataset" and *never* device
name or path, right? In this case, add an exception to libmount will be
pretty simple. I'll do it and I can also backport it to util-linux 2.36.2.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#11295 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAHFLHET46YPBIFD5OWCW7TSZ3ISNANCNFSM4UPHAOZA>
.
|
@karelzak that was fast, thanks! Yes, it's expected to be a dataset name. |
@behlendorf Wait... are we talking about the target string passed to the mount helper? Because that string can definitely be something other than a dataset name. Lines 45 to 52 in 60a2434
|
Correct. It's normally expected to be the dataset name, but we wanted to also support passing a vdev path as well. I think that's generally useful behavior. For example, and at the time this made it possible to adapt xfstests to run on ZFS which was handy. With the libmount change it seems like that should still be possible it's just not going to canonicalize the provided path for us. |
Well then that is great news, just wanted to make sure - given the prior 'always "dataset" and never device name or path' qualifier. |
The change in libmount means that for example symlinks and tags (LABEL=foo) will not be converted to the device name. If this behavior is not expected then we can make it more sensitive to other scenarios. For example, source strings that start with "/dev" can be used as a path; we can use tags in the traditional way, etc. It would be nice if you can define the source string more precisely for me. Thanks. |
@karelzak If the change to libmount means that it no longer modifies the path string, then I believe that is exactly what everybody wants. We've already got ZFS specific logic built into the mount helper, coincidentally this commit was for the function that performs device name conversion - specifically the part that undoes libmount's path canonicalization 😏 |
Prior to util-linux 2.36.2, if a file or directory in the current working directory was named 'dataset' then mount(8) would prepend the current working directory to the dataset. Eventually, we should be able to drop this workaround. Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Sterling Jensen <[email protected]> Closes #11295 Closes #11462
@sterlingjensen OK, libmount since v2.37 and v2.36.2 will not touch the mount source string for ZFS at all. |
Prior to util-linux 2.36.2, if a file or directory in the current working directory was named 'dataset' then mount(8) would prepend the current working directory to the dataset. Eventually, we should be able to drop this workaround. Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Sterling Jensen <[email protected]> Closes openzfs#11295 Closes openzfs#11462
Prior to util-linux 2.36.2, if a file or directory in the current working directory was named 'dataset' then mount(8) would prepend the current working directory to the dataset. Eventually, we should be able to drop this workaround. Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Sterling Jensen <[email protected]> Closes #11295 Closes #11462
Fixes: #1231 Addresses: systemd/systemd#18188 Addresses: openzfs/zfs#11295 Signed-off-by: Karel Zak <[email protected]>
Canonicalization, the source of the trouble, was disabled in 9000a9f. Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Sterling Jensen <[email protected]> Closes openzfs#11295
Prior to util-linux 2.36.2, if a file or directory in the current working directory was named 'dataset' then mount(8) would prepend the current working directory to the dataset. Eventually, we should be able to drop this workaround. Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Sterling Jensen <[email protected]> Closes openzfs#11295 Closes openzfs#11462
Canonicalization, the source of the trouble, was disabled in 9000a9f. Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Sterling Jensen <[email protected]> Closes openzfs#11295
Prior to util-linux 2.36.2, if a file or directory in the current working directory was named 'dataset' then mount(8) would prepend the current working directory to the dataset. Eventually, we should be able to drop this workaround. Reviewed-by: Brian Behlendorf <[email protected]> Signed-off-by: Sterling Jensen <[email protected]> Closes openzfs#11295 Closes openzfs#11462
Canonicalization, the source of the trouble, was disabled in 9000a9f.
Signed-off-by: Sterling Jensen [email protected]
Motivation and Context
Description
How Has This Been Tested?
Types of changes
Checklist:
Signed-off-by
.