You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
losetup displays wrong path after underlying mount namespace is removed #4166
As expected, we see the path /bar/foo/image for the backing file.
When we run losetup on the host, we see the same path:
$ losetup
NAME SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE DIO LOG-SEC
/dev/loop0 0 0 0 1 /bar/foo/image 0 512
Now, exit from / remove the container (mount namespace).
Now, re-run losetup on the host
$ losetup
NAME SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE DIO LOG-SEC
/dev/loop0 0 0 0 1 /foo/image 0 512
This yields the path minus the previous mount point /bar: /foo/image.
For most applications, this should be non-critical. But it is a
scenario that you're somewhat likely to run into when setting up loop
devices in containers. It's especially misleading if the mount doesn't
happen at the toy /bar path but / of the container, where losetup
just suddenly points to a non-existent path that can't really be traced
back to the container easily.
Skimming loopdev.c, it appears that this is the value reported by
the sysfs, so one could argue if this should be addressed in losetup
at all. I'm not a kernel expert, so I'm not sure if other options
exist for this, but I still wanted to report this as a potential
papercut. Feel free to let me know if this is a wontfix for you.
Reproducible on 6.17.12-400.asahi.fc42.aarch64+16k with the same path issue. Seems like a problem originating in the kernel indeed.
After browsing a bit through the kernel code, looks like the magic happens here: linux/drivers/block/loop.c:loop_attr_backing_file_show()->file_path()->d_path()->prepend_path()
It searches for the mount struct the path's vfsmount object belongs to here and pass that to __prepend_path(), which looks for the mountpoint, if I got it correctly. However, since the struct mount created in the container namespace is gone it will not find anything and return to simply prepend a '/' here.
If you make the mount namespace persistent (unshare --mount=/foo/bar/mnt_ns) you will not have this issue.
Anyways, I'm not very familiar with the VFS internals so maybe @karelzak or @brauner have a better idea of what's going on here.
Would it make sense to use fs/d_path.c:__d_path() to test whether the path is reachable from the root found with fs/d_path.c:get_fs_root_rcu() and then annotate the filename string with (unreachable) if not ?
After debugging a bit with bpftrace, it seems like __prepend_path() returns 2 (here), and if I understand correctly in this case it might indicate that it is an anonymous/detached mount object that is kept alive due to the backing file's reference to it via the loop device. The return value may be useful in dpath() for annotations (e.g. unreachable/detached/not-mounted), no ?
if I understand correctly in this case it might indicate that it is an anonymous/detached mount object that is kept alive due to the backing file's reference to it via the loop device.
I'm no kernel expert, but I understand it like that too. I think annotating it as you explained above will be a great improvement. Potentially also for other tools in util-linux.
This is a common issue; the kernel can provide paths that may not be valid for userspace. It's well known for deleted files; in this case, the kernel is so nice that it appends "(deleted)" to the path.
Userspace tools that just print kernel status (like losetup) should not try to be smart in this case. All we can do is show it to users. I agree that, in the case of an unreachable namespace, it would be nice to add something like "(unreachable)", especially since it already supports "(deleted)".
Activity
cgoesche commentedon Apr 1, 2026
Reproducible on
6.17.12-400.asahi.fc42.aarch64+16kwith the same path issue. Seems like a problem originating in the kernel indeed.After browsing a bit through the kernel code, looks like the magic happens here:
linux/drivers/block/loop.c:loop_attr_backing_file_show()->file_path()->d_path()->prepend_path()It searches for the mount struct the path's vfsmount object belongs to here and pass that to
__prepend_path(),which looks for the mountpoint, if I got it correctly. However, since thestruct mountcreated in the container namespace is gone it will not find anything and return to simply prepend a '/' here.If you make the mount namespace persistent (
unshare --mount=/foo/bar/mnt_ns) you will not have this issue.Anyways, I'm not very familiar with the VFS internals so maybe @karelzak or @brauner have a better idea of what's going on here.
Would it make sense to use
fs/d_path.c:__d_path()to test whether the path is reachable from the root found withfs/d_path.c:get_fs_root_rcu()and then annotate the filename string with(unreachable)if not ?cgoesche commentedon Apr 1, 2026
After debugging a bit with
bpftrace, it seems like__prepend_path()returns 2 (here), and if I understand correctly in this case it might indicate that it is an anonymous/detached mount object that is kept alive due to the backing file's reference to it via the loop device. The return value may be useful indpath()for annotations (e.g. unreachable/detached/not-mounted), no ?msanft commentedon Apr 2, 2026
Thanks for taking this up @cgoesche!
I'm no kernel expert, but I understand it like that too. I think annotating it as you explained above will be a great improvement. Potentially also for other tools in util-linux.
karelzak commentedon Apr 2, 2026
This is a common issue; the kernel can provide paths that may not be valid for userspace. It's well known for deleted files; in this case, the kernel is so nice that it appends "(deleted)" to the path.
Userspace tools that just print kernel status (like
losetup) should not try to be smart in this case. All we can do is show it to users. I agree that, in the case of an unreachable namespace, it would be nice to add something like "(unreachable)", especially since it already supports "(deleted)".cgoesche commentedon May 3, 2026
With this patch the unreachable mount path component is replaced with
(unreachable).The output then looks like this
If this is a reasonable semantic I'd bring this to the VFS maintainers, what do you think ?
msanft commentedon May 3, 2026
Thanks @cgoesche! The patch LGTM! You'd probably want to align the leading space to the
" (deleted)"one, I guesscgoesche commentedon May 3, 2026
Since the
(unreachable)is prepended to the path it should be fine without the whitespace. Unlike the(deleted)label, which is appended.msanft commentedon May 4, 2026
Oops. Sorry! Thanks :)