]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libmount: check for availability of mount_setattr
authorThomas Weißschuh <thomas@t-8ch.de>
Sat, 20 May 2023 04:38:20 +0000 (06:38 +0200)
committerThomas Weißschuh <thomas@t-8ch.de>
Mon, 22 May 2023 07:38:07 +0000 (09:38 +0200)
If mount_setattr is not available but needed fall back to the legacy
mount API.

Fixes #2247

Signed-off-by: Thomas Weißschuh <thomas@t-8ch.de>
libmount/src/hook_mount.c
tests/expected/mount/fallback-mount_setattr [new file with mode: 0644]
tests/ts/mount/fallback

index a324637cb73e5260ac06704f82ec14b82c852a8b..01de9e1c57396959dc69fdcbed2c0b5f4b2e6dde 100644 (file)
@@ -510,6 +510,15 @@ static inline int fsopen_is_supported(void)
        return rc;
 }
 
+static inline int mount_setattr_is_supported(void)
+{
+       int rc;
+
+       errno = 0;
+       rc = mount_setattr(-1, NULL, 0, NULL, 0);
+       return !(rc == -1 && errno == ENOSYS);
+}
+
 /*
  * open_tree() and fsopen()
  */
@@ -675,9 +684,14 @@ static int hook_prepare(struct libmnt_context *cxt,
        /* call mount_setattr() */
        if (!rc
            && cxt->helper == NULL
-           && (set != 0 || clr != 0 || (flags & MS_REMOUNT)))
+           && (set != 0 || clr != 0 || (flags & MS_REMOUNT))) {
+               if (!mount_setattr_is_supported()) {
+                       hookset_deinit(cxt, hs);
+                       return 1;
+               }
                rc = mnt_context_append_hook(cxt, hs, MNT_STAGE_MOUNT, NULL,
                                        hook_set_vfsflags);
+       }
 
        /* call move_mount() to attach target */
        if (!rc
@@ -688,9 +702,14 @@ static int hook_prepare(struct libmnt_context *cxt,
                                        hook_attach_target);
 
        /* set propagation (has to be attached to VFS) */
-       if (!rc && mnt_optlist_get_propagation(ol))
+       if (!rc && mnt_optlist_get_propagation(ol)) {
+               if (!mount_setattr_is_supported()) {
+                       hookset_deinit(cxt, hs);
+                       return 1;
+               }
                rc = mnt_context_append_hook(cxt, hs, MNT_STAGE_MOUNT_POST, NULL,
                                        hook_set_propagation);
+       }
 
        DBG(HOOK, ul_debugobj(hs, "prepare mount done [rc=%d]", rc));
        return rc;
diff --git a/tests/expected/mount/fallback-mount_setattr b/tests/expected/mount/fallback-mount_setattr
new file mode 100644 (file)
index 0000000..3e18ebf
--- /dev/null
@@ -0,0 +1 @@
+private
index 6033eb5757b3d2c9c277887b236d3a68c63a1a09..b225be189a92eb758a1deecae6a7f49924ed5298 100755 (executable)
@@ -68,5 +68,21 @@ $TS_CMD_UMOUNT $MOUNTPOINT
 ts_finalize_subtest
 
 
+ts_init_subtest "mount_setattr"
+"$TS_CMD_MOUNT" "$DEVICE" "$MOUNTPOINT"  >> $TS_OUTPUT 2>> $TS_ERRLOG
+ts_is_mounted $DEVICE || ts_log "Cannot find $DEVICE in /proc/mounts"
+$TS_CMD_ENOSYS -s mount_setattr -- \
+       "$TS_CMD_MOUNT" -o remount,ro "$MOUNTPOINT" \
+       >> $TS_OUTPUT 2>> $TS_ERRLOG
+$TS_CMD_FINDMNT --kernel --mountpoint "$MOUNTPOINT" --options "ro" &> /dev/null
+[ "$?" == "0" ] || ts_die "Cannot find read-only in $MOUNTPOINT in /proc/self/mountinfo"
+$TS_CMD_ENOSYS -s mount_setattr -- \
+       "$TS_CMD_MOUNT" --make-slave "$MOUNTPOINT" \
+       >> $TS_OUTPUT 2>> $TS_ERRLOG
+$TS_CMD_FINDMNT -n --kernel --mountpoint "$MOUNTPOINT" -o PROPAGATION >> $TS_OUTPUT
+$TS_CMD_UMOUNT $MOUNTPOINT
+ts_finalize_subtest
+
+
 ts_finalize