Files
apfstests/common/overlay
T
Amir Goldstein 668a411a73 overlay: nicer report when features are not supported
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>
2018-06-07 16:58:37 +08:00

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
}