commit 1bd85b64632280d6bf0e86b4ff29da8b19321c5f Author: Thomas Weißschuh 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 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