]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libmount: don't canonicalize symlinks for bind operation
authorKarel Zak <kzak@redhat.com>
Thu, 3 Aug 2023 09:43:28 +0000 (11:43 +0200)
committerKarel Zak <kzak@redhat.com>
Thu, 3 Aug 2023 09:58:22 +0000 (11:58 +0200)
The new kernel mount API can bind over symlink by default.

Unfortunately, libmount always canonicalizes all paths (due to
backward compatibility, search in mountinfo, search in fstab, etc.).

Possible workaround is -c, --no-canonicalize but it disable all paths
canonicalization, tags to paths conversions etc.

This patch disables the canonicalization only for the target path
(if symlink) on bind operation.

Fixes: https://github.com/util-linux/util-linux/issues/2370
Signed-off-by: Karel Zak <kzak@redhat.com>
libmount/src/context_mount.c
sys-utils/mount.8.adoc

index 05c84f17021d52ed3d078cba096235619c58c7fb..5aec87d6c3842399728114dddf84aef83f3921cd 100644 (file)
@@ -669,6 +669,7 @@ static int prepare_target(struct libmnt_context *cxt)
        const char *tgt, *prefix;
        int rc = 0;
        struct libmnt_ns *ns_old;
+       struct stat st;
 
        assert(cxt);
        assert(cxt->fs);
@@ -708,7 +709,10 @@ static int prepare_target(struct libmnt_context *cxt)
                return -MNT_ERR_NAMESPACE;
 
        /* canonicalize the path */
-       if (rc == 0) {
+       if (rc == 0 &&
+           !(cxt->optlist && mnt_optlist_is_bind(cxt->optlist)
+             && mnt_safe_lstat(tgt, &st) == 0 && S_ISLNK(st.st_mode))) {
+
                struct libmnt_cache *cache = mnt_context_get_cache(cxt);
 
                if (cache) {
index 74d2960e5401f4cf128553d741b6e96cf28a0d02..6479efd64910430b2eb471dab0a72873a794bc3b 100644 (file)
@@ -240,6 +240,8 @@ It's also possible to change nosuid, nodev, noexec, noatime, nodiratime, relatim
 
 Since util-linux 2.31, *mount* ignores the *bind* flag from _/etc/fstab_ on a *remount* operation (if *-o remount* is specified on command line). This is necessary to fully control mount options on remount by command line. In previous versions the bind flag has been always applied and it was impossible to re-define mount options without interaction with the bind semantic. This *mount* behavior does not affect situations when "remount,bind" is specified in the _/etc/fstab_ file.
 
+Since util-linux 2.40, *mount* does not canonicalize the mountpoint path on bind operation if the target is a symlink. This feature is usable (only) with the new kernel mount API where *bind mount over symlinks* is supported.
+
 === The move operation
 
 Move a *mounted tree* to another place (atomically). The call is:
@@ -317,7 +319,9 @@ Note that it is a bad practice to use *mount -a* for _fstab_ checking. The recom
 Remount a subtree somewhere else (so that its contents are available in both places). See above, under *Bind mount operation*.
 
 *-c*, *--no-canonicalize*::
-Don't canonicalize paths. The *mount* command canonicalizes all paths (from the command line or _fstab_) by default. This option can be used together with the *-f* flag for already canonicalized absolute paths. The option is designed for mount helpers which call *mount -i*. It is strongly recommended to not use this command-line option for normal mount operations.
+Don't canonicalize paths. The *mount* command canonicalizes all paths (from the command line or _fstab_) by default. The option is designed for mount helpers which call *mount -i*. It is strongly recommended to not use this command-line option for normal mount operations.
++
+Since util-linux 2.40, mount does not canonicalize the mountpoint path on bind operation if the target is a symlink (see "*Bind mount operation*" section for more details).
 +
 Note that *mount* does not pass this option to the **/sbin/mount.**__type__ helpers.