. common/config
-BC=$(which bc 2> /dev/null) || BC=
+BC="$(type -P bc)" || BC=
_require_math()
{
# mount scratch device with given options and _fail if mount fails
_scratch_mount()
{
- _try_scratch_mount $* || _fail "mount failed"
+ _try_scratch_mount $* || _fail "mount $(_scratch_mount_options $*) failed"
}
_scratch_mount_idmapped()
$DUMP_COMPRESSOR -f "$dumpfile" &>> "$seqres.full"
}
+# Capture the metadata of a filesystem in a dump file for offline analysis.
+# This is not supported by all filesystem types, so this function should only
+# be used after a test has already failed.
+_metadump_dev() {
+ local device="$1"
+ local dumpfile="$2"
+ local compressopt="$3"
+
+ test "$DUMP_CORRUPT_FS" = 1 || return 0
+
+ case "$FSTYP" in
+ ext*)
+ _ext4_metadump $device $dumpfile $compressopt
+ ;;
+ xfs)
+ _xfs_metadump $dumpfile $device none $compressopt
+ ;;
+ *)
+ echo "Don't know how to metadump $FSTYP"
+ return 1
+ ;;
+ esac
+}
+
_test_mkfs()
{
case $FSTYP in
_fail "Usage: _scratch_dev_pool_get ndevs"
fi
- local test_ndevs=$1
- local config_ndevs=`echo $SCRATCH_DEV_POOL| wc -w`
- local -a devs="( $SCRATCH_DEV_POOL )"
-
- typeset -p config_ndevs >/dev/null 2>&1
+ typeset -p SCRATCH_DEV_POOL >/dev/null 2>&1
if [ $? -ne 0 ]; then
_fail "Bug: cant find SCRATCH_DEV_POOL ndevs"
fi
+ local test_ndevs=$1
+ local config_ndevs=`echo $SCRATCH_DEV_POOL| wc -w`
+ local -a devs="( $SCRATCH_DEV_POOL )"
+
if [ $config_ndevs -lt $test_ndevs ]; then
_notrun "Need at least test requested number of ndevs $test_ndevs"
fi
fi
}
+_check_minimal_fs_size()
+{
+ local fssize=$1
+
+ if [ -n "$MIN_FSSIZE" ]; then
+ [ $MIN_FSSIZE -gt "$fssize" ] &&
+ _notrun "specified filesystem size is too small"
+ fi
+}
+
# Create fs of certain size on scratch device
# _scratch_mkfs_sized <size in bytes> [optional blocksize]
_scratch_mkfs_sized()
xfs)
def_blksz=`echo $MKFS_OPTIONS | sed -rn 's/.*-b ?size= ?+([0-9]+).*/\1/p'`
;;
- ext2|ext3|ext4|ext4dev|udf|btrfs|reiser4|ocfs2|reiserfs)
+ btrfs)
+ def_blksz=`echo $MKFS_OPTIONS | sed -rn 's/.*-s ?+([0-9]+).*/\1/p'`
+ ;;
+ ext2|ext3|ext4|ext4dev|udf|reiser4|ocfs2|reiserfs)
def_blksz=`echo $MKFS_OPTIONS | sed -rn 's/.*-b ?+([0-9]+).*/\1/p'`
;;
jfs)
local blocks=`expr $fssize / $blocksize`
+ _check_minimal_fs_size $fssize
+
if [ -b "$SCRATCH_DEV" ]; then
local devsize=`blockdev --getsize64 $SCRATCH_DEV`
[ "$fssize" -gt "$devsize" ] && _notrun "Scratch device too small"
rm -f ${RESULT_DIR}/require_scratch
}
+# we need the scratch device and it needs to not be an lvm device
+_require_scratch_nolvm()
+{
+ _require_scratch_nocheck
+
+ # This works if we don't have LVM, all we want is to skip if the scratch
+ # device is an lvm device.
+ $LVM_PROG lvdisplay $SCRATCH_DEV > /dev/null 2>&1
+ [ $? -eq 0 ] && _notrun "test requires a non-lvm scratch device"
+}
+
# we need the scratch device and it should be checked post test.
_require_scratch()
{
else
_notrun "This test requires loopback device support"
fi
+
+ # loop device does not handle zone information
+ _require_non_zoned_device ${TEST_DEV}
}
# this test requires kernel support for a secondary filesystem
fi
}
+# Decide if the scratch filesystem is likely to be mounted in fsdax mode.
+# It goes 3 ways based on mount options::
+# 1. "dax" or "dax=always" means always test using DAX
+# 2. "dax=never" means we'll never use DAX
+# 3. "dax=inode" or nothing means "use scratch dev capability" to
+# determine whether DAX is going to be used.
+#
+# Returns 0 if DAX will be used, 1 if DAX is not going to be used.
+__scratch_uses_fsdax()
+{
+ local ops=$(_normalize_mount_options)
+
+ echo $ops | egrep -qw "dax(=always| |$)" && return 0
+ echo $ops | grep -qw "dax=never" && return 1
+
+ local sysfs="/sys/block/$(_short_dev $SCRATCH_DEV)"
+ test -e "${sysfs}/dax" && return 0
+ test "$(cat "${sysfs}/queue/dax" 2>/dev/null)" = "1" && return 0
+ return 1
+}
+
# this test requires a specific device mapper target
_require_dm_target()
{
local target=$1
+ local fsdax
+ local bdevdax
# require SCRATCH_DEV to be a valid block device with sane BLKFLSBUF
# behaviour
_require_sane_bdev_flush $SCRATCH_DEV
_require_command "$DMSETUP_PROG" dmsetup
- _normalize_mount_options | egrep -q "dax(=always| |$)" || \
- test -e "/sys/block/$(_short_dev $SCRATCH_DEV)/dax"
- if [ $? -eq 0 ]; then
+ if __scratch_uses_fsdax; then
case $target in
stripe|linear|log-writes)
;;
if [ $? -ne 0 ]; then
_notrun "This test requires dm $target support"
fi
+
+ # dm-error cannot handle the zone information
+ #
+ # dm-snapshot and dm-thin-pool cannot ensure sequential writes on
+ # the backing device
+ case $target in
+ error|snapshot|thin-pool)
+ _require_non_zoned_device ${SCRATCH_DEV}
+ ;;
+ esac
}
_zone_type()
cat /etc/group
}
-# check for a user on the machine, fsgqa as default
+# check if a user exists in the system
+#
+_require_user_exists()
+{
+ local user=$1
+ _cat_passwd | grep -q "^$user:"
+ [ "$?" == "0" ] || _notrun "$user user not defined."
+}
+
+# check if a user exists and is able to execute commands.
+# Uses 'fsgqa' user as default.
#
_require_user()
{
- qa_user=fsgqa
- if [ -n "$1" ];then
- qa_user=$1
- fi
- _cat_passwd | grep -q $qa_user
- [ "$?" == "0" ] || _notrun "$qa_user user not defined."
- echo /bin/true | su $qa_user
- [ "$?" == "0" ] || _notrun "$qa_user cannot execute commands."
+ qa_user=fsgqa
+ if [ -n "$1" ];then
+ qa_user=$1
+ fi
+ _require_user_exists $qa_user
+ echo /bin/true | su $qa_user
+ [ "$?" == "0" ] || _notrun "$qa_user cannot execute commands."
}
# check for a chown support
rm -f $testfile 2>&1 > /dev/null
}
+# Format a swapfile and return its size in bytes
_format_swapfile() {
local fname="$1"
local sz="$2"
+ local swap_log=""
rm -f "$fname"
touch "$fname"
$CHATTR_PROG +C "$fname" > /dev/null 2>&1
_pwrite_byte 0x61 0 "$sz" "$fname" >> $seqres.full
# Ignore permission complaints on filesystems that don't support perms
- $MKSWAP_PROG "$fname" 2> >(grep -v 'insecure permission' >&2) >> $seqres.full
+ swap_log=$($MKSWAP_PROG "$fname" 2>&1 | grep -v "insecure permission")
+ echo $swap_log >> $seqres.full
+
+ echo $swap_log | grep -oP '\w+(?= bytes)'
}
_swapon_file() {
local fname="$1"
# Ignore permission complaints on filesystems that don't support perms
- swapon "$fname" 2> >(grep -v "insecure permissions" >&2)
+ $(swapon "$fname" 2> >(grep -v "insecure permissions" >&2))
}
# Check that the filesystem supports swapfiles
_scratch_mount
# Minimum size for mkswap is 10 pages
- _format_swapfile "$SCRATCH_MNT/swap" $(($(get_page_size) * 10))
+ _format_swapfile "$SCRATCH_MNT/swap" $(($(get_page_size) * 10)) > /dev/null
# ext* has supported all variants of swap files since their
# introduction, so swapon should not fail.
return 0
;;
nfs*)
- # NFSv2 and NFSv3 only support default behavior of SEEK_HOLE,
- # while NFSv4 supports non-default behavior
- local nfsvers=`_df_device $TEST_DEV | $AWK_PROG '{ print $2 }'`
- [ "$nfsvers" = "nfs4" ]
+ # NFSv2, NFSv3, and NFSv4.0/4.1 only support default behavior of SEEK_HOLE,
+ # while NFSv4.2 supports non-default behavior
+ local nfsvers=`_mount() | grep $TEST_DEV | sed -n 's/^.*vers=\([0-9.]*\).*$/\1/p'`
+ [ "$nfsvers" = "4.2" ]
return $?
;;
overlay)
{
local file=$1 dev
dev=`losetup -f --show $file` || _fail "Cannot assign $file to a loop device"
+
+ # Try to enable asynchronous directio mode on the loopback device so
+ # that writeback started by a filesystem mounted on the loop device
+ # won't be throttled by buffered writes to the lower filesystem. This
+ # is a performance optimization for tests that want to write a lot of
+ # data, so it isn't required to work.
+ test -b "$dev" && losetup --direct-io=on $dev 2> /dev/null
+
echo $dev
}
_notrun "od does not support endian flag"
}
+# Skip this test unless the filesystem treats names (directory entries,
+# fs labels, and extended attribute names) as raw byte sequences.
+_require_names_are_bytes() {
+ case "$FSTYP" in
+ ext2|ext3|ext4|f2fs|xfs|btrfs)
+ # do nothing
+ ;;
+ *)
+ _notrun "$FSTYP does not allow unrestricted byte streams for names"
+ ;;
+ esac
+}
+
+_has_kernel_config()
+{
+ local option=$1
+ local uname=$(uname -r)
+ local config_list="$KCONFIG_PATH
+ /proc/config.gz
+ /lib/modules/$uname/build/.config
+ /boot/config-$uname
+ /lib/kernel/config-$uname"
+
+ for config in $config_list; do
+ [ ! -f $config ] && continue
+ [ $config = "/proc/config.gz" ] && break
+ grep -qE "^${option}=[my]" $config
+ return
+ done
+
+ [ ! -f $config ] && _notrun "Could not locate kernel config file"
+
+ # We can only get here with /proc/config.gz
+ _require_command "$GZIP_PROG" gzip
+ $GZIP_PROG -cd $config | grep -qE "^${option}=[my]"
+}
+
+_require_kernel_config()
+{
+ _has_kernel_config $1 || _notrun "Installed kernel not built with $1"
+}
+
init_rc
################################################################################