fi
fi
+_dump_err()
+{
+ err_msg="$*"
+ echo "$err_msg"
+}
+
+_dump_err2()
+{
+ err_msg="$*"
+ >2& echo "$err_msg"
+}
+
+_log_err()
+{
+ err_msg="$*"
+ echo "$err_msg" | tee -a $seqres.full
+ echo "(see $seqres.full for details)"
+}
+
# make sure we have a standard umask
umask 022
;;
ceph)
;;
+ glusterfs)
+ ;;
overlay)
;;
reiser4)
;;
esac
+if [ ! -z "$REPORT_LIST" ]; then
+ . ./common/report
+ _assert_report_list
+fi
+
_mount()
{
$MOUNT_PROG `_mount_ops_filter $*`
}
+# Call _mount to do mount operation but also save mountpoint to
+# MOUNTED_POINT_STACK. Note that the mount point must be the last parameter
+_get_mount()
+{
+ local mnt_point=${!#}
+
+ _mount $*
+ if [ $? -eq 0 ]; then
+ MOUNTED_POINT_STACK="$mnt_point $MOUNTED_POINT_STACK"
+ else
+ return 1
+ fi
+}
+
+# Unmount the last mounted mountpoint in MOUNTED_POINT_STACK
+# and return it to caller
+_put_mount()
+{
+ local last_mnt=`echo $MOUNTED_POINT_STACK | awk '{print $1}'`
+
+ if [ -n "$last_mnt" ]; then
+ $UMOUNT_PROG $last_mnt
+ fi
+ MOUNTED_POINT_STACK=`echo $MOUNTED_POINT_STACK | cut -d\ -f2-`
+}
+
+# Unmount all mountpoints in MOUNTED_POINT_STACK and clear the stack
+_clear_mount_stack()
+{
+ if [ -n "$MOUNTED_POINT_STACK" ]; then
+ $UMOUNT_PROG $MOUNTED_POINT_STACK
+ fi
+ MOUNTED_POINT_STACK=""
+}
+
_scratch_options()
{
type=$1
_overlay_basic_mount_options()
{
- echo "-o lowerdir=$1/$OVERLAY_LOWER_DIR,upperdir=$1/$OVERLAY_UPPER_DIR,workdir=$1/$OVERLAY_WORK_DIR"
+ echo "-o lowerdir=$1/$OVL_LOWER,upperdir=$1/$OVL_UPPER,workdir=$1/$OVL_WORK"
}
_overlay_mount_options()
_scratch_options mount
if [ "$FSTYP" == "overlay" ]; then
- echo `_overlay_mount_options $SCRATCH_DEV`
+ echo `_overlay_mount_options $OVL_BASE_SCRATCH_MNT`
return 0
fi
echo `_common_dev_mount_options $*` $SCRATCH_OPTIONS \
-o workdir=$workdir $*
}
-# Given a dir, set up 3 subdirectories and mount on the given 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()
{
_supports_filetype $dir || _notrun "upper fs needs to support d_type"
- mkdir -p $dir/$OVERLAY_UPPER_DIR
- mkdir -p $dir/$OVERLAY_LOWER_DIR
- mkdir -p $dir/$OVERLAY_WORK_DIR
+ _overlay_mkdirs $dir
- _overlay_mount_dirs $dir/$OVERLAY_LOWER_DIR $dir/$OVERLAY_UPPER_DIR \
- $dir/$OVERLAY_WORK_DIR $OVERLAY_MOUNT_OPTIONS \
+ _overlay_mount_dirs $dir/$OVL_LOWER $dir/$OVL_UPPER \
+ $dir/$OVL_WORK $OVERLAY_MOUNT_OPTIONS \
$SELINUX_MOUNT_OPTIONS $* $dir $mnt
}
+_overlay_base_test_mount()
+{
+ if [ -z "$OVL_BASE_TEST_DEV" -o -z "$OVL_BASE_TEST_DIR" ] || \
+ _check_mounted_on OVL_BASE_TEST_DEV $OVL_BASE_TEST_DEV \
+ OVL_BASE_TEST_DIR $OVL_BASE_TEST_DIR
+ 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 $TEST_FS_MOUNT_OPTS \
+ $SELINUX_MOUNT_OPTIONS \
+ $OVL_BASE_TEST_DEV $OVL_BASE_TEST_DIR
+}
+
_overlay_test_mount()
{
- _overlay_mount $TEST_DEV $TEST_DIR $*
+ _overlay_base_test_mount && \
+ _overlay_mount $OVL_BASE_TEST_DIR $TEST_DIR $*
+}
+
+_overlay_base_scratch_mount()
+{
+ if [ -z "$OVL_BASE_SCRATCH_DEV" -o -z "$OVL_BASE_SCRATCH_MNT" ] || \
+ _check_mounted_on OVL_BASE_SCRATCH_DEV $OVL_BASE_SCRATCH_DEV \
+ OVL_BASE_SCRATCH_MNT $OVL_BASE_SCRATCH_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 $OVL_BASE_MOUNT_OPTIONS \
+ $SELINUX_MOUNT_OPTIONS \
+ $OVL_BASE_SCRATCH_DEV $OVL_BASE_SCRATCH_MNT
+}
+
+_overlay_base_scratch_unmount()
+{
+ [ -n "$OVL_BASE_SCRATCH_DEV" -a -n "$OVL_BASE_SCRATCH_MNT" ] || return 0
+
+ $UMOUNT_PROG $OVL_BASE_SCRATCH_MNT
}
_overlay_scratch_mount()
{
- _overlay_mount $SCRATCH_DEV $SCRATCH_MNT $*
+ _overlay_base_scratch_mount && \
+ _overlay_mount $OVL_BASE_SCRATCH_MNT $SCRATCH_MNT $*
+}
+
+_overlay_base_test_unmount()
+{
+ [ -n "$OVL_BASE_TEST_DEV" -a -n "$OVL_BASE_TEST_DIR" ] || return 0
+
+ $UMOUNT_PROG $OVL_BASE_TEST_DIR
}
_overlay_test_unmount()
{
$UMOUNT_PROG $TEST_DIR
+ _overlay_base_test_unmount
}
_overlay_scratch_unmount()
{
$UMOUNT_PROG $SCRATCH_MNT
+ _overlay_base_scratch_unmount
}
_scratch_mount()
ceph)
# do nothing for ceph
;;
+ glusterfs)
+ # do nothing for glusterfs
+ ;;
overlay)
# do nothing for overlay
;;
{
case $FSTYP in
overlay)
- # $SCRATCH_DEV is a valid directory in overlay case
- rm -rf $SCRATCH_DEV/*
+ # Avoid rm -rf /* if we messed up
+ [ -n "$OVL_BASE_SCRATCH_MNT" ] || return 1
+ _overlay_base_scratch_mount || return 1
+ rm -rf $OVL_BASE_SCRATCH_MNT/* || return 1
+ _overlay_mkdirs $OVL_BASE_SCRATCH_MNT
+ # leave base fs mouted so tests can setup lower/upper dir files
;;
*)
+ [ -n "$SCRATCH_MNT" ] || return 1
_scratch_mount
rm -rf $SCRATCH_MNT/*
_scratch_unmount
local mkfs_status
case $FSTYP in
- nfs*|cifs|ceph|overlay)
+ nfs*|cifs|ceph|overlay|glusterfs)
# unable to re-create this fstyp, just remove all files in
# $SCRATCH_MNT to avoid EEXIST caused by the leftover files
# created in previous runs
_scratch_cleanup_files
- return 0
+ return $?
;;
tmpfs)
# do nothing for tmpfs
_scratch_xfs_repair "$@" 2>&1
res=$?
fi
- test $res -ne 0 && >&2 echo "xfs_repair failed, err=$res"
+ if [ $res -ne 0 ]; then
+ _dump_err2 "xfs_repair failed, err=$res"
+ fi
return $res
;;
*)
res=0
;;
*)
- >&2 echo "fsck.$FSTYP failed, err=$res"
+ _dump_err2 "fsck.$FSTYP failed, err=$res"
;;
esac
return $res
# Fix the filesystem type up here so that the callers don't
# have to bother with this quirk.
#
- _df_device $1 | $AWK_PROG '{ print $2 }' | sed -e 's/nfs4/nfs/'
+ _df_device $1 | $AWK_PROG '{ print $2 }' | \
+ sed -e 's/nfs4/nfs/' -e 's/fuse.glusterfs/glusterfs/'
}
# return the FS mount options of a mounted device
_notrun "not suitable for this OS: $HOSTOS"
}
+# check if a FS on a device is mounted
+# if so, verify that it is mounted on mount point
+# if fstype is given as argument, verify that it is also
+# mounted with correct fs type
+#
+_check_mounted_on()
+{
+ local devname=$1
+ local dev=$2
+ local mntname=$3
+ local mnt=$4
+ local type=$5
+
+ # find $dev as the source, and print result in "$dev $mnt" format
+ local mount_rec=`findmnt -rncv -S $dev -o SOURCE,TARGET`
+ [ -n "$mount_rec" ] || return 1 # 1 = not mounted
+
+ # if it's mounted, make sure its on $mnt
+ if [ "$mount_rec" != "$dev $mnt" ]; then
+ echo "$devname=$dev is mounted but not on $mntname=$mnt - aborting"
+ echo "Already mounted result:"
+ echo $mount_rec
+ return 2 # 2 = mounted on wrong mnt
+ fi
+
+ if [ -n "$type" -a "`_fs_type $dev`" != "$type" ]; then
+ echo "$devname=$dev is mounted but not a type $type filesystem"
+ # raw $DF_PROG cannot handle NFS/CIFS/overlay correctly
+ _df_device $dev
+ return 3 # 3 = mounted as wrong type
+ fi
+ return 0 # 0 = mounted as expected
+}
+
# this test needs a scratch partition - check we're ok & unmount it
# No post-test check of the device is required. e.g. the test intentionally
# finishes the test with the filesystem in a corrupt state
_require_scratch_nocheck()
{
case "$FSTYP" in
+ glusterfs)
+ echo $SCRATCH_DEV | egrep -q ":/?" > /dev/null 2>&1
+ if [ -z "$SCRATCH_DEV" -o "$?" != "0" ]; then
+ _notrun "this test requires a valid \$SCRATCH_DEV"
+ fi
+ if [ ! -d "$SCRATCH_MNT" ]; then
+ _notrun "this test requires a valid \$SCRATCH_MNT"
+ fi
+ ;;
nfs*|ceph)
echo $SCRATCH_DEV | grep -q ":/" > /dev/null 2>&1
if [ -z "$SCRATCH_DEV" -o "$?" != "0" ]; then
fi
;;
overlay)
- if [ -z "$SCRATCH_DEV" -o ! -d "$SCRATCH_DEV" ]; then
- _notrun "this test requires a valid \$SCRATCH_DEV as ovl base dir"
+ if [ -z "$OVL_BASE_SCRATCH_MNT" -o ! -d "$OVL_BASE_SCRATCH_MNT" ]; then
+ _notrun "this test requires a valid \$OVL_BASE_SCRATCH_MNT as ovl base dir"
fi
- if [ ! -d "$SCRATCH_MNT" ]; then
+ # if $SCRATCH_MNT is derived from $OVL_BASE_SCRATCH_MNT then
+ # don't check $SCRATCH_MNT dir here because base fs may not be mounted
+ # and we will create the mount point anyway on _overlay_mount
+ if [ "$SCRATCH_MNT" != "$OVL_BASE_SCRATCH_MNT/$OVL_MNT" -a ! -d "$SCRATCH_MNT" ]; then
_notrun "this test requires a valid \$SCRATCH_MNT"
fi
;;
;;
esac
- # mounted?
- # Note that we use -F here so grep doesn't try to interpret an NFS over
- # IPv6 server as a regular expression.
- mount_rec=`_mount | grep -F $SCRATCH_DEV`
- if [ "$mount_rec" ]
+ _check_mounted_on SCRATCH_DEV $SCRATCH_DEV SCRATCH_MNT $SCRATCH_MNT
+ local err=$?
+ [ $err -le 1 ] || exit 1
+ if [ $err -eq 0 ]
then
- # if it's mounted, make sure its on $SCRATCH_MNT
- if ! echo $mount_rec | grep -q $SCRATCH_MNT
- then
- echo "\$SCRATCH_DEV=$SCRATCH_DEV is mounted but not on \$SCRATCH_MNT=$SCRATCH_MNT - aborting"
- echo "Already mounted result:"
- echo $mount_rec
- exit 1
- fi
- # and then unmount it
+ # if it's mounted, unmount it
if ! _scratch_unmount
then
echo "failed to unmount $SCRATCH_DEV"
_require_test()
{
case "$FSTYP" in
+ glusterfs)
+ echo $TEST_DEV | egrep -q ":/?" > /dev/null 2>&1
+ if [ -z "$TEST_DEV" -o "$?" != "0" ]; then
+ _notrun "this test requires a valid \$TEST_DEV"
+ fi
+ if [ ! -d "$TEST_DIR" ]; then
+ _notrun "this test requires a valid \$TEST_DIR"
+ fi
+ ;;
nfs*|ceph)
echo $TEST_DEV | grep -q ":/" > /dev/null 2>&1
if [ -z "$TEST_DEV" -o "$?" != "0" ]; then
fi
;;
overlay)
- if [ -z "$TEST_DEV" -o ! -d "$TEST_DEV" ]; then
- _notrun "this test requires a valid \$TEST_DEV as ovl base dir"
+ if [ -z "$OVL_BASE_TEST_DIR" -o ! -d "$OVL_BASE_TEST_DIR" ]; then
+ _notrun "this test requires a valid \$TEST_DIR as ovl base dir"
fi
if [ ! -d "$TEST_DIR" ]; then
_notrun "this test requires a valid \$TEST_DIR"
;;
esac
- # mounted?
- # Note that we use -F here so grep doesn't try to interpret an NFS over
- # IPv6 server as a regular expression.
- mount_rec=`_mount | grep -F $TEST_DEV`
- if [ "$mount_rec" ]
+ _check_mounted_on TEST_DEV $TEST_DEV TEST_DIR $TEST_DIR
+ local err=$?
+ [ $err -le 1 ] || exit 1
+ if [ $err -ne 0 ]
then
- # if it's mounted, make sure its on $TEST_DIR
- if ! echo $mount_rec | grep -q $TEST_DIR
- then
- echo "\$TEST_DEV=$TEST_DEV is mounted but not on \$TEST_DIR=$TEST_DIR - aborting"
- echo "Already mounted result:"
- echo $mount_rec
- exit 1
- fi
- else
- out=`_mount_or_remount_rw "$MOUNT_OPTIONS" $TEST_DEV $TEST_DIR`
- if [ $? -ne 1 ]; then
- echo $out
+ if ! _test_mount
+ then
+ echo "!!! failed to mount $TEST_DEV on $TEST_DIR"
exit 1
fi
fi
fi
}
+# this test requires tmpfs filesystem support
+#
+_require_tmpfs()
+{
+ modprobe tmpfs >/dev/null 2>&1
+ grep -q tmpfs /proc/filesystems ||
+ _notrun "this test requires tmpfs support"
+}
+
# this test requires that (large) loopback device files are not in use
#
_require_no_large_scratch_dev()
_scratch_unmount
}
-# this test requires the bigalloc feature to be available in mkfs.ext4
-#
-_require_ext4_mkfs_bigalloc()
+# Check the specified feature whether it is available in mkfs.ext4 or not.
+_require_ext4_mkfs_feature()
{
- $MKFS_EXT4_PROG -F -O bigalloc -n $SCRATCH_DEV 512m >/dev/null 2>&1 \
- || _notrun "mkfs.ext4 doesn't have bigalloc feature"
+ local feature=$1
+ local testfile=/tmp/$$.ext4_mkfs
+
+ if [ -z "$feature" ]; then
+ echo "Usage: _require_ext4_mkfs_feature feature"
+ exit 1
+ fi
+
+ touch $testfile
+ local result=$($MKFS_EXT4_PROG -F -O $feature -n $testfile 512m 2>&1)
+ rm -f $testfile
+ echo $result | grep -q "Invalid filesystem option" && \
+ _notrun "mkfs.ext4 doesn't support $feature feature"
}
# this test requires the ext4 kernel support bigalloc feature
{
local dn
dn=$(domainname 2>/dev/null)
- test -n "${dn}" -a "${dn}" != "(none)"
+ test -n "${dn}" -a "${dn}" != "(none)" -a "${dn}" != "localdomain"
echo $?
}
_overlay_mount $device $mountpoint
fi
if [ $? -ne 0 ]; then
- echo "!!! failed to remount $device on $mountpoint"
+ _dump_err "!!! failed to remount $device on $mountpoint"
return 0 # ok=0
fi
else
fsck -t $FSTYP $FSCK_OPTIONS $device >$tmp.fsck 2>&1
if [ $? -ne 0 ]
then
- echo "_check_generic_filesystem: filesystem on $device is inconsistent (see $seqres.full)"
-
- echo "_check_generic filesystem: filesystem on $device is inconsistent" >>$seqres.full
+ _log_err "_check_generic_filesystem: filesystem on $device is inconsistent"
echo "*** fsck.$FSTYP output ***" >>$seqres.full
cat $tmp.fsck >>$seqres.full
echo "*** end fsck.$FSTYP output" >>$seqres.full
ceph)
# no way to check consistency for CephFS
;;
+ glusterfs)
+ # no way to check consistency for GlusterFS
+ ;;
overlay)
# no way to check consistency for overlay
;;
ceph)
# no way to check consistency for CephFS
;;
+ glusterfs)
+ # no way to check consistency for GlusterFS
+ ;;
overlay)
# no way to check consistency for overlay
;;
# convert urandom incompressible data to compressible text data
_ddt()
{
- cat /dev/urandom | od | dd iflag=fullblock ${*}
+ od /dev/urandom | dd iflag=fullblock ${*}
}
#takes files, randomdata
_scratch_unmount
}
+# Does dax mount option work on this dev/fs?
+_require_scratch_dax()
+{
+ _require_scratch
+ _scratch_mkfs > /dev/null 2>&1
+ _scratch_mount -o dax
+ # Check options to be sure. XFS ignores dax option
+ # and goes on if dev underneath does not support dax.
+ _fs_options $SCRATCH_DEV | grep -qw "dax" || \
+ _notrun "$SCRATCH_DEV $FSTYP does not support -o dax"
+ _scratch_unmount
+}
+
# Does norecovery support by this fs?
_require_norecovery()
{
_require_chattr()
{
- attribute=$1
-
- touch $TEST_DIR/syscalltest
- chattr "+$attribute" $TEST_DIR/syscalltest > $TEST_DIR/syscalltest.out 2>&1
- status=$?
- chattr "-$attribute" $TEST_DIR/syscalltest > $TEST_DIR/syscalltest.out 2>&1
- if [ "$status" -ne 0 ]; then
- _notrun "file system doesn't support chattr +$attribute"
- fi
- cat $TEST_DIR/syscalltest.out >> $seqres.full
+ if [ -z "$1" ]; then
+ echo "Usage: _require_chattr <attr>"
+ exit 1
+ fi
+ local attribute=$1
- rm -f $TEST_DIR/syscalltest.out
+ touch $TEST_DIR/syscalltest
+ chattr "+$attribute" $TEST_DIR/syscalltest > $TEST_DIR/syscalltest.out 2>&1
+ status=$?
+ chattr "-$attribute" $TEST_DIR/syscalltest > $TEST_DIR/syscalltest.out 2>&1
+ if [ "$status" -ne 0 ]; then
+ _notrun "file system doesn't support chattr +$attribute"
+ fi
+ cat $TEST_DIR/syscalltest.out >> $seqres.full
+ rm -f $TEST_DIR/syscalltest.out
}
_get_total_inode()
-e "general protection fault:" \
$seqres.dmesg
if [ $? -eq 0 ]; then
- echo "_check_dmesg: something found in dmesg (see $seqres.dmesg)"
+ _dump_err "_check_dmesg: something found in dmesg (see $seqres.dmesg)"
return 1
else
rm -f $seqres.dmesg
fi
fi
- if [ "`_fs_type $TEST_DEV`" != "$FSTYP" ]
- then
- echo "common/rc: Error: \$TEST_DEV ($TEST_DEV) is not a MOUNTED $FSTYP filesystem"
- # raw $DF_PROG cannot handle NFS/CIFS/overlay correctly
- _df_device $TEST_DEV
- exit 1
+ # Sanity check that TEST partition is not mounted at another mount point
+ # or as another fs type
+ _check_mounted_on TEST_DEV $TEST_DEV TEST_DIR $TEST_DIR $FSTYP || exit 1
+ if [ -n "$SCRATCH_DEV" ]; then
+ # Sanity check that SCRATCH partition is not mounted at another
+ # mount point, because it is about to be unmounted and formatted.
+ # Another fs type for scratch is fine (bye bye old fs type).
+ _check_mounted_on SCRATCH_DEV $SCRATCH_DEV SCRATCH_MNT $SCRATCH_MNT
+ [ $? -le 1 ] || exit 1
fi
+
# Figure out if we need to add -F ("foreign", deprecated) option to xfs_io
$XFS_IO_PROG -c stat $TEST_DIR 2>&1 | grep -q "is not on an XFS filesystem" && \
export XFS_IO_PROG="$XFS_IO_PROG -F"
}
-
init_rc
################################################################################