99 lines
3 KiB
Diff
99 lines
3 KiB
Diff
|
commit 1bd85b64632280d6bf0e86b4ff29da8b19321c5f
|
||
|
Author: Thomas Weißschuh <thomas@t-8ch.de>
|
||
|
Date: Sat May 20 06:38:20 2023 +0200
|
||
|
|
||
|
libmount: check for availability of mount_setattr
|
||
|
|
||
|
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>
|
||
|
|
||
|
diff --git a/libmount/src/hook_mount.c b/libmount/src/hook_mount.c
|
||
|
index a324637cb..01de9e1c5 100644
|
||
|
--- a/libmount/src/hook_mount.c
|
||
|
+++ b/libmount/src/hook_mount.c
|
||
|
@@ -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
|
||
|
index 000000000..3e18ebf09
|
||
|
--- /dev/null
|
||
|
+++ b/tests/expected/mount/fallback-mount_setattr
|
||
|
@@ -0,0 +1 @@
|
||
|
+private
|
||
|
diff --git a/tests/ts/mount/fallback b/tests/ts/mount/fallback
|
||
|
index 6033eb575..b225be189 100755
|
||
|
--- a/tests/ts/mount/fallback
|
||
|
+++ b/tests/ts/mount/fallback
|
||
|
@@ -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
|
||
|
|