]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libmount: add MOVE_MOUNT_BENEATH support
authorKarel Zak <kzak@redhat.com>
Mon, 11 Aug 2025 11:07:38 +0000 (13:07 +0200)
committerKarel Zak <kzak@redhat.com>
Tue, 12 Aug 2025 08:30:30 +0000 (10:30 +0200)
Fixes: https://github.com/util-linux/util-linux/issues/2604
Signed-off-by: Karel Zak <kzak@redhat.com>
include/mount-api-utils.h
libmount/docs/libmount-sections.txt
libmount/src/context.c
libmount/src/hook_mount.c
libmount/src/libmount.h.in
libmount/src/libmount.sym
libmount/src/mountP.h

index 79b50101dccfc3f70d747f01aeb1bed061914da1..920d6766a8a478a3cb70091c6afa57f8423bf5a3 100644 (file)
@@ -65,8 +65,12 @@ static inline int open_tree(int dfd, const char *filename, unsigned int flags)
 # define MOVE_MOUNT_SET_GROUP    0x00000100 /* Set sharing group instead */
 #endif
 
+#ifndef MOVE_MOUNT_BENEATH
+# define MOVE_MOUNT_BENEATH      0x00000200 /* Mount beneath top mount */
+#endif
+
 #ifndef MOVE_MOUNT__MASK
-# define MOVE_MOUNT__MASK 0x00000077
+# define MOVE_MOUNT__MASK        0x00000377
 #endif
 
 #if !defined(HAVE_MOVE_MOUNT) && defined(SYS_move_mount)
index 91d778644c8a22f368e2c2fe37adaef470ceeec8..6070362188f6157af3e9ca972fdda72cf5ca6b15 100644 (file)
@@ -31,6 +31,7 @@ mnt_context_disable_canonicalize
 mnt_context_disable_helpers
 mnt_context_disable_mtab
 mnt_context_disable_swapmatch
+mnt_context_enable_beneath
 mnt_context_enable_exclusive
 mnt_context_enable_fake
 mnt_context_enable_force
@@ -71,6 +72,7 @@ mnt_context_get_user_mflags
 mnt_context_helper_executed
 mnt_context_helper_setopt
 mnt_context_init_helper
+mnt_context_is_beneath
 mnt_context_is_child
 mnt_context_is_exclusive
 mnt_context_is_fake
index 122d2dbf2375915b431e38f2a38233a4388e3c01..66b5c2d8f1b31f423c521ec02b2e8b53112057a1 100644 (file)
@@ -617,6 +617,32 @@ int mnt_context_is_exclusive(struct libmnt_context *cxt)
        return cxt->flags & MNT_FL_EXCL ? 1 : 0;
 }
 
+/**
+ * mnt_context_enable_beneath
+ * @cxt: mount context
+ * @enable: TRUE or FALSE
+ *
+ * Enable/disable underlying mount (move). The filesystem is attached beneath the current
+ * top-level mount of the mountpoint. See mount_move( MOVE_MOUNT_BENEATH ).
+ *
+ * Returns: 0 on success, negative number in case of error.
+ */
+int mnt_context_enable_beneath(struct libmnt_context *cxt, int enable)
+{
+       return set_flag(cxt, MNT_FL_BENEATH, enable);
+}
+
+/**
+ * mnt_context_is_beneath:
+ * @cxt: mount context
+ *
+ * Returns: 1 if beneath mount is enabled or 0
+ */
+int mnt_context_is_beneath(struct libmnt_context *cxt)
+{
+       return cxt->flags & MNT_FL_BENEATH ? 1 : 0;
+}
+
 /**
  * mnt_context_enable_fork:
  * @cxt: mount context
index e1c67990ea454519455c0f2849f28060ce13ae0c..77cf51ad3dbe41657ff6e3e5b54530839c99e40b 100644 (file)
@@ -517,6 +517,7 @@ static int hook_attach_target(struct libmnt_context *cxt,
                void *data __attribute__((__unused__)))
 {
        struct libmnt_sysapi *api;
+       unsigned int flags;
        const char *target;
        int rc = 0;
 
@@ -542,7 +543,11 @@ static int hook_attach_target(struct libmnt_context *cxt,
                umount2(target, MNT_DETACH);
        }
 
-       rc = move_mount(api->fd_tree, "", AT_FDCWD, target, MOVE_MOUNT_F_EMPTY_PATH);
+       flags = MOVE_MOUNT_F_EMPTY_PATH;
+       if (mnt_context_is_beneath(cxt))
+               flags |= MOVE_MOUNT_BENEATH;
+
+       rc = move_mount(api->fd_tree, "", AT_FDCWD, target, flags);
        hookset_set_syscall_status(cxt, "move_mount", rc == 0);
 
        if (rc == 0) {
index fbb6c8ff691bbc58faad972bd1164144203ac246..04b7b30749120ae5299c66ff238481659c3cf6c4 100644 (file)
@@ -818,6 +818,7 @@ extern int mnt_context_set_optsmode(struct libmnt_context *cxt, int mode);
 extern int mnt_context_disable_canonicalize(struct libmnt_context *cxt, int disable);
 extern int mnt_context_enable_onlyonce(struct libmnt_context *cxt, int enable);
 extern int mnt_context_enable_exclusive(struct libmnt_context *cxt, int enable);
+extern int mnt_context_enable_beneath(struct libmnt_context *cxt, int enable);
 extern int mnt_context_enable_lazy(struct libmnt_context *cxt, int enable);
 extern int mnt_context_enable_rdonly_umount(struct libmnt_context *cxt, int enable);
 extern int mnt_context_enable_rwonly_mount(struct libmnt_context *cxt, int enable);
@@ -837,6 +838,8 @@ extern int mnt_context_is_onlyonce(struct libmnt_context *cxt)
                        __ul_attribute__((nonnull));
 extern int mnt_context_is_exclusive(struct libmnt_context *cxt)
                        __ul_attribute__((nonnull));
+extern int mnt_context_is_beneath(struct libmnt_context *cxt)
+                       __ul_attribute__((nonnull));
 extern int mnt_context_is_lazy(struct libmnt_context *cxt)
                        __ul_attribute__((nonnull));
 extern int mnt_context_is_rdonly_umount(struct libmnt_context *cxt)
index 0b0e3bffece8170b2b7a4bfa5cc3bc1917bab6e6..42fefc1508ec82924614270d322dc96fabcb8711 100644 (file)
@@ -410,7 +410,9 @@ MOUNT_2_41 {
 } MOUNT_2_40;
 
 MOUNT_2_42 {
+       mnt_context_enable_beneath;
        mnt_context_enable_exclusive;
+       mnt_context_is_beneath;
        mnt_context_is_exclusive;
        mnt_monitor_enable_mountinfo;
        mnt_monitor_enable_fanotify;
index 8dc31acad9035bc3035ea544b418e48cc024d7a6..fb01041f6b157aa107f6bec95e583f20ec91f47a 100644 (file)
@@ -537,6 +537,7 @@ struct libmnt_context
 #define MNT_FL_RWONLY_MOUNT    (1 << 14)       /* explicit mount -w; never try read-only  */
 #define MNT_FL_ONLYONCE                (1 << 15)
 #define MNT_FL_EXCL            (1 << 16)
+#define MNT_FL_BENEATH         (1 << 17)
 
 #define MNT_FL_MOUNTDATA       (1 << 20)
 #define MNT_FL_TAB_APPLIED     (1 << 21)       /* fstab merged to cxt->fs */