@@ -647,6 +647,7 @@ _overlay_config_override()
# Set fsck options, use default if user not set directly.
export FSCK_OPTIONS="$OVERLAY_FSCK_OPTIONS"
[ -z "$FSCK_OPTIONS" ] && _fsck_opts
+ export IDMAPPED_MOUNTS="$IDMAPPED_MOUNTS"
}
_overlay_config_restore()
@@ -73,6 +73,7 @@ _overlay_base_mount()
if [ -z "$dev" -o -z "$mnt" ] || \
_check_mounted_on $devname $dev $mntname $mnt; then
+ _idmapped_mount $dev $mnt
# no base fs or already mounted
return 0
elif [ $? -ne 1 ]; then
@@ -81,6 +82,7 @@ _overlay_base_mount()
fi
_mount $* $dev $mnt
+ _idmapped_mount $dev $mnt
}
_overlay_base_test_mount()
@@ -334,6 +334,7 @@ _try_scratch_mount()
return $?
fi
_mount -t $FSTYP `_scratch_mount_options $*`
+ _idmapped_mount $SCRATCH_DEV $SCRATCH_MNT
}
# mount scratch device with given options and _fail if mount fails
@@ -444,6 +445,53 @@ _scratch_shutdown_handle()
fi
}
+_move_mount()
+{
+ local mnt=$1
+ local tmp=$2
+
+ # Replace $mnt with $tmp. Use a temporary bind-mount because
+ # mount --move will fail with certain mount propagation layouts.
+ $UMOUNT_PROG $mnt || _fail "Failed to unmount $mnt"
+ _mount --bind $tmp $mnt || _fail "Failed to bind-mount $tmp to $mnt"
+ $UMOUNT_PROG $tmp || _fail "Failed to unmount $tmp"
+ rmdir $tmp
+}
+
+_idmapped_mount()
+{
+ [ "$IDMAPPED_MOUNTS" = "true" ] || return 0
+
+ local dev=$1
+ local mnt=$2
+ local status=0
+ local tmp=`mktemp -d`
+
+ local mount_rec=`findmnt -rncv -S $dev -o OPTIONS`
+ if [[ "$mount_rec" == *"idmapped"* ]]; then
+ return 0
+ fi
+
+ # We create an idmapped mount where {g,u}id 0 writes to disk as
+ # {g,u}id 10000000 and $(id -u fsgqa) + 10000000. We change ownership
+ # of $mnt so {g,u} id 0 can actually create objects in there.
+ chown 10000000:10000000 $mnt || return 1
+ $here/src/idmapped-mounts/mount-idmapped \
+ --map-mount b:10000000:0:100000000000 \
+ $mnt $tmp
+ if [ $? -ne 0 ]; then
+ rmdir $tmp
+ return 1
+ fi
+
+ # The next call ensures we don't end up stacking an idmapped mount on
+ # top of the original mount. Instead we fully replace the original
+ # mount with the idmapped mount. This will not just allow a clean mount
+ # layout it also makes unmount and remounting way simpler.
+ _move_mount $mnt $tmp
+ return $?
+}
+
_test_mount()
{
if [ "$FSTYP" == "overlay" ]; then
@@ -452,6 +500,7 @@ _test_mount()
fi
_test_options mount
_mount -t $FSTYP $TEST_OPTIONS $TEST_FS_MOUNT_OPTS $SELINUX_MOUNT_OPTIONS $* $TEST_DEV $TEST_DIR
+ _idmapped_mount $TEST_DEV $TEST_DIR
}
_test_unmount()
@@ -3007,6 +3056,7 @@ _mount_or_remount_rw()
if [ $USE_REMOUNT -eq 0 ]; then
if [ "$FSTYP" != "overlay" ]; then
_mount -t $FSTYP $mount_opts $device $mountpoint
+ _idmapped_mount $device $mountpoint
else
_overlay_mount $device $mountpoint
fi
In addition to the generic and filesystem-specific idmapped mount testsuites that already exist upstream today add simple infrastructure so any test can be run on idmapped mounts simply by setting IDMAPPED_MOUNTS=true in the config file or section. The main user for now will be overlay to verify it works correctly on idmapped mounts. Cc: Eryu Guan <guaneryu@gmail.com> Cc: Christoph Hellwig <hch@lst.de> Cc: <fstests@vger.kernel.org> Signed-off-by: Christian Brauner (Microsoft) <brauner@kernel.org> --- common/config | 1 + common/overlay | 2 ++ common/rc | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+)