mirror of
https://github.com/linux-apfs/apfstests.git
synced 2026-05-01 15:01:44 -07:00
668a411a73
Commit ea7ad43 ("fstests: implement require of multiple overlayfs
features") changed the message when tests are not run due to missing
overlayfs feature.
Restore the check for existing module param before trying to mount
which restores the old message format, e.g.:
[not run] feature 'metacopy' not supported by overlay
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Reviewed-by: Eryu Guan <guaneryu@gmail.com>
Signed-off-by: Eryu Guan <guaneryu@gmail.com>
323 lines
7.9 KiB
Plaintext
323 lines
7.9 KiB
Plaintext
#
|
|
# overlayfs specific common functions.
|
|
#
|
|
. ./common/module
|
|
|
|
# Export overlayfs xattrs and constant value
|
|
export OVL_XATTR_OPAQUE="trusted.overlay.opaque"
|
|
export OVL_XATTR_REDIRECT="trusted.overlay.redirect"
|
|
export OVL_XATTR_IMPURE="trusted.overlay.impure"
|
|
export OVL_XATTR_ORIGIN="trusted.overlay.origin"
|
|
export OVL_XATTR_NLINK="trusted.overlay.nlink"
|
|
export OVL_XATTR_UPPER="trusted.overlay.upper"
|
|
export OVL_XATTR_METACOPY="trusted.overlay.metacopy"
|
|
|
|
# helper function to do the actual overlayfs mount operation
|
|
_overlay_mount_dirs()
|
|
{
|
|
local lowerdir=$1
|
|
local upperdir=$2
|
|
local workdir=$3
|
|
shift 3
|
|
|
|
$MOUNT_PROG -t overlay -o lowerdir=$lowerdir -o upperdir=$upperdir \
|
|
-o workdir=$workdir `_common_dev_mount_options $*`
|
|
}
|
|
|
|
# Mount with same options/mnt/dev of scratch mount, but optionally
|
|
# with different lower/upper/work dirs
|
|
_overlay_scratch_mount_dirs()
|
|
{
|
|
local lowerdir=$1
|
|
local upperdir=$2
|
|
local workdir=$3
|
|
shift 3
|
|
|
|
_overlay_mount_dirs $lowerdir $upperdir $workdir \
|
|
$* $OVL_BASE_SCRATCH_MNT $SCRATCH_MNT
|
|
}
|
|
|
|
_overlay_mkdirs()
|
|
{
|
|
local dir=$1
|
|
|
|
mkdir -p $dir/$OVL_UPPER
|
|
mkdir -p $dir/$OVL_LOWER
|
|
mkdir -p $dir/$OVL_WORK
|
|
mkdir -p $dir/$OVL_MNT
|
|
}
|
|
|
|
# Given a base fs dir, set up overlay directories and mount on the given mnt.
|
|
# The dir is used as the mount device so it can be seen from df or mount
|
|
_overlay_mount()
|
|
{
|
|
local dir=$1
|
|
local mnt=$2
|
|
shift 2
|
|
|
|
_supports_filetype $dir || _notrun "upper fs needs to support d_type"
|
|
|
|
_overlay_mkdirs $dir
|
|
|
|
_overlay_mount_dirs $dir/$OVL_LOWER $dir/$OVL_UPPER $dir/$OVL_WORK \
|
|
$* $dir $mnt
|
|
}
|
|
|
|
_overlay_base_mount()
|
|
{
|
|
local devname=$1
|
|
local mntname=$2
|
|
local dev=$3
|
|
local mnt=$4
|
|
shift 4
|
|
|
|
if [ -z "$dev" -o -z "$mnt" ] || \
|
|
_check_mounted_on $devname $dev $mntname $mnt; then
|
|
# no base fs or already mounted
|
|
return 0
|
|
elif [ $? -ne 1 ]; then
|
|
# base fs mounted but not on mount point
|
|
return 1
|
|
fi
|
|
|
|
_mount $* $dev $mnt
|
|
}
|
|
|
|
_overlay_base_test_mount()
|
|
{
|
|
_overlay_base_mount OVL_BASE_TEST_DEV OVL_BASE_TEST_DIR \
|
|
"$OVL_BASE_TEST_DEV" "$OVL_BASE_TEST_DIR" \
|
|
$TEST_FS_MOUNT_OPTS $SELINUX_MOUNT_OPTIONS
|
|
}
|
|
|
|
_overlay_test_mount()
|
|
{
|
|
_overlay_base_test_mount && \
|
|
_overlay_mount $OVL_BASE_TEST_DIR $TEST_DIR $*
|
|
}
|
|
|
|
_overlay_base_scratch_mount()
|
|
{
|
|
_overlay_base_mount OVL_BASE_SCRATCH_DEV OVL_BASE_SCRATCH_MNT \
|
|
"$OVL_BASE_SCRATCH_DEV" "$OVL_BASE_SCRATCH_MNT" \
|
|
$OVL_BASE_MOUNT_OPTIONS $SELINUX_MOUNT_OPTIONS
|
|
}
|
|
|
|
_overlay_scratch_mount()
|
|
{
|
|
_overlay_base_scratch_mount && \
|
|
_overlay_mount $OVL_BASE_SCRATCH_MNT $SCRATCH_MNT $*
|
|
}
|
|
|
|
_overlay_base_unmount()
|
|
{
|
|
local dev=$1
|
|
local mnt=$2
|
|
|
|
[ -n "$dev" -a -n "$mnt" ] || return 0
|
|
|
|
$UMOUNT_PROG $mnt
|
|
}
|
|
|
|
_overlay_test_unmount()
|
|
{
|
|
$UMOUNT_PROG $TEST_DIR
|
|
_overlay_base_unmount "$OVL_BASE_TEST_DEV" "$OVL_BASE_TEST_DIR"
|
|
}
|
|
|
|
_overlay_scratch_unmount()
|
|
{
|
|
$UMOUNT_PROG $SCRATCH_MNT
|
|
_overlay_base_unmount "$OVL_BASE_SCRATCH_DEV" "$OVL_BASE_SCRATCH_MNT"
|
|
}
|
|
|
|
# Check that a specific overlayfs feature is supported
|
|
__check_scratch_overlay_feature()
|
|
{
|
|
local feature=$1
|
|
|
|
# overalyfs features (e.g. redirect_dir, index) are
|
|
# configurable from Kconfig (the build default), by module
|
|
# parameter (the system default) and per mount by mount
|
|
# option ${feature}=[on|off].
|
|
local default=`_get_fs_module_param ${feature}`
|
|
[ "$default" = Y ] || [ "$default" = N ] || \
|
|
_notrun "feature '${feature}' not supported by ${FSTYP}"
|
|
|
|
# Check options to be sure. For example, Overlayfs will fallback to
|
|
# index=off if underlying fs does not support file handles.
|
|
# Overlayfs only displays mount option if it differs from the default.
|
|
# Overlayfs may enable the feature, but fallback to read-only mount.
|
|
((( [ "$default" = N ] && _fs_options $SCRATCH_DEV | grep -q "${feature}=on" ) || \
|
|
( [ "$default" = Y ] && ! _fs_options $SCRATCH_DEV | grep -q "${feature}=off" )) && \
|
|
touch $SCRATCH_MNT/foo 2>/dev/null ) || \
|
|
_notrun "${FSTYP} feature '${feature}' cannot be enabled on ${SCRATCH_DEV}"
|
|
}
|
|
|
|
# Require a set of overlayfs features
|
|
_require_scratch_overlay_features()
|
|
{
|
|
local features=( $* )
|
|
local opts="rw"
|
|
|
|
for feature in ${features[*]}; do
|
|
# If the module parameter does not exist then there is no
|
|
# point in checking the mount option.
|
|
_get_fs_module_param ${feature} > /dev/null 2>&1 || \
|
|
_notrun "feature '${feature}' not supported by overlay"
|
|
opts+=",${feature}=on"
|
|
done
|
|
|
|
_scratch_mkfs > /dev/null 2>&1
|
|
_try_scratch_mount -o $opts || \
|
|
_notrun "overlay features '${features[*]}' cannot be enabled on ${SCRATCH_DEV}"
|
|
|
|
for feature in ${features[*]}; do
|
|
__check_scratch_overlay_feature ${feature}
|
|
done
|
|
|
|
_scratch_unmount
|
|
}
|
|
|
|
# Helper function to check underlying dirs of overlay filesystem
|
|
_overlay_fsck_dirs()
|
|
{
|
|
local lowerdir=$1
|
|
local upperdir=$2
|
|
local workdir=$3
|
|
shift 3
|
|
|
|
[[ ! -x "$FSCK_OVERLAY_PROG" ]] && return 0
|
|
|
|
$FSCK_OVERLAY_PROG -o lowerdir=$lowerdir -o upperdir=$upperdir \
|
|
-o workdir=$workdir $*
|
|
}
|
|
|
|
_overlay_check_dirs()
|
|
{
|
|
local lowerdir=$1
|
|
local upperdir=$2
|
|
local workdir=$3
|
|
shift 3
|
|
local err=0
|
|
|
|
_overlay_fsck_dirs $lowerdir $upperdir $workdir \
|
|
$FSCK_OPTIONS $* >>$tmp.fsck 2>&1
|
|
if [ $? -ne 0 ]; then
|
|
_log_err "_overlay_check_fs: overlayfs on $lowerdir,$upperdir,$workdir is inconsistent"
|
|
|
|
echo "*** fsck.overlay output ***" >>$seqres.full
|
|
cat $tmp.fsck >>$seqres.full
|
|
echo "*** end fsck.overlay output" >>$seqres.full
|
|
|
|
echo "*** mount output ***" >>$seqres.full
|
|
_mount >>$seqres.full
|
|
echo "*** end mount output" >>$seqres.full
|
|
|
|
err=1
|
|
fi
|
|
rm -f $tmp.fsck
|
|
|
|
return $err
|
|
}
|
|
|
|
# Check the same mnt/dev of _check_overlay_scratch_fs but non-default
|
|
# underlying scratch dirs of overlayfs, it needs lower/upper/work dirs
|
|
# provided as arguments, and it's useful for non-default setups such
|
|
# as multiple lower layers
|
|
_overlay_check_scratch_dirs()
|
|
{
|
|
local lowerdir=$1
|
|
local upperdir=$2
|
|
local workdir=$3
|
|
shift 3
|
|
|
|
# Need to umount overlay for scratch dir check
|
|
local ovl_mounted=`_is_dir_mountpoint $SCRATCH_MNT`
|
|
[ -z "$ovl_mounted" ] || $UMOUNT_PROG $SCRATCH_MNT
|
|
|
|
# Check dirs with extra overlay options
|
|
_overlay_check_dirs $lowerdir $upperdir $workdir $*
|
|
local ret=$?
|
|
|
|
if [ $ret -eq 0 -a -n "$ovl_mounted" ]; then
|
|
# overlay was mounted, remount with extra mount options
|
|
_overlay_scratch_mount_dirs $lowerdir $upperdir \
|
|
$workdir $*
|
|
ret=$?
|
|
fi
|
|
|
|
return $ret
|
|
}
|
|
|
|
_overlay_check_fs()
|
|
{
|
|
# The first arguments is overlay mount point use for checking
|
|
# overlay filesystem is mounted or not, the remaining arquments
|
|
# use for mounting overlay base filesystem if it was not mounted.
|
|
# We shift one to aligns arguments for _overlay_base_mount.
|
|
local ovl_mnt=$1
|
|
shift 1
|
|
|
|
local base_dev=$3
|
|
local base_mnt=$4
|
|
|
|
[ "$FSTYP" = overlay ] || return 0
|
|
|
|
# Base fs needs to be mounted to check overlay dirs
|
|
local base_fstype=""
|
|
local ovl_mounted=""
|
|
|
|
[ -z "$base_dev" ] || \
|
|
base_fstype=`_fs_type $base_dev`
|
|
|
|
# If base_dev is set but base_fstype is empty, base fs is not
|
|
# mounted, we need to mount base fs. Otherwise, we need to
|
|
# check and umount overlayfs if it was mounted.
|
|
if [ -n "$base_dev" -a -z "$base_fstype" ]; then
|
|
_overlay_base_mount $*
|
|
else
|
|
# Check and umount overlay for dir check
|
|
ovl_mounted=`_is_dir_mountpoint $ovl_mnt`
|
|
[ -z "$ovl_mounted" ] || $UMOUNT_PROG $ovl_mnt
|
|
fi
|
|
|
|
_overlay_check_dirs $base_mnt/$OVL_LOWER $base_mnt/$OVL_UPPER \
|
|
$base_mnt/$OVL_WORK
|
|
local ret=$?
|
|
|
|
if [ -n "$base_dev" -a -z "$base_fstype" ]; then
|
|
_overlay_base_unmount "$base_dev" "$base_mnt"
|
|
elif [ $ret -eq 0 -a -n "$ovl_mounted" ]; then
|
|
# overlay was mounted, remount besides extra mount options
|
|
_overlay_mount $base_mnt $ovl_mnt
|
|
ret=$?
|
|
fi
|
|
|
|
if [ $ret != 0 ]; then
|
|
status=1
|
|
if [ "$iam" != "check" ]; then
|
|
exit 1
|
|
fi
|
|
return 1
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
_check_overlay_test_fs()
|
|
{
|
|
_overlay_check_fs "$TEST_DIR" \
|
|
OVL_BASE_TEST_DEV OVL_BASE_TEST_DIR \
|
|
"$OVL_BASE_TEST_DEV" "$OVL_BASE_TEST_DIR" \
|
|
$TEST_FS_MOUNT_OPTS $SELINUX_MOUNT_OPTIONS
|
|
}
|
|
|
|
_check_overlay_scratch_fs()
|
|
{
|
|
_overlay_check_fs "$SCRATCH_MNT" \
|
|
OVL_BASE_SCRATCH_DEV OVL_BASE_SCRATCH_MNT \
|
|
"$OVL_BASE_SCRATCH_DEV" "$OVL_BASE_SCRATCH_MNT" \
|
|
$OVL_BASE_MOUNT_OPTIONS $SELINUX_MOUNT_OPTIONS
|
|
}
|