Message ID | 20161129213233.8462-2-david@fromorbit.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Wed, Nov 30, 2016 at 08:32:32AM +1100, Dave Chinner wrote: > From: Dave Chinner <dchinner@redhat.com> > > common/rc has become a dumping ground for common functions that > don't have a specific topic file. It's getting huge and difficiult > to manage, and people are duplicating functionality because they > can't easily find existing functions in the mess. > > Let's start to make it a little easier to manage by splitting out > the XFS specific functions into common/xfs and source that from > common/rc automatically. Other filesytems can follow suit in > future, leaving us with only generic functionality in common/rc. > > Signed-Off-By: Dave Chinner <dchinner@redhat.com> Ye $deities, finally! common/rc is an unholy dumping ground. :) For the XFS parts only, Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> --D > --- > common/rc | 623 +------------------------------------------------------------ > common/xfs | 618 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 624 insertions(+), 617 deletions(-) > create mode 100644 common/xfs > > diff --git a/common/rc b/common/rc > index 8c993066597c..00b53643f248 100644 > --- a/common/rc > +++ b/common/rc > @@ -123,6 +123,9 @@ then > fi > fi > > +# make sure we have a standard umask > +umask 022 > + > # check for correct setup > case "$FSTYP" in > xfs) > @@ -130,6 +133,9 @@ case "$FSTYP" in > [ "$XFS_REPAIR_PROG" = "" ] && _fatal "xfs_repair not found" > [ "$XFS_DB_PROG" = "" ] && _fatal "xfs_db not found" > [ "$MKFS_XFS_PROG" = "" ] && _fatal "mkfs_xfs not found" > + > + #source the XFS specific functions now. > + . ./common/xfs > ;; > udf) > [ "$MKFS_UDF_PROG" = "" ] && _fatal "mkfs_udf/mkudffs not found" > @@ -156,9 +162,6 @@ case "$FSTYP" in > ;; > esac > > -# make sure we have a standard umask > -umask 022 > - > _mount() > { > $MOUNT_PROG `_mount_ops_filter $*` > @@ -425,171 +428,6 @@ _scratch_metadump() > xfs_metadump $options $SCRATCH_DEV $dumpfile > } > > -_setup_large_xfs_fs() > -{ > - fs_size=$1 > - local tmp_dir=/tmp/ > - > - [ "$LARGE_SCRATCH_DEV" != yes ] && return 0 > - [ -z "$SCRATCH_DEV_EMPTY_SPACE" ] && SCRATCH_DEV_EMPTY_SPACE=0 > - [ $SCRATCH_DEV_EMPTY_SPACE -ge $fs_size ] && return 0 > - > - # calculate the size of the file we need to allocate. > - # Default free space in the FS is 50GB, but you can specify more via > - # SCRATCH_DEV_EMPTY_SPACE > - file_size=$(($fs_size - 50*1024*1024*1024)) > - file_size=$(($file_size - $SCRATCH_DEV_EMPTY_SPACE)) > - > - # mount the filesystem, create the file, unmount it > - _scratch_mount 2>&1 >$tmp_dir/mnt.err > - local status=$? > - if [ $status -ne 0 ]; then > - echo "mount failed" > - cat $tmp_dir/mnt.err >&2 > - rm -f $tmp_dir/mnt.err > - return $status > - fi > - rm -f $tmp_dir/mnt.err > - > - xfs_io -F -f \ > - -c "truncate $file_size" \ > - -c "falloc -k 0 $file_size" \ > - -c "chattr +d" \ > - $SCRATCH_MNT/.use_space 2>&1 > /dev/null > - export NUM_SPACE_FILES=1 > - status=$? > - _scratch_unmount > - if [ $status -ne 0 ]; then > - echo "large file prealloc failed" > - cat $tmp_dir/mnt.err >&2 > - return $status > - fi > - return 0 > -} > - > -_scratch_mkfs_xfs_opts() > -{ > - mkfs_opts=$* > - > - # remove metadata related mkfs options if mkfs.xfs doesn't them > - if [ -n "$XFS_MKFS_HAS_NO_META_SUPPORT" ]; then > - mkfs_opts=`echo $mkfs_opts | sed "s/-m\s\+\S\+//g"` > - fi > - > - _scratch_options mkfs > - > - $MKFS_XFS_PROG $SCRATCH_OPTIONS $mkfs_opts $SCRATCH_DEV > -} > - > - > -_scratch_mkfs_xfs_supported() > -{ > - local mkfs_opts=$* > - > - _scratch_options mkfs > - > - $MKFS_XFS_PROG -N $MKFS_OPTIONS $SCRATCH_OPTIONS $mkfs_opts $SCRATCH_DEV > - local mkfs_status=$? > - > - # a mkfs failure may be caused by conflicts between $MKFS_OPTIONS and > - # $mkfs_opts, try again without $MKFS_OPTIONS > - if [ $mkfs_status -ne 0 -a -n "$mkfs_opts" ]; then > - $MKFS_XFS_PROG -N $SCRATCH_OPTIONS $mkfs_opts $SCRATCH_DEV > - mkfs_status=$? > - fi > - return $mkfs_status > -} > - > -_scratch_mkfs_xfs() > -{ > - # extra mkfs options can be added by tests > - local extra_mkfs_options=$* > - > - local tmp_dir=/tmp/ > - > - # save mkfs output in case conflict means we need to run again. > - # only the output for the mkfs that applies should be shown > - _scratch_mkfs_xfs_opts $MKFS_OPTIONS $extra_mkfs_options \ > - 2>$tmp_dir.mkfserr 1>$tmp_dir.mkfsstd > - local mkfs_status=$? > - > - > - # a mkfs failure may be caused by conflicts between > - # $MKFS_OPTIONS and $extra_mkfs_options > - if [ $mkfs_status -ne 0 -a ! -z "$extra_mkfs_options" ]; then > - ( > - echo -n "** mkfs failed with extra mkfs options " > - echo "added to \"$MKFS_OPTIONS\" by test $seq **" > - echo -n "** attempting to mkfs using only test $seq " > - echo "options: $extra_mkfs_options **" > - ) >> $seqres.full > - > - # running mkfs again. overwrite previous mkfs output files > - _scratch_mkfs_xfs_opts $extra_mkfs_options \ > - 2>$tmp_dir.mkfserr 1>$tmp_dir.mkfsstd > - local mkfs_status=$? > - fi > - > - if [ $mkfs_status -eq 0 -a "$LARGE_SCRATCH_DEV" = yes ]; then > - # manually parse the mkfs output to get the fs size in bytes > - local fs_size > - fs_size=`cat $tmp_dir.mkfsstd | perl -ne ' > - if (/^data\s+=\s+bsize=(\d+)\s+blocks=(\d+)/) { > - my $size = $1 * $2; > - print STDOUT "$size\n"; > - }'` > - _setup_large_xfs_fs $fs_size > - mkfs_status=$? > - fi > - > - # output stored mkfs output, filtering unnecessary warnings from stderr > - cat $tmp_dir.mkfsstd > - cat $tmp_dir.mkfserr | sed \ > - -e '/less than device physical sector/d' \ > - -e '/switching to logical sector/d' \ > - >&2 > - rm -f $tmp_dir.mkfserr $tmp_dir.mkfsstd > - > - return $mkfs_status > -} > - > -# xfs_check script is planned to be deprecated. But, we want to > -# be able to invoke "xfs_check" behavior in xfstests in order to > -# maintain the current verification levels. > -_xfs_check() > -{ > - OPTS=" " > - DBOPTS=" " > - USAGE="Usage: xfs_check [-fsvV] [-l logdev] [-i ino]... [-b bno]... special" > - > - while getopts "b:fi:l:stvV" c > - do > - case $c in > - s) OPTS=$OPTS"-s ";; > - t) OPTS=$OPTS"-t ";; > - v) OPTS=$OPTS"-v ";; > - i) OPTS=$OPTS"-i "$OPTARG" ";; > - b) OPTS=$OPTS"-b "$OPTARG" ";; > - f) DBOPTS=$DBOPTS" -f";; > - l) DBOPTS=$DBOPTS" -l "$OPTARG" ";; > - V) $XFS_DB_PROG -p xfs_check -V > - return $? > - ;; > - esac > - done > - set -- extra $@ > - shift $OPTIND > - case $# in > - 1) ${XFS_DB_PROG}${DBOPTS} -F -i -p xfs_check -c "check$OPTS" $1 > - status=$? > - ;; > - 2) echo $USAGE 1>&1 > - status=2 > - ;; > - esac > - return $status > -} > - > _setup_large_ext4_fs() > { > fs_size=$1 > @@ -1113,55 +951,6 @@ _scratch_resvblks() > esac > } > > -_scratch_xfs_db_options() > -{ > - SCRATCH_OPTIONS="" > - [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \ > - SCRATCH_OPTIONS="-l$SCRATCH_LOGDEV" > - echo $SCRATCH_OPTIONS $* $SCRATCH_DEV > -} > - > -_scratch_xfs_db() > -{ > - $XFS_DB_PROG "$@" $(_scratch_xfs_db_options) > -} > - > -_scratch_xfs_logprint() > -{ > - SCRATCH_OPTIONS="" > - [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \ > - SCRATCH_OPTIONS="-l$SCRATCH_LOGDEV" > - $XFS_LOGPRINT_PROG $SCRATCH_OPTIONS $* $SCRATCH_DEV > -} > - > -_test_xfs_logprint() > -{ > - TEST_OPTIONS="" > - [ "$USE_EXTERNAL" = yes -a ! -z "$TEST_LOGDEV" ] && \ > - TEST_OPTIONS="-l$TEST_LOGDEV" > - $XFS_LOGPRINT_PROG $TEST_OPTIONS $* $TEST_DEV > -} > - > -_scratch_xfs_check() > -{ > - SCRATCH_OPTIONS="" > - [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \ > - SCRATCH_OPTIONS="-l $SCRATCH_LOGDEV" > - [ "$LARGE_SCRATCH_DEV" = yes ] && \ > - SCRATCH_OPTIONS=$SCRATCH_OPTIONS" -t" > - _xfs_check $SCRATCH_OPTIONS $* $SCRATCH_DEV > -} > - > -_scratch_xfs_repair() > -{ > - SCRATCH_OPTIONS="" > - [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \ > - SCRATCH_OPTIONS="-l$SCRATCH_LOGDEV" > - [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_RTDEV" ] && \ > - SCRATCH_OPTIONS=$SCRATCH_OPTIONS" -r$SCRATCH_RTDEV" > - [ "$LARGE_SCRATCH_DEV" = yes ] && SCRATCH_OPTIONS=$SCRATCH_OPTIONS" -t" > - $XFS_REPAIR_PROG $SCRATCH_OPTIONS $* $SCRATCH_DEV > -} > > # Repair scratch filesystem. Returns 0 if the FS is good to go (either no > # errors found or errors were fixed) and nonzero otherwise; also spits out > @@ -1794,38 +1583,6 @@ _require_dm_target() > fi > } > > -# this test requires the projid32bit feature to be available in mkfs.xfs. > -# > -_require_projid32bit() > -{ > - _scratch_mkfs_xfs_supported -i projid32bit=1 >/dev/null 2>&1 \ > - || _notrun "mkfs.xfs doesn't have projid32bit feature" > -} > - > -_require_projid16bit() > -{ > - _scratch_mkfs_xfs_supported -i projid32bit=0 >/dev/null 2>&1 \ > - || _notrun "16 bit project IDs not supported on $SCRATCH_DEV" > -} > - > -# this test requires the crc feature to be available in mkfs.xfs > -# > -_require_xfs_mkfs_crc() > -{ > - _scratch_mkfs_xfs_supported -m crc=1 >/dev/null 2>&1 \ > - || _notrun "mkfs.xfs doesn't have crc feature" > -} > - > -# this test requires the xfs kernel support crc feature > -# > -_require_xfs_crc() > -{ > - _scratch_mkfs_xfs -m crc=1 >/dev/null 2>&1 > - _scratch_mount >/dev/null 2>&1 \ > - || _notrun "Kernel doesn't support crc feature" > - _scratch_unmount > -} > - > # this test requires the ext4 kernel support crc feature on scratch device > # > _require_scratch_ext4_crc() > @@ -1837,17 +1594,6 @@ _require_scratch_ext4_crc() > _scratch_unmount > } > > -# this test requires the xfs kernel support crc feature on scratch device > -# > -_require_scratch_xfs_crc() > -{ > - _scratch_mkfs_xfs >/dev/null 2>&1 > - _scratch_mount >/dev/null 2>&1 \ > - || _notrun "Kernel doesn't support crc feature" > - xfs_info $SCRATCH_MNT | grep -q 'crc=1' || _notrun "crc feature not supported by this filesystem" > - _scratch_unmount > -} > - > # this test requires the bigalloc feature to be available in mkfs.ext4 > # > _require_ext4_mkfs_bigalloc() > @@ -1866,52 +1612,6 @@ _require_ext4_bigalloc() > _scratch_unmount > } > > -# this test requires the finobt feature to be available in mkfs.xfs > -# > -_require_xfs_mkfs_finobt() > -{ > - _scratch_mkfs_xfs_supported -m crc=1,finobt=1 >/dev/null 2>&1 \ > - || _notrun "mkfs.xfs doesn't have finobt feature" > -} > - > -# this test requires the xfs kernel support finobt feature > -# > -_require_xfs_finobt() > -{ > - _scratch_mkfs_xfs -m crc=1,finobt=1 >/dev/null 2>&1 > - _scratch_mount >/dev/null 2>&1 \ > - || _notrun "Kernel doesn't support finobt feature" > - _scratch_unmount > -} > - > -# this test requires xfs sysfs attribute support > -# > -_require_xfs_sysfs() > -{ > - attr=$1 > - sysfsdir=/sys/fs/xfs > - > - if [ ! -e $sysfsdir ]; then > - _notrun "no kernel support for XFS sysfs attributes" > - fi > - > - if [ ! -z $1 ] && [ ! -e $sysfsdir/$attr ]; then > - _notrun "sysfs attribute '$attr' is not supported" > - fi > -} > - > -# this test requires the xfs sparse inode feature > -# > -_require_xfs_sparse_inodes() > -{ > - _scratch_mkfs_xfs_supported -m crc=1 -i sparse > /dev/null 2>&1 \ > - || _notrun "mkfs.xfs does not support sparse inodes" > - _scratch_mkfs_xfs -m crc=1 -i sparse > /dev/null 2>&1 > - _scratch_mount >/dev/null 2>&1 \ > - || _notrun "kernel does not support sparse inodes" > - _scratch_unmount > -} > - > # this test requires that external log/realtime devices are not in use > # > _require_nonexternal() > @@ -2093,20 +1793,6 @@ _require_xfs_io_command() > _notrun "xfs_io $command doesn't support $param" > } > > -# check that xfs_db supports a specific command > -_require_xfs_db_command() > -{ > - if [ $# -ne 1 ] > - then > - echo "Usage: _require_xfs_db_command command" 1>&2 > - exit 1 > - fi > - command=$1 > - > - _scratch_xfs_db -x -c "help" | grep $command > /dev/null || \ > - _notrun "xfs_db $command support is missing" > -} > - > # check that kernel and filesystem support direct I/O > _require_odirect() > { > @@ -2403,150 +2089,6 @@ _check_generic_filesystem() > return 0 > } > > -# run xfs_check and friends on a FS. > - > -_check_xfs_filesystem() > -{ > - if [ $# -ne 3 ] > - then > - echo "Usage: _check_xfs_filesystem device <logdev>|none <rtdev>|none" 1>&2 > - exit 1 > - fi > - > - extra_mount_options="" > - extra_log_options="" > - extra_options="" > - device=$1 > - if [ -f $device ];then > - extra_options="-f" > - fi > - > - if [ "$2" != "none" ]; then > - extra_log_options="-l$2" > - extra_mount_options="-ologdev=$2" > - fi > - > - if [ "$3" != "none" ]; then > - extra_rt_options="-r$3" > - extra_mount_options=$extra_mount_options" -ortdev=$3" > - fi > - extra_mount_options=$extra_mount_options" $MOUNT_OPTIONS" > - > - [ "$FSTYP" != xfs ] && return 0 > - > - type=`_fs_type $device` > - ok=1 > - > - if [ "$type" = "xfs" ] > - then > - if [ -n "$TEST_XFS_SCRUB" ] && [ -x "$XFS_SCRUB_PROG" ]; then > - "$XFS_SCRUB_PROG" $scrubflag -vd $device >>$seqres.full > - if [ $? -ne 0 ]; then > - echo "filesystem on $device failed scrub (see $seqres.full)" > - ok=0 > - fi > - fi > - # mounted ... > - mountpoint=`_umount_or_remount_ro $device` > - fi > - > - $XFS_LOGPRINT_PROG -t $extra_log_options $device 2>&1 \ > - | tee $tmp.logprint | grep -q "<CLEAN>" > - if [ $? -ne 0 -a "$HOSTOS" = "Linux" ] > - then > - echo "_check_xfs_filesystem: filesystem on $device has dirty log (see $seqres.full)" > - > - echo "_check_xfs_filesystem: filesystem on $device has dirty log" >>$seqres.full > - echo "*** xfs_logprint -t output ***" >>$seqres.full > - cat $tmp.logprint >>$seqres.full > - echo "*** end xfs_logprint output" >>$seqres.full > - > - ok=0 > - fi > - > - # xfs_check runs out of memory on large files, so even providing the test > - # option (-t) to avoid indexing the free space trees doesn't make it pass on > - # large filesystems. Avoid it. > - if [ "$LARGE_SCRATCH_DEV" != yes ]; then > - _xfs_check $extra_log_options $device 2>&1 |\ > - _fix_malloc >$tmp.fs_check > - fi > - if [ -s $tmp.fs_check ] > - then > - echo "_check_xfs_filesystem: filesystem on $device is inconsistent (c) (see $seqres.full)" > - > - echo "_check_xfs_filesystem: filesystem on $device is inconsistent" >>$seqres.full > - echo "*** xfs_check output ***" >>$seqres.full > - cat $tmp.fs_check >>$seqres.full > - echo "*** end xfs_check output" >>$seqres.full > - > - ok=0 > - fi > - > - $XFS_REPAIR_PROG -n $extra_options $extra_log_options $extra_rt_options $device >$tmp.repair 2>&1 > - if [ $? -ne 0 ] > - then > - echo "_check_xfs_filesystem: filesystem on $device is inconsistent (r) (see $seqres.full)" > - > - echo "_check_xfs_filesystem: filesystem on $device is inconsistent" >>$seqres.full > - echo "*** xfs_repair -n output ***" >>$seqres.full > - cat $tmp.repair | _fix_malloc >>$seqres.full > - echo "*** end xfs_repair output" >>$seqres.full > - > - ok=0 > - fi > - rm -f $tmp.fs_check $tmp.logprint $tmp.repair > - > - # Optionally test the index rebuilding behavior. > - if [ -n "$TEST_XFS_REPAIR_REBUILD" ]; then > - $XFS_REPAIR_PROG $extra_options $extra_log_options $extra_rt_options $device >$tmp.repair 2>&1 > - if [ $? -ne 0 ]; then > - echo "_check_xfs_filesystem: filesystem on $device is inconsistent (rebuild) (see $seqres.full)" > - > - echo "_check_xfs_filesystem: filesystem on $device is inconsistent (rebuild)" >>$seqres.full > - echo "*** xfs_repair output ***" >>$seqres.full > - cat $tmp.repair | _fix_malloc >>$seqres.full > - echo "*** end xfs_repair output" >>$seqres.full > - > - ok=0 > - fi > - rm -f $tmp.repair > - > - $XFS_REPAIR_PROG -n $extra_options $extra_log_options $extra_rt_options $device >$tmp.repair 2>&1 > - if [ $? -ne 0 ]; then > - echo "_check_xfs_filesystem: filesystem on $device is inconsistent (rebuild-reverify) (see $seqres.full)" > - > - echo "_check_xfs_filesystem: filesystem on $device is inconsistent (rebuild-reverify)" >>$seqres.full > - echo "*** xfs_repair -n output ***" >>$seqres.full > - cat $tmp.repair | _fix_malloc >>$seqres.full > - echo "*** end xfs_repair output" >>$seqres.full > - > - ok=0 > - fi > - rm -f $tmp.repair > - fi > - > - if [ $ok -eq 0 ] > - then > - echo "*** mount output ***" >>$seqres.full > - _mount >>$seqres.full > - echo "*** end mount output" >>$seqres.full > - elif [ "$type" = "xfs" ] > - then > - _mount_or_remount_rw "$extra_mount_options" $device $mountpoint > - fi > - > - if [ $ok -eq 0 ]; then > - status=1 > - if [ "$iam" != "check" ]; then > - exit 1 > - fi > - return 1 > - fi > - > - return 0 > -} > - > # Filter the knowen errors the UDF Verifier reports. > _udf_test_known_error_filter() > { > @@ -2590,26 +2132,6 @@ _check_udf_filesystem() > return 0 > } > > -_check_xfs_test_fs() > -{ > - TEST_LOG="none" > - TEST_RT="none" > - [ "$USE_EXTERNAL" = yes -a ! -z "$TEST_LOGDEV" ] && \ > - TEST_LOG="$TEST_LOGDEV" > - > - [ "$USE_EXTERNAL" = yes -a ! -z "$TEST_RTDEV" ] && \ > - TEST_RT="$TEST_RTDEV" > - > - _check_xfs_filesystem $TEST_DEV $TEST_LOG $TEST_RT > - > - # check for ipath consistency > - if $XFS_GROWFS_PROG -n $TEST_DIR | grep -q 'inode-paths=1'; then > - # errors go to stderr > - xfs_check_ipaths $TEST_DIR >/dev/null > - xfs_repair_ipaths -n $TEST_DIR >/dev/null > - fi > -} > - > _check_btrfs_filesystem() > { > device=$1 > @@ -3382,24 +2904,6 @@ _require_test_fcntl_advisory_locks() > _notrun "Require fcntl advisory locks support" > } > > -# XFS ability to change UUIDs on V5/CRC filesystems > -# > -_require_meta_uuid() > -{ > - # This will create a crc fs on $SCRATCH_DEV > - _require_xfs_crc > - > - _scratch_xfs_db -x -c "uuid restore" 2>&1 \ > - | grep -q "invalid UUID\|supported on V5 fs" \ > - && _notrun "Userspace doesn't support meta_uuid feature" > - > - _scratch_xfs_db -x -c "uuid generate" >/dev/null 2>&1 > - > - _scratch_mount >/dev/null 2>&1 \ > - || _notrun "Kernel doesn't support meta_uuid feature" > - _scratch_unmount > -} > - > _require_btrfs_dev_del_by_devid() > { > $BTRFS_UTIL_PROG device delete --help | egrep devid > /dev/null 2>&1 > @@ -3416,47 +2920,6 @@ _require_test_lsattr() > _notrun "lsattr not supported by test filesystem type: $FSTYP" > } > > -_require_xfs_test_rmapbt() > -{ > - _require_test > - > - if [ "$(xfs_info "$TEST_DIR" | grep -c "rmapbt=1")" -ne 1 ]; then > - _notrun "rmapbt not supported by test filesystem type: $FSTYP" > - fi > -} > - > -_require_xfs_scratch_rmapbt() > -{ > - _require_scratch > - > - _scratch_mkfs > /dev/null > - _scratch_mount > - if [ "$(xfs_info "$SCRATCH_MNT" | grep -c "rmapbt=1")" -ne 1 ]; then > - _scratch_unmount > - _notrun "rmapbt not supported by scratch filesystem type: $FSTYP" > - fi > - _scratch_unmount > -} > - > -_xfs_bmapx_find() { > - case "$1" in > - "attr") > - param="a" > - ;; > - "cow") > - param="c" > - ;; > - *) > - param="e" > - ;; > - esac > - shift > - file="$1" > - shift > - > - $XFS_IO_PROG -c "bmap -${param}lpv" "$file" | grep -c "$@" > -} > - > _require_chattr() > { > attribute=$1 > @@ -3962,80 +3425,6 @@ _get_fs_sysfs_attr() > } > > > -# Reset all xfs error handling attributes, set them to original > -# status. > -# > -# Only one argument, and it's mandatory: > -# - dev: device name, e.g. $SCRATCH_DEV > -# > -# Note: this function only works for XFS > -_reset_xfs_sysfs_error_handling() > -{ > - local dev=$1 > - > - if [ ! -b "$dev" -o "$FSTYP" != "xfs" ];then > - _fail "Usage: reset_xfs_sysfs_error_handling <device>" > - fi > - > - _set_fs_sysfs_attr $dev error/fail_at_unmount 1 > - echo -n "error/fail_at_unmount=" > - _get_fs_sysfs_attr $dev error/fail_at_unmount > - > - # Make sure all will be configured to retry forever by default, except > - # for ENODEV, which is an unrecoverable error, so it will be configured > - # to not retry on error by default. > - for e in default EIO ENOSPC; do > - _set_fs_sysfs_attr $dev \ > - error/metadata/${e}/max_retries -1 > - echo -n "error/metadata/${e}/max_retries=" > - _get_fs_sysfs_attr $dev error/metadata/${e}/max_retries > - > - _set_fs_sysfs_attr $dev \ > - error/metadata/${e}/retry_timeout_seconds 0 > - echo -n "error/metadata/${e}/retry_timeout_seconds=" > - _get_fs_sysfs_attr $dev \ > - error/metadata/${e}/retry_timeout_seconds > - done > -} > - > -# Skip if we are running an older binary without the stricter input checks. > -# Make multiple checks to be sure that there is no regression on the one > -# selected feature check, which would skew the result. > -# > -# At first, make a common function that runs the tests and returns > -# number of failed cases. > -_xfs_mkfs_validation_check() > -{ > - local tmpfile=`mktemp` > - local cmd="$MKFS_XFS_PROG -f -N -d file,name=$tmpfile,size=1g" > - > - $cmd -s size=2s >/dev/null 2>&1 > - local sum=$? > - > - $cmd -l version=2,su=260k >/dev/null 2>&1 > - sum=`expr $sum + $?` > - > - rm -f $tmpfile > - return $sum > -} > - > -# Skip the test if all calls passed - mkfs accepts invalid input > -_require_xfs_mkfs_validation() > -{ > - _xfs_mkfs_validation_check > - if [ "$?" -eq 0 ]; then > - _notrun "Requires newer mkfs with stricter input checks: the oldest supported version of xfsprogs is 4.7." > - fi > -} > - > -# The oposite of _require_xfs_mkfs_validation. > -_require_xfs_mkfs_without_validation() > -{ > - _xfs_mkfs_validation_check > - if [ "$?" -ne 0 ]; then > - _notrun "Requires older mkfs without strict input checks: the last supported version of xfsprogs is 4.5." > - fi > -} > > init_rc > > diff --git a/common/xfs b/common/xfs > new file mode 100644 > index 000000000000..0dde83f26518 > --- /dev/null > +++ b/common/xfs > @@ -0,0 +1,618 @@ > +# > +# XFS specific common functions. > +# > + > +_setup_large_xfs_fs() > +{ > + fs_size=$1 > + local tmp_dir=/tmp/ > + > + [ "$LARGE_SCRATCH_DEV" != yes ] && return 0 > + [ -z "$SCRATCH_DEV_EMPTY_SPACE" ] && SCRATCH_DEV_EMPTY_SPACE=0 > + [ $SCRATCH_DEV_EMPTY_SPACE -ge $fs_size ] && return 0 > + > + # calculate the size of the file we need to allocate. > + # Default free space in the FS is 50GB, but you can specify more via > + # SCRATCH_DEV_EMPTY_SPACE > + file_size=$(($fs_size - 50*1024*1024*1024)) > + file_size=$(($file_size - $SCRATCH_DEV_EMPTY_SPACE)) > + > + # mount the filesystem, create the file, unmount it > + _scratch_mount 2>&1 >$tmp_dir/mnt.err > + local status=$? > + if [ $status -ne 0 ]; then > + echo "mount failed" > + cat $tmp_dir/mnt.err >&2 > + rm -f $tmp_dir/mnt.err > + return $status > + fi > + rm -f $tmp_dir/mnt.err > + > + xfs_io -F -f \ > + -c "truncate $file_size" \ > + -c "falloc -k 0 $file_size" \ > + -c "chattr +d" \ > + $SCRATCH_MNT/.use_space 2>&1 > /dev/null > + export NUM_SPACE_FILES=1 > + status=$? > + _scratch_unmount > + if [ $status -ne 0 ]; then > + echo "large file prealloc failed" > + cat $tmp_dir/mnt.err >&2 > + return $status > + fi > + return 0 > +} > + > +_scratch_mkfs_xfs_opts() > +{ > + mkfs_opts=$* > + > + # remove metadata related mkfs options if mkfs.xfs doesn't them > + if [ -n "$XFS_MKFS_HAS_NO_META_SUPPORT" ]; then > + mkfs_opts=`echo $mkfs_opts | sed "s/-m\s\+\S\+//g"` > + fi > + > + _scratch_options mkfs > + > + $MKFS_XFS_PROG $SCRATCH_OPTIONS $mkfs_opts $SCRATCH_DEV > +} > + > + > +_scratch_mkfs_xfs_supported() > +{ > + local mkfs_opts=$* > + > + _scratch_options mkfs > + > + $MKFS_XFS_PROG -N $MKFS_OPTIONS $SCRATCH_OPTIONS $mkfs_opts $SCRATCH_DEV > + local mkfs_status=$? > + > + # a mkfs failure may be caused by conflicts between $MKFS_OPTIONS and > + # $mkfs_opts, try again without $MKFS_OPTIONS > + if [ $mkfs_status -ne 0 -a -n "$mkfs_opts" ]; then > + $MKFS_XFS_PROG -N $SCRATCH_OPTIONS $mkfs_opts $SCRATCH_DEV > + mkfs_status=$? > + fi > + return $mkfs_status > +} > + > +_scratch_mkfs_xfs() > +{ > + # extra mkfs options can be added by tests > + local extra_mkfs_options=$* > + > + local tmp_dir=/tmp/ > + > + # save mkfs output in case conflict means we need to run again. > + # only the output for the mkfs that applies should be shown > + _scratch_mkfs_xfs_opts $MKFS_OPTIONS $extra_mkfs_options \ > + 2>$tmp_dir.mkfserr 1>$tmp_dir.mkfsstd > + local mkfs_status=$? > + > + > + # a mkfs failure may be caused by conflicts between > + # $MKFS_OPTIONS and $extra_mkfs_options > + if [ $mkfs_status -ne 0 -a ! -z "$extra_mkfs_options" ]; then > + ( > + echo -n "** mkfs failed with extra mkfs options " > + echo "added to \"$MKFS_OPTIONS\" by test $seq **" > + echo -n "** attempting to mkfs using only test $seq " > + echo "options: $extra_mkfs_options **" > + ) >> $seqres.full > + > + # running mkfs again. overwrite previous mkfs output files > + _scratch_mkfs_xfs_opts $extra_mkfs_options \ > + 2>$tmp_dir.mkfserr 1>$tmp_dir.mkfsstd > + local mkfs_status=$? > + fi > + > + if [ $mkfs_status -eq 0 -a "$LARGE_SCRATCH_DEV" = yes ]; then > + # manually parse the mkfs output to get the fs size in bytes > + local fs_size > + fs_size=`cat $tmp_dir.mkfsstd | perl -ne ' > + if (/^data\s+=\s+bsize=(\d+)\s+blocks=(\d+)/) { > + my $size = $1 * $2; > + print STDOUT "$size\n"; > + }'` > + _setup_large_xfs_fs $fs_size > + mkfs_status=$? > + fi > + > + # output stored mkfs output, filtering unnecessary warnings from stderr > + cat $tmp_dir.mkfsstd > + cat $tmp_dir.mkfserr | sed \ > + -e '/less than device physical sector/d' \ > + -e '/switching to logical sector/d' \ > + >&2 > + rm -f $tmp_dir.mkfserr $tmp_dir.mkfsstd > + > + return $mkfs_status > +} > + > +# xfs_check script is planned to be deprecated. But, we want to > +# be able to invoke "xfs_check" behavior in xfstests in order to > +# maintain the current verification levels. > +_xfs_check() > +{ > + OPTS=" " > + DBOPTS=" " > + USAGE="Usage: xfs_check [-fsvV] [-l logdev] [-i ino]... [-b bno]... special" > + > + while getopts "b:fi:l:stvV" c > + do > + case $c in > + s) OPTS=$OPTS"-s ";; > + t) OPTS=$OPTS"-t ";; > + v) OPTS=$OPTS"-v ";; > + i) OPTS=$OPTS"-i "$OPTARG" ";; > + b) OPTS=$OPTS"-b "$OPTARG" ";; > + f) DBOPTS=$DBOPTS" -f";; > + l) DBOPTS=$DBOPTS" -l "$OPTARG" ";; > + V) $XFS_DB_PROG -p xfs_check -V > + return $? > + ;; > + esac > + done > + set -- extra $@ > + shift $OPTIND > + case $# in > + 1) ${XFS_DB_PROG}${DBOPTS} -F -i -p xfs_check -c "check$OPTS" $1 > + status=$? > + ;; > + 2) echo $USAGE 1>&1 > + status=2 > + ;; > + esac > + return $status > +} > + > +_scratch_xfs_db_options() > +{ > + SCRATCH_OPTIONS="" > + [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \ > + SCRATCH_OPTIONS="-l$SCRATCH_LOGDEV" > + echo $SCRATCH_OPTIONS $* $SCRATCH_DEV > +} > + > +_scratch_xfs_db() > +{ > + $XFS_DB_PROG "$@" $(_scratch_xfs_db_options) > +} > + > +_scratch_xfs_logprint() > +{ > + SCRATCH_OPTIONS="" > + [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \ > + SCRATCH_OPTIONS="-l$SCRATCH_LOGDEV" > + $XFS_LOGPRINT_PROG $SCRATCH_OPTIONS $* $SCRATCH_DEV > +} > + > +_test_xfs_logprint() > +{ > + TEST_OPTIONS="" > + [ "$USE_EXTERNAL" = yes -a ! -z "$TEST_LOGDEV" ] && \ > + TEST_OPTIONS="-l$TEST_LOGDEV" > + $XFS_LOGPRINT_PROG $TEST_OPTIONS $* $TEST_DEV > +} > + > +_scratch_xfs_check() > +{ > + SCRATCH_OPTIONS="" > + [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \ > + SCRATCH_OPTIONS="-l $SCRATCH_LOGDEV" > + [ "$LARGE_SCRATCH_DEV" = yes ] && \ > + SCRATCH_OPTIONS=$SCRATCH_OPTIONS" -t" > + _xfs_check $SCRATCH_OPTIONS $* $SCRATCH_DEV > +} > + > +_scratch_xfs_repair() > +{ > + SCRATCH_OPTIONS="" > + [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \ > + SCRATCH_OPTIONS="-l$SCRATCH_LOGDEV" > + [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_RTDEV" ] && \ > + SCRATCH_OPTIONS=$SCRATCH_OPTIONS" -r$SCRATCH_RTDEV" > + [ "$LARGE_SCRATCH_DEV" = yes ] && SCRATCH_OPTIONS=$SCRATCH_OPTIONS" -t" > + $XFS_REPAIR_PROG $SCRATCH_OPTIONS $* $SCRATCH_DEV > +} > + > +# this test requires the projid32bit feature to be available in mkfs.xfs. > +# > +_require_projid32bit() > +{ > + _scratch_mkfs_xfs_supported -i projid32bit=1 >/dev/null 2>&1 \ > + || _notrun "mkfs.xfs doesn't have projid32bit feature" > +} > + > +_require_projid16bit() > +{ > + _scratch_mkfs_xfs_supported -i projid32bit=0 >/dev/null 2>&1 \ > + || _notrun "16 bit project IDs not supported on $SCRATCH_DEV" > +} > + > +# this test requires the crc feature to be available in mkfs.xfs > +# > +_require_xfs_mkfs_crc() > +{ > + _scratch_mkfs_xfs_supported -m crc=1 >/dev/null 2>&1 \ > + || _notrun "mkfs.xfs doesn't have crc feature" > +} > + > +# this test requires the xfs kernel support crc feature > +# > +_require_xfs_crc() > +{ > + _scratch_mkfs_xfs -m crc=1 >/dev/null 2>&1 > + _scratch_mount >/dev/null 2>&1 \ > + || _notrun "Kernel doesn't support crc feature" > + _scratch_unmount > +} > + > +# this test requires the xfs kernel support crc feature on scratch device > +# > +_require_scratch_xfs_crc() > +{ > + _scratch_mkfs_xfs >/dev/null 2>&1 > + _scratch_mount >/dev/null 2>&1 \ > + || _notrun "Kernel doesn't support crc feature" > + xfs_info $SCRATCH_MNT | grep -q 'crc=1' || _notrun "crc feature not supported by this filesystem" > + _scratch_unmount > +} > + > +# this test requires the finobt feature to be available in mkfs.xfs > +# > +_require_xfs_mkfs_finobt() > +{ > + _scratch_mkfs_xfs_supported -m crc=1,finobt=1 >/dev/null 2>&1 \ > + || _notrun "mkfs.xfs doesn't have finobt feature" > +} > + > +# this test requires the xfs kernel support finobt feature > +# > +_require_xfs_finobt() > +{ > + _scratch_mkfs_xfs -m crc=1,finobt=1 >/dev/null 2>&1 > + _scratch_mount >/dev/null 2>&1 \ > + || _notrun "Kernel doesn't support finobt feature" > + _scratch_unmount > +} > + > +# this test requires xfs sysfs attribute support > +# > +_require_xfs_sysfs() > +{ > + attr=$1 > + sysfsdir=/sys/fs/xfs > + > + if [ ! -e $sysfsdir ]; then > + _notrun "no kernel support for XFS sysfs attributes" > + fi > + > + if [ ! -z $1 ] && [ ! -e $sysfsdir/$attr ]; then > + _notrun "sysfs attribute '$attr' is not supported" > + fi > +} > + > +# this test requires the xfs sparse inode feature > +# > +_require_xfs_sparse_inodes() > +{ > + _scratch_mkfs_xfs_supported -m crc=1 -i sparse > /dev/null 2>&1 \ > + || _notrun "mkfs.xfs does not support sparse inodes" > + _scratch_mkfs_xfs -m crc=1 -i sparse > /dev/null 2>&1 > + _scratch_mount >/dev/null 2>&1 \ > + || _notrun "kernel does not support sparse inodes" > + _scratch_unmount > +} > + > +# check that xfs_db supports a specific command > +_require_xfs_db_command() > +{ > + if [ $# -ne 1 ] > + then > + echo "Usage: _require_xfs_db_command command" 1>&2 > + exit 1 > + fi > + command=$1 > + > + _scratch_xfs_db -x -c "help" | grep $command > /dev/null || \ > + _notrun "xfs_db $command support is missing" > +} > + > +# run xfs_check and friends on a FS. > +_check_xfs_filesystem() > +{ > + if [ $# -ne 3 ] > + then > + echo "Usage: _check_xfs_filesystem device <logdev>|none <rtdev>|none" 1>&2 > + exit 1 > + fi > + > + extra_mount_options="" > + extra_log_options="" > + extra_options="" > + device=$1 > + if [ -f $device ];then > + extra_options="-f" > + fi > + > + if [ "$2" != "none" ]; then > + extra_log_options="-l$2" > + extra_mount_options="-ologdev=$2" > + fi > + > + if [ "$3" != "none" ]; then > + extra_rt_options="-r$3" > + extra_mount_options=$extra_mount_options" -ortdev=$3" > + fi > + extra_mount_options=$extra_mount_options" $MOUNT_OPTIONS" > + > + [ "$FSTYP" != xfs ] && return 0 > + > + type=`_fs_type $device` > + ok=1 > + > + if [ "$type" = "xfs" ] > + then > + if [ -n "$TEST_XFS_SCRUB" ] && [ -x "$XFS_SCRUB_PROG" ]; then > + "$XFS_SCRUB_PROG" $scrubflag -vd $device >>$seqres.full > + if [ $? -ne 0 ]; then > + echo "filesystem on $device failed scrub (see $seqres.full)" > + ok=0 > + fi > + fi > + # mounted ... > + mountpoint=`_umount_or_remount_ro $device` > + fi > + > + $XFS_LOGPRINT_PROG -t $extra_log_options $device 2>&1 \ > + | tee $tmp.logprint | grep -q "<CLEAN>" > + if [ $? -ne 0 -a "$HOSTOS" = "Linux" ] > + then > + echo "_check_xfs_filesystem: filesystem on $device has dirty log (see $seqres.full)" > + > + echo "_check_xfs_filesystem: filesystem on $device has dirty log" >>$seqres.full > + echo "*** xfs_logprint -t output ***" >>$seqres.full > + cat $tmp.logprint >>$seqres.full > + echo "*** end xfs_logprint output" >>$seqres.full > + > + ok=0 > + fi > + > + # xfs_check runs out of memory on large files, so even providing the test > + # option (-t) to avoid indexing the free space trees doesn't make it pass on > + # large filesystems. Avoid it. > + if [ "$LARGE_SCRATCH_DEV" != yes ]; then > + _xfs_check $extra_log_options $device 2>&1 |\ > + _fix_malloc >$tmp.fs_check > + fi > + if [ -s $tmp.fs_check ] > + then > + echo "_check_xfs_filesystem: filesystem on $device is inconsistent (c) (see $seqres.full)" > + > + echo "_check_xfs_filesystem: filesystem on $device is inconsistent" >>$seqres.full > + echo "*** xfs_check output ***" >>$seqres.full > + cat $tmp.fs_check >>$seqres.full > + echo "*** end xfs_check output" >>$seqres.full > + > + ok=0 > + fi > + > + $XFS_REPAIR_PROG -n $extra_options $extra_log_options $extra_rt_options $device >$tmp.repair 2>&1 > + if [ $? -ne 0 ] > + then > + echo "_check_xfs_filesystem: filesystem on $device is inconsistent (r) (see $seqres.full)" > + > + echo "_check_xfs_filesystem: filesystem on $device is inconsistent" >>$seqres.full > + echo "*** xfs_repair -n output ***" >>$seqres.full > + cat $tmp.repair | _fix_malloc >>$seqres.full > + echo "*** end xfs_repair output" >>$seqres.full > + > + ok=0 > + fi > + rm -f $tmp.fs_check $tmp.logprint $tmp.repair > + > + # Optionally test the index rebuilding behavior. > + if [ -n "$TEST_XFS_REPAIR_REBUILD" ]; then > + $XFS_REPAIR_PROG $extra_options $extra_log_options $extra_rt_options $device >$tmp.repair 2>&1 > + if [ $? -ne 0 ]; then > + echo "_check_xfs_filesystem: filesystem on $device is inconsistent (rebuild) (see $seqres.full)" > + > + echo "_check_xfs_filesystem: filesystem on $device is inconsistent (rebuild)" >>$seqres.full > + echo "*** xfs_repair output ***" >>$seqres.full > + cat $tmp.repair | _fix_malloc >>$seqres.full > + echo "*** end xfs_repair output" >>$seqres.full > + > + ok=0 > + fi > + rm -f $tmp.repair > + > + $XFS_REPAIR_PROG -n $extra_options $extra_log_options $extra_rt_options $device >$tmp.repair 2>&1 > + if [ $? -ne 0 ]; then > + echo "_check_xfs_filesystem: filesystem on $device is inconsistent (rebuild-reverify) (see $seqres.full)" > + > + echo "_check_xfs_filesystem: filesystem on $device is inconsistent (rebuild-reverify)" >>$seqres.full > + echo "*** xfs_repair -n output ***" >>$seqres.full > + cat $tmp.repair | _fix_malloc >>$seqres.full > + echo "*** end xfs_repair output" >>$seqres.full > + > + ok=0 > + fi > + rm -f $tmp.repair > + fi > + > + if [ $ok -eq 0 ] > + then > + echo "*** mount output ***" >>$seqres.full > + _mount >>$seqres.full > + echo "*** end mount output" >>$seqres.full > + elif [ "$type" = "xfs" ] > + then > + _mount_or_remount_rw "$extra_mount_options" $device $mountpoint > + fi > + > + if [ $ok -eq 0 ]; then > + status=1 > + if [ "$iam" != "check" ]; then > + exit 1 > + fi > + return 1 > + fi > + > + return 0 > +} > + > +_check_xfs_test_fs() > +{ > + TEST_LOG="none" > + TEST_RT="none" > + [ "$USE_EXTERNAL" = yes -a ! -z "$TEST_LOGDEV" ] && \ > + TEST_LOG="$TEST_LOGDEV" > + > + [ "$USE_EXTERNAL" = yes -a ! -z "$TEST_RTDEV" ] && \ > + TEST_RT="$TEST_RTDEV" > + > + _check_xfs_filesystem $TEST_DEV $TEST_LOG $TEST_RT > + > + # check for ipath consistency > + if $XFS_GROWFS_PROG -n $TEST_DIR | grep -q 'inode-paths=1'; then > + # errors go to stderr > + xfs_check_ipaths $TEST_DIR >/dev/null > + xfs_repair_ipaths -n $TEST_DIR >/dev/null > + fi > +} > + > +_require_xfs_test_rmapbt() > +{ > + _require_test > + > + if [ "$(xfs_info "$TEST_DIR" | grep -c "rmapbt=1")" -ne 1 ]; then > + _notrun "rmapbt not supported by test filesystem type: $FSTYP" > + fi > +} > + > +_require_xfs_scratch_rmapbt() > +{ > + _require_scratch > + > + _scratch_mkfs > /dev/null > + _scratch_mount > + if [ "$(xfs_info "$SCRATCH_MNT" | grep -c "rmapbt=1")" -ne 1 ]; then > + _scratch_unmount > + _notrun "rmapbt not supported by scratch filesystem type: $FSTYP" > + fi > + _scratch_unmount > +} > + > +_xfs_bmapx_find() { > + case "$1" in > + "attr") > + param="a" > + ;; > + "cow") > + param="c" > + ;; > + *) > + param="e" > + ;; > + esac > + shift > + file="$1" > + shift > + > + $XFS_IO_PROG -c "bmap -${param}lpv" "$file" | grep -c "$@" > +} > + > +# Reset all xfs error handling attributes, set them to original > +# status. > +# > +# Only one argument, and it's mandatory: > +# - dev: device name, e.g. $SCRATCH_DEV > +# > +# Note: this function only works for XFS > +_reset_xfs_sysfs_error_handling() > +{ > + local dev=$1 > + > + if [ ! -b "$dev" -o "$FSTYP" != "xfs" ];then > + _fail "Usage: reset_xfs_sysfs_error_handling <device>" > + fi > + > + _set_fs_sysfs_attr $dev error/fail_at_unmount 1 > + echo -n "error/fail_at_unmount=" > + _get_fs_sysfs_attr $dev error/fail_at_unmount > + > + # Make sure all will be configured to retry forever by default, except > + # for ENODEV, which is an unrecoverable error, so it will be configured > + # to not retry on error by default. > + for e in default EIO ENOSPC; do > + _set_fs_sysfs_attr $dev \ > + error/metadata/${e}/max_retries -1 > + echo -n "error/metadata/${e}/max_retries=" > + _get_fs_sysfs_attr $dev error/metadata/${e}/max_retries > + > + _set_fs_sysfs_attr $dev \ > + error/metadata/${e}/retry_timeout_seconds 0 > + echo -n "error/metadata/${e}/retry_timeout_seconds=" > + _get_fs_sysfs_attr $dev \ > + error/metadata/${e}/retry_timeout_seconds > + done > +} > + > +# Skip if we are running an older binary without the stricter input checks. > +# Make multiple checks to be sure that there is no regression on the one > +# selected feature check, which would skew the result. > +# > +# At first, make a common function that runs the tests and returns > +# number of failed cases. > +_xfs_mkfs_validation_check() > +{ > + local tmpfile=`mktemp` > + local cmd="$MKFS_XFS_PROG -f -N -d file,name=$tmpfile,size=1g" > + > + $cmd -s size=2s >/dev/null 2>&1 > + local sum=$? > + > + $cmd -l version=2,su=260k >/dev/null 2>&1 > + sum=`expr $sum + $?` > + > + rm -f $tmpfile > + return $sum > +} > + > +# Skip the test if all calls passed - mkfs accepts invalid input > +_require_xfs_mkfs_validation() > +{ > + _xfs_mkfs_validation_check > + if [ "$?" -eq 0 ]; then > + _notrun "Requires newer mkfs with stricter input checks: the oldest supported version of xfsprogs is 4.7." > + fi > +} > + > +# The opposite of _require_xfs_mkfs_validation. > +_require_xfs_mkfs_without_validation() > +{ > + _xfs_mkfs_validation_check > + if [ "$?" -ne 0 ]; then > + _notrun "Requires older mkfs without strict input checks: the last supported version of xfsprogs is 4.5." > + fi > +} > + > +# XFS ability to change UUIDs on V5/CRC filesystems > +# > +_require_meta_uuid() > +{ > + # This will create a crc fs on $SCRATCH_DEV > + _require_xfs_crc > + > + _scratch_xfs_db -x -c "uuid restore" 2>&1 \ > + | grep -q "invalid UUID\|supported on V5 fs" \ > + && _notrun "Userspace doesn't support meta_uuid feature" > + > + _scratch_xfs_db -x -c "uuid generate" >/dev/null 2>&1 > + > + _scratch_mount >/dev/null 2>&1 \ > + || _notrun "Kernel doesn't support meta_uuid feature" > + _scratch_unmount > +} > -- > 2.10.2 > > -- > To unsubscribe from this list: send the line "unsubscribe fstests" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe fstests" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/common/rc b/common/rc index 8c993066597c..00b53643f248 100644 --- a/common/rc +++ b/common/rc @@ -123,6 +123,9 @@ then fi fi +# make sure we have a standard umask +umask 022 + # check for correct setup case "$FSTYP" in xfs) @@ -130,6 +133,9 @@ case "$FSTYP" in [ "$XFS_REPAIR_PROG" = "" ] && _fatal "xfs_repair not found" [ "$XFS_DB_PROG" = "" ] && _fatal "xfs_db not found" [ "$MKFS_XFS_PROG" = "" ] && _fatal "mkfs_xfs not found" + + #source the XFS specific functions now. + . ./common/xfs ;; udf) [ "$MKFS_UDF_PROG" = "" ] && _fatal "mkfs_udf/mkudffs not found" @@ -156,9 +162,6 @@ case "$FSTYP" in ;; esac -# make sure we have a standard umask -umask 022 - _mount() { $MOUNT_PROG `_mount_ops_filter $*` @@ -425,171 +428,6 @@ _scratch_metadump() xfs_metadump $options $SCRATCH_DEV $dumpfile } -_setup_large_xfs_fs() -{ - fs_size=$1 - local tmp_dir=/tmp/ - - [ "$LARGE_SCRATCH_DEV" != yes ] && return 0 - [ -z "$SCRATCH_DEV_EMPTY_SPACE" ] && SCRATCH_DEV_EMPTY_SPACE=0 - [ $SCRATCH_DEV_EMPTY_SPACE -ge $fs_size ] && return 0 - - # calculate the size of the file we need to allocate. - # Default free space in the FS is 50GB, but you can specify more via - # SCRATCH_DEV_EMPTY_SPACE - file_size=$(($fs_size - 50*1024*1024*1024)) - file_size=$(($file_size - $SCRATCH_DEV_EMPTY_SPACE)) - - # mount the filesystem, create the file, unmount it - _scratch_mount 2>&1 >$tmp_dir/mnt.err - local status=$? - if [ $status -ne 0 ]; then - echo "mount failed" - cat $tmp_dir/mnt.err >&2 - rm -f $tmp_dir/mnt.err - return $status - fi - rm -f $tmp_dir/mnt.err - - xfs_io -F -f \ - -c "truncate $file_size" \ - -c "falloc -k 0 $file_size" \ - -c "chattr +d" \ - $SCRATCH_MNT/.use_space 2>&1 > /dev/null - export NUM_SPACE_FILES=1 - status=$? - _scratch_unmount - if [ $status -ne 0 ]; then - echo "large file prealloc failed" - cat $tmp_dir/mnt.err >&2 - return $status - fi - return 0 -} - -_scratch_mkfs_xfs_opts() -{ - mkfs_opts=$* - - # remove metadata related mkfs options if mkfs.xfs doesn't them - if [ -n "$XFS_MKFS_HAS_NO_META_SUPPORT" ]; then - mkfs_opts=`echo $mkfs_opts | sed "s/-m\s\+\S\+//g"` - fi - - _scratch_options mkfs - - $MKFS_XFS_PROG $SCRATCH_OPTIONS $mkfs_opts $SCRATCH_DEV -} - - -_scratch_mkfs_xfs_supported() -{ - local mkfs_opts=$* - - _scratch_options mkfs - - $MKFS_XFS_PROG -N $MKFS_OPTIONS $SCRATCH_OPTIONS $mkfs_opts $SCRATCH_DEV - local mkfs_status=$? - - # a mkfs failure may be caused by conflicts between $MKFS_OPTIONS and - # $mkfs_opts, try again without $MKFS_OPTIONS - if [ $mkfs_status -ne 0 -a -n "$mkfs_opts" ]; then - $MKFS_XFS_PROG -N $SCRATCH_OPTIONS $mkfs_opts $SCRATCH_DEV - mkfs_status=$? - fi - return $mkfs_status -} - -_scratch_mkfs_xfs() -{ - # extra mkfs options can be added by tests - local extra_mkfs_options=$* - - local tmp_dir=/tmp/ - - # save mkfs output in case conflict means we need to run again. - # only the output for the mkfs that applies should be shown - _scratch_mkfs_xfs_opts $MKFS_OPTIONS $extra_mkfs_options \ - 2>$tmp_dir.mkfserr 1>$tmp_dir.mkfsstd - local mkfs_status=$? - - - # a mkfs failure may be caused by conflicts between - # $MKFS_OPTIONS and $extra_mkfs_options - if [ $mkfs_status -ne 0 -a ! -z "$extra_mkfs_options" ]; then - ( - echo -n "** mkfs failed with extra mkfs options " - echo "added to \"$MKFS_OPTIONS\" by test $seq **" - echo -n "** attempting to mkfs using only test $seq " - echo "options: $extra_mkfs_options **" - ) >> $seqres.full - - # running mkfs again. overwrite previous mkfs output files - _scratch_mkfs_xfs_opts $extra_mkfs_options \ - 2>$tmp_dir.mkfserr 1>$tmp_dir.mkfsstd - local mkfs_status=$? - fi - - if [ $mkfs_status -eq 0 -a "$LARGE_SCRATCH_DEV" = yes ]; then - # manually parse the mkfs output to get the fs size in bytes - local fs_size - fs_size=`cat $tmp_dir.mkfsstd | perl -ne ' - if (/^data\s+=\s+bsize=(\d+)\s+blocks=(\d+)/) { - my $size = $1 * $2; - print STDOUT "$size\n"; - }'` - _setup_large_xfs_fs $fs_size - mkfs_status=$? - fi - - # output stored mkfs output, filtering unnecessary warnings from stderr - cat $tmp_dir.mkfsstd - cat $tmp_dir.mkfserr | sed \ - -e '/less than device physical sector/d' \ - -e '/switching to logical sector/d' \ - >&2 - rm -f $tmp_dir.mkfserr $tmp_dir.mkfsstd - - return $mkfs_status -} - -# xfs_check script is planned to be deprecated. But, we want to -# be able to invoke "xfs_check" behavior in xfstests in order to -# maintain the current verification levels. -_xfs_check() -{ - OPTS=" " - DBOPTS=" " - USAGE="Usage: xfs_check [-fsvV] [-l logdev] [-i ino]... [-b bno]... special" - - while getopts "b:fi:l:stvV" c - do - case $c in - s) OPTS=$OPTS"-s ";; - t) OPTS=$OPTS"-t ";; - v) OPTS=$OPTS"-v ";; - i) OPTS=$OPTS"-i "$OPTARG" ";; - b) OPTS=$OPTS"-b "$OPTARG" ";; - f) DBOPTS=$DBOPTS" -f";; - l) DBOPTS=$DBOPTS" -l "$OPTARG" ";; - V) $XFS_DB_PROG -p xfs_check -V - return $? - ;; - esac - done - set -- extra $@ - shift $OPTIND - case $# in - 1) ${XFS_DB_PROG}${DBOPTS} -F -i -p xfs_check -c "check$OPTS" $1 - status=$? - ;; - 2) echo $USAGE 1>&1 - status=2 - ;; - esac - return $status -} - _setup_large_ext4_fs() { fs_size=$1 @@ -1113,55 +951,6 @@ _scratch_resvblks() esac } -_scratch_xfs_db_options() -{ - SCRATCH_OPTIONS="" - [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \ - SCRATCH_OPTIONS="-l$SCRATCH_LOGDEV" - echo $SCRATCH_OPTIONS $* $SCRATCH_DEV -} - -_scratch_xfs_db() -{ - $XFS_DB_PROG "$@" $(_scratch_xfs_db_options) -} - -_scratch_xfs_logprint() -{ - SCRATCH_OPTIONS="" - [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \ - SCRATCH_OPTIONS="-l$SCRATCH_LOGDEV" - $XFS_LOGPRINT_PROG $SCRATCH_OPTIONS $* $SCRATCH_DEV -} - -_test_xfs_logprint() -{ - TEST_OPTIONS="" - [ "$USE_EXTERNAL" = yes -a ! -z "$TEST_LOGDEV" ] && \ - TEST_OPTIONS="-l$TEST_LOGDEV" - $XFS_LOGPRINT_PROG $TEST_OPTIONS $* $TEST_DEV -} - -_scratch_xfs_check() -{ - SCRATCH_OPTIONS="" - [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \ - SCRATCH_OPTIONS="-l $SCRATCH_LOGDEV" - [ "$LARGE_SCRATCH_DEV" = yes ] && \ - SCRATCH_OPTIONS=$SCRATCH_OPTIONS" -t" - _xfs_check $SCRATCH_OPTIONS $* $SCRATCH_DEV -} - -_scratch_xfs_repair() -{ - SCRATCH_OPTIONS="" - [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \ - SCRATCH_OPTIONS="-l$SCRATCH_LOGDEV" - [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_RTDEV" ] && \ - SCRATCH_OPTIONS=$SCRATCH_OPTIONS" -r$SCRATCH_RTDEV" - [ "$LARGE_SCRATCH_DEV" = yes ] && SCRATCH_OPTIONS=$SCRATCH_OPTIONS" -t" - $XFS_REPAIR_PROG $SCRATCH_OPTIONS $* $SCRATCH_DEV -} # Repair scratch filesystem. Returns 0 if the FS is good to go (either no # errors found or errors were fixed) and nonzero otherwise; also spits out @@ -1794,38 +1583,6 @@ _require_dm_target() fi } -# this test requires the projid32bit feature to be available in mkfs.xfs. -# -_require_projid32bit() -{ - _scratch_mkfs_xfs_supported -i projid32bit=1 >/dev/null 2>&1 \ - || _notrun "mkfs.xfs doesn't have projid32bit feature" -} - -_require_projid16bit() -{ - _scratch_mkfs_xfs_supported -i projid32bit=0 >/dev/null 2>&1 \ - || _notrun "16 bit project IDs not supported on $SCRATCH_DEV" -} - -# this test requires the crc feature to be available in mkfs.xfs -# -_require_xfs_mkfs_crc() -{ - _scratch_mkfs_xfs_supported -m crc=1 >/dev/null 2>&1 \ - || _notrun "mkfs.xfs doesn't have crc feature" -} - -# this test requires the xfs kernel support crc feature -# -_require_xfs_crc() -{ - _scratch_mkfs_xfs -m crc=1 >/dev/null 2>&1 - _scratch_mount >/dev/null 2>&1 \ - || _notrun "Kernel doesn't support crc feature" - _scratch_unmount -} - # this test requires the ext4 kernel support crc feature on scratch device # _require_scratch_ext4_crc() @@ -1837,17 +1594,6 @@ _require_scratch_ext4_crc() _scratch_unmount } -# this test requires the xfs kernel support crc feature on scratch device -# -_require_scratch_xfs_crc() -{ - _scratch_mkfs_xfs >/dev/null 2>&1 - _scratch_mount >/dev/null 2>&1 \ - || _notrun "Kernel doesn't support crc feature" - xfs_info $SCRATCH_MNT | grep -q 'crc=1' || _notrun "crc feature not supported by this filesystem" - _scratch_unmount -} - # this test requires the bigalloc feature to be available in mkfs.ext4 # _require_ext4_mkfs_bigalloc() @@ -1866,52 +1612,6 @@ _require_ext4_bigalloc() _scratch_unmount } -# this test requires the finobt feature to be available in mkfs.xfs -# -_require_xfs_mkfs_finobt() -{ - _scratch_mkfs_xfs_supported -m crc=1,finobt=1 >/dev/null 2>&1 \ - || _notrun "mkfs.xfs doesn't have finobt feature" -} - -# this test requires the xfs kernel support finobt feature -# -_require_xfs_finobt() -{ - _scratch_mkfs_xfs -m crc=1,finobt=1 >/dev/null 2>&1 - _scratch_mount >/dev/null 2>&1 \ - || _notrun "Kernel doesn't support finobt feature" - _scratch_unmount -} - -# this test requires xfs sysfs attribute support -# -_require_xfs_sysfs() -{ - attr=$1 - sysfsdir=/sys/fs/xfs - - if [ ! -e $sysfsdir ]; then - _notrun "no kernel support for XFS sysfs attributes" - fi - - if [ ! -z $1 ] && [ ! -e $sysfsdir/$attr ]; then - _notrun "sysfs attribute '$attr' is not supported" - fi -} - -# this test requires the xfs sparse inode feature -# -_require_xfs_sparse_inodes() -{ - _scratch_mkfs_xfs_supported -m crc=1 -i sparse > /dev/null 2>&1 \ - || _notrun "mkfs.xfs does not support sparse inodes" - _scratch_mkfs_xfs -m crc=1 -i sparse > /dev/null 2>&1 - _scratch_mount >/dev/null 2>&1 \ - || _notrun "kernel does not support sparse inodes" - _scratch_unmount -} - # this test requires that external log/realtime devices are not in use # _require_nonexternal() @@ -2093,20 +1793,6 @@ _require_xfs_io_command() _notrun "xfs_io $command doesn't support $param" } -# check that xfs_db supports a specific command -_require_xfs_db_command() -{ - if [ $# -ne 1 ] - then - echo "Usage: _require_xfs_db_command command" 1>&2 - exit 1 - fi - command=$1 - - _scratch_xfs_db -x -c "help" | grep $command > /dev/null || \ - _notrun "xfs_db $command support is missing" -} - # check that kernel and filesystem support direct I/O _require_odirect() { @@ -2403,150 +2089,6 @@ _check_generic_filesystem() return 0 } -# run xfs_check and friends on a FS. - -_check_xfs_filesystem() -{ - if [ $# -ne 3 ] - then - echo "Usage: _check_xfs_filesystem device <logdev>|none <rtdev>|none" 1>&2 - exit 1 - fi - - extra_mount_options="" - extra_log_options="" - extra_options="" - device=$1 - if [ -f $device ];then - extra_options="-f" - fi - - if [ "$2" != "none" ]; then - extra_log_options="-l$2" - extra_mount_options="-ologdev=$2" - fi - - if [ "$3" != "none" ]; then - extra_rt_options="-r$3" - extra_mount_options=$extra_mount_options" -ortdev=$3" - fi - extra_mount_options=$extra_mount_options" $MOUNT_OPTIONS" - - [ "$FSTYP" != xfs ] && return 0 - - type=`_fs_type $device` - ok=1 - - if [ "$type" = "xfs" ] - then - if [ -n "$TEST_XFS_SCRUB" ] && [ -x "$XFS_SCRUB_PROG" ]; then - "$XFS_SCRUB_PROG" $scrubflag -vd $device >>$seqres.full - if [ $? -ne 0 ]; then - echo "filesystem on $device failed scrub (see $seqres.full)" - ok=0 - fi - fi - # mounted ... - mountpoint=`_umount_or_remount_ro $device` - fi - - $XFS_LOGPRINT_PROG -t $extra_log_options $device 2>&1 \ - | tee $tmp.logprint | grep -q "<CLEAN>" - if [ $? -ne 0 -a "$HOSTOS" = "Linux" ] - then - echo "_check_xfs_filesystem: filesystem on $device has dirty log (see $seqres.full)" - - echo "_check_xfs_filesystem: filesystem on $device has dirty log" >>$seqres.full - echo "*** xfs_logprint -t output ***" >>$seqres.full - cat $tmp.logprint >>$seqres.full - echo "*** end xfs_logprint output" >>$seqres.full - - ok=0 - fi - - # xfs_check runs out of memory on large files, so even providing the test - # option (-t) to avoid indexing the free space trees doesn't make it pass on - # large filesystems. Avoid it. - if [ "$LARGE_SCRATCH_DEV" != yes ]; then - _xfs_check $extra_log_options $device 2>&1 |\ - _fix_malloc >$tmp.fs_check - fi - if [ -s $tmp.fs_check ] - then - echo "_check_xfs_filesystem: filesystem on $device is inconsistent (c) (see $seqres.full)" - - echo "_check_xfs_filesystem: filesystem on $device is inconsistent" >>$seqres.full - echo "*** xfs_check output ***" >>$seqres.full - cat $tmp.fs_check >>$seqres.full - echo "*** end xfs_check output" >>$seqres.full - - ok=0 - fi - - $XFS_REPAIR_PROG -n $extra_options $extra_log_options $extra_rt_options $device >$tmp.repair 2>&1 - if [ $? -ne 0 ] - then - echo "_check_xfs_filesystem: filesystem on $device is inconsistent (r) (see $seqres.full)" - - echo "_check_xfs_filesystem: filesystem on $device is inconsistent" >>$seqres.full - echo "*** xfs_repair -n output ***" >>$seqres.full - cat $tmp.repair | _fix_malloc >>$seqres.full - echo "*** end xfs_repair output" >>$seqres.full - - ok=0 - fi - rm -f $tmp.fs_check $tmp.logprint $tmp.repair - - # Optionally test the index rebuilding behavior. - if [ -n "$TEST_XFS_REPAIR_REBUILD" ]; then - $XFS_REPAIR_PROG $extra_options $extra_log_options $extra_rt_options $device >$tmp.repair 2>&1 - if [ $? -ne 0 ]; then - echo "_check_xfs_filesystem: filesystem on $device is inconsistent (rebuild) (see $seqres.full)" - - echo "_check_xfs_filesystem: filesystem on $device is inconsistent (rebuild)" >>$seqres.full - echo "*** xfs_repair output ***" >>$seqres.full - cat $tmp.repair | _fix_malloc >>$seqres.full - echo "*** end xfs_repair output" >>$seqres.full - - ok=0 - fi - rm -f $tmp.repair - - $XFS_REPAIR_PROG -n $extra_options $extra_log_options $extra_rt_options $device >$tmp.repair 2>&1 - if [ $? -ne 0 ]; then - echo "_check_xfs_filesystem: filesystem on $device is inconsistent (rebuild-reverify) (see $seqres.full)" - - echo "_check_xfs_filesystem: filesystem on $device is inconsistent (rebuild-reverify)" >>$seqres.full - echo "*** xfs_repair -n output ***" >>$seqres.full - cat $tmp.repair | _fix_malloc >>$seqres.full - echo "*** end xfs_repair output" >>$seqres.full - - ok=0 - fi - rm -f $tmp.repair - fi - - if [ $ok -eq 0 ] - then - echo "*** mount output ***" >>$seqres.full - _mount >>$seqres.full - echo "*** end mount output" >>$seqres.full - elif [ "$type" = "xfs" ] - then - _mount_or_remount_rw "$extra_mount_options" $device $mountpoint - fi - - if [ $ok -eq 0 ]; then - status=1 - if [ "$iam" != "check" ]; then - exit 1 - fi - return 1 - fi - - return 0 -} - # Filter the knowen errors the UDF Verifier reports. _udf_test_known_error_filter() { @@ -2590,26 +2132,6 @@ _check_udf_filesystem() return 0 } -_check_xfs_test_fs() -{ - TEST_LOG="none" - TEST_RT="none" - [ "$USE_EXTERNAL" = yes -a ! -z "$TEST_LOGDEV" ] && \ - TEST_LOG="$TEST_LOGDEV" - - [ "$USE_EXTERNAL" = yes -a ! -z "$TEST_RTDEV" ] && \ - TEST_RT="$TEST_RTDEV" - - _check_xfs_filesystem $TEST_DEV $TEST_LOG $TEST_RT - - # check for ipath consistency - if $XFS_GROWFS_PROG -n $TEST_DIR | grep -q 'inode-paths=1'; then - # errors go to stderr - xfs_check_ipaths $TEST_DIR >/dev/null - xfs_repair_ipaths -n $TEST_DIR >/dev/null - fi -} - _check_btrfs_filesystem() { device=$1 @@ -3382,24 +2904,6 @@ _require_test_fcntl_advisory_locks() _notrun "Require fcntl advisory locks support" } -# XFS ability to change UUIDs on V5/CRC filesystems -# -_require_meta_uuid() -{ - # This will create a crc fs on $SCRATCH_DEV - _require_xfs_crc - - _scratch_xfs_db -x -c "uuid restore" 2>&1 \ - | grep -q "invalid UUID\|supported on V5 fs" \ - && _notrun "Userspace doesn't support meta_uuid feature" - - _scratch_xfs_db -x -c "uuid generate" >/dev/null 2>&1 - - _scratch_mount >/dev/null 2>&1 \ - || _notrun "Kernel doesn't support meta_uuid feature" - _scratch_unmount -} - _require_btrfs_dev_del_by_devid() { $BTRFS_UTIL_PROG device delete --help | egrep devid > /dev/null 2>&1 @@ -3416,47 +2920,6 @@ _require_test_lsattr() _notrun "lsattr not supported by test filesystem type: $FSTYP" } -_require_xfs_test_rmapbt() -{ - _require_test - - if [ "$(xfs_info "$TEST_DIR" | grep -c "rmapbt=1")" -ne 1 ]; then - _notrun "rmapbt not supported by test filesystem type: $FSTYP" - fi -} - -_require_xfs_scratch_rmapbt() -{ - _require_scratch - - _scratch_mkfs > /dev/null - _scratch_mount - if [ "$(xfs_info "$SCRATCH_MNT" | grep -c "rmapbt=1")" -ne 1 ]; then - _scratch_unmount - _notrun "rmapbt not supported by scratch filesystem type: $FSTYP" - fi - _scratch_unmount -} - -_xfs_bmapx_find() { - case "$1" in - "attr") - param="a" - ;; - "cow") - param="c" - ;; - *) - param="e" - ;; - esac - shift - file="$1" - shift - - $XFS_IO_PROG -c "bmap -${param}lpv" "$file" | grep -c "$@" -} - _require_chattr() { attribute=$1 @@ -3962,80 +3425,6 @@ _get_fs_sysfs_attr() } -# Reset all xfs error handling attributes, set them to original -# status. -# -# Only one argument, and it's mandatory: -# - dev: device name, e.g. $SCRATCH_DEV -# -# Note: this function only works for XFS -_reset_xfs_sysfs_error_handling() -{ - local dev=$1 - - if [ ! -b "$dev" -o "$FSTYP" != "xfs" ];then - _fail "Usage: reset_xfs_sysfs_error_handling <device>" - fi - - _set_fs_sysfs_attr $dev error/fail_at_unmount 1 - echo -n "error/fail_at_unmount=" - _get_fs_sysfs_attr $dev error/fail_at_unmount - - # Make sure all will be configured to retry forever by default, except - # for ENODEV, which is an unrecoverable error, so it will be configured - # to not retry on error by default. - for e in default EIO ENOSPC; do - _set_fs_sysfs_attr $dev \ - error/metadata/${e}/max_retries -1 - echo -n "error/metadata/${e}/max_retries=" - _get_fs_sysfs_attr $dev error/metadata/${e}/max_retries - - _set_fs_sysfs_attr $dev \ - error/metadata/${e}/retry_timeout_seconds 0 - echo -n "error/metadata/${e}/retry_timeout_seconds=" - _get_fs_sysfs_attr $dev \ - error/metadata/${e}/retry_timeout_seconds - done -} - -# Skip if we are running an older binary without the stricter input checks. -# Make multiple checks to be sure that there is no regression on the one -# selected feature check, which would skew the result. -# -# At first, make a common function that runs the tests and returns -# number of failed cases. -_xfs_mkfs_validation_check() -{ - local tmpfile=`mktemp` - local cmd="$MKFS_XFS_PROG -f -N -d file,name=$tmpfile,size=1g" - - $cmd -s size=2s >/dev/null 2>&1 - local sum=$? - - $cmd -l version=2,su=260k >/dev/null 2>&1 - sum=`expr $sum + $?` - - rm -f $tmpfile - return $sum -} - -# Skip the test if all calls passed - mkfs accepts invalid input -_require_xfs_mkfs_validation() -{ - _xfs_mkfs_validation_check - if [ "$?" -eq 0 ]; then - _notrun "Requires newer mkfs with stricter input checks: the oldest supported version of xfsprogs is 4.7." - fi -} - -# The oposite of _require_xfs_mkfs_validation. -_require_xfs_mkfs_without_validation() -{ - _xfs_mkfs_validation_check - if [ "$?" -ne 0 ]; then - _notrun "Requires older mkfs without strict input checks: the last supported version of xfsprogs is 4.5." - fi -} init_rc diff --git a/common/xfs b/common/xfs new file mode 100644 index 000000000000..0dde83f26518 --- /dev/null +++ b/common/xfs @@ -0,0 +1,618 @@ +# +# XFS specific common functions. +# + +_setup_large_xfs_fs() +{ + fs_size=$1 + local tmp_dir=/tmp/ + + [ "$LARGE_SCRATCH_DEV" != yes ] && return 0 + [ -z "$SCRATCH_DEV_EMPTY_SPACE" ] && SCRATCH_DEV_EMPTY_SPACE=0 + [ $SCRATCH_DEV_EMPTY_SPACE -ge $fs_size ] && return 0 + + # calculate the size of the file we need to allocate. + # Default free space in the FS is 50GB, but you can specify more via + # SCRATCH_DEV_EMPTY_SPACE + file_size=$(($fs_size - 50*1024*1024*1024)) + file_size=$(($file_size - $SCRATCH_DEV_EMPTY_SPACE)) + + # mount the filesystem, create the file, unmount it + _scratch_mount 2>&1 >$tmp_dir/mnt.err + local status=$? + if [ $status -ne 0 ]; then + echo "mount failed" + cat $tmp_dir/mnt.err >&2 + rm -f $tmp_dir/mnt.err + return $status + fi + rm -f $tmp_dir/mnt.err + + xfs_io -F -f \ + -c "truncate $file_size" \ + -c "falloc -k 0 $file_size" \ + -c "chattr +d" \ + $SCRATCH_MNT/.use_space 2>&1 > /dev/null + export NUM_SPACE_FILES=1 + status=$? + _scratch_unmount + if [ $status -ne 0 ]; then + echo "large file prealloc failed" + cat $tmp_dir/mnt.err >&2 + return $status + fi + return 0 +} + +_scratch_mkfs_xfs_opts() +{ + mkfs_opts=$* + + # remove metadata related mkfs options if mkfs.xfs doesn't them + if [ -n "$XFS_MKFS_HAS_NO_META_SUPPORT" ]; then + mkfs_opts=`echo $mkfs_opts | sed "s/-m\s\+\S\+//g"` + fi + + _scratch_options mkfs + + $MKFS_XFS_PROG $SCRATCH_OPTIONS $mkfs_opts $SCRATCH_DEV +} + + +_scratch_mkfs_xfs_supported() +{ + local mkfs_opts=$* + + _scratch_options mkfs + + $MKFS_XFS_PROG -N $MKFS_OPTIONS $SCRATCH_OPTIONS $mkfs_opts $SCRATCH_DEV + local mkfs_status=$? + + # a mkfs failure may be caused by conflicts between $MKFS_OPTIONS and + # $mkfs_opts, try again without $MKFS_OPTIONS + if [ $mkfs_status -ne 0 -a -n "$mkfs_opts" ]; then + $MKFS_XFS_PROG -N $SCRATCH_OPTIONS $mkfs_opts $SCRATCH_DEV + mkfs_status=$? + fi + return $mkfs_status +} + +_scratch_mkfs_xfs() +{ + # extra mkfs options can be added by tests + local extra_mkfs_options=$* + + local tmp_dir=/tmp/ + + # save mkfs output in case conflict means we need to run again. + # only the output for the mkfs that applies should be shown + _scratch_mkfs_xfs_opts $MKFS_OPTIONS $extra_mkfs_options \ + 2>$tmp_dir.mkfserr 1>$tmp_dir.mkfsstd + local mkfs_status=$? + + + # a mkfs failure may be caused by conflicts between + # $MKFS_OPTIONS and $extra_mkfs_options + if [ $mkfs_status -ne 0 -a ! -z "$extra_mkfs_options" ]; then + ( + echo -n "** mkfs failed with extra mkfs options " + echo "added to \"$MKFS_OPTIONS\" by test $seq **" + echo -n "** attempting to mkfs using only test $seq " + echo "options: $extra_mkfs_options **" + ) >> $seqres.full + + # running mkfs again. overwrite previous mkfs output files + _scratch_mkfs_xfs_opts $extra_mkfs_options \ + 2>$tmp_dir.mkfserr 1>$tmp_dir.mkfsstd + local mkfs_status=$? + fi + + if [ $mkfs_status -eq 0 -a "$LARGE_SCRATCH_DEV" = yes ]; then + # manually parse the mkfs output to get the fs size in bytes + local fs_size + fs_size=`cat $tmp_dir.mkfsstd | perl -ne ' + if (/^data\s+=\s+bsize=(\d+)\s+blocks=(\d+)/) { + my $size = $1 * $2; + print STDOUT "$size\n"; + }'` + _setup_large_xfs_fs $fs_size + mkfs_status=$? + fi + + # output stored mkfs output, filtering unnecessary warnings from stderr + cat $tmp_dir.mkfsstd + cat $tmp_dir.mkfserr | sed \ + -e '/less than device physical sector/d' \ + -e '/switching to logical sector/d' \ + >&2 + rm -f $tmp_dir.mkfserr $tmp_dir.mkfsstd + + return $mkfs_status +} + +# xfs_check script is planned to be deprecated. But, we want to +# be able to invoke "xfs_check" behavior in xfstests in order to +# maintain the current verification levels. +_xfs_check() +{ + OPTS=" " + DBOPTS=" " + USAGE="Usage: xfs_check [-fsvV] [-l logdev] [-i ino]... [-b bno]... special" + + while getopts "b:fi:l:stvV" c + do + case $c in + s) OPTS=$OPTS"-s ";; + t) OPTS=$OPTS"-t ";; + v) OPTS=$OPTS"-v ";; + i) OPTS=$OPTS"-i "$OPTARG" ";; + b) OPTS=$OPTS"-b "$OPTARG" ";; + f) DBOPTS=$DBOPTS" -f";; + l) DBOPTS=$DBOPTS" -l "$OPTARG" ";; + V) $XFS_DB_PROG -p xfs_check -V + return $? + ;; + esac + done + set -- extra $@ + shift $OPTIND + case $# in + 1) ${XFS_DB_PROG}${DBOPTS} -F -i -p xfs_check -c "check$OPTS" $1 + status=$? + ;; + 2) echo $USAGE 1>&1 + status=2 + ;; + esac + return $status +} + +_scratch_xfs_db_options() +{ + SCRATCH_OPTIONS="" + [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \ + SCRATCH_OPTIONS="-l$SCRATCH_LOGDEV" + echo $SCRATCH_OPTIONS $* $SCRATCH_DEV +} + +_scratch_xfs_db() +{ + $XFS_DB_PROG "$@" $(_scratch_xfs_db_options) +} + +_scratch_xfs_logprint() +{ + SCRATCH_OPTIONS="" + [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \ + SCRATCH_OPTIONS="-l$SCRATCH_LOGDEV" + $XFS_LOGPRINT_PROG $SCRATCH_OPTIONS $* $SCRATCH_DEV +} + +_test_xfs_logprint() +{ + TEST_OPTIONS="" + [ "$USE_EXTERNAL" = yes -a ! -z "$TEST_LOGDEV" ] && \ + TEST_OPTIONS="-l$TEST_LOGDEV" + $XFS_LOGPRINT_PROG $TEST_OPTIONS $* $TEST_DEV +} + +_scratch_xfs_check() +{ + SCRATCH_OPTIONS="" + [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \ + SCRATCH_OPTIONS="-l $SCRATCH_LOGDEV" + [ "$LARGE_SCRATCH_DEV" = yes ] && \ + SCRATCH_OPTIONS=$SCRATCH_OPTIONS" -t" + _xfs_check $SCRATCH_OPTIONS $* $SCRATCH_DEV +} + +_scratch_xfs_repair() +{ + SCRATCH_OPTIONS="" + [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_LOGDEV" ] && \ + SCRATCH_OPTIONS="-l$SCRATCH_LOGDEV" + [ "$USE_EXTERNAL" = yes -a ! -z "$SCRATCH_RTDEV" ] && \ + SCRATCH_OPTIONS=$SCRATCH_OPTIONS" -r$SCRATCH_RTDEV" + [ "$LARGE_SCRATCH_DEV" = yes ] && SCRATCH_OPTIONS=$SCRATCH_OPTIONS" -t" + $XFS_REPAIR_PROG $SCRATCH_OPTIONS $* $SCRATCH_DEV +} + +# this test requires the projid32bit feature to be available in mkfs.xfs. +# +_require_projid32bit() +{ + _scratch_mkfs_xfs_supported -i projid32bit=1 >/dev/null 2>&1 \ + || _notrun "mkfs.xfs doesn't have projid32bit feature" +} + +_require_projid16bit() +{ + _scratch_mkfs_xfs_supported -i projid32bit=0 >/dev/null 2>&1 \ + || _notrun "16 bit project IDs not supported on $SCRATCH_DEV" +} + +# this test requires the crc feature to be available in mkfs.xfs +# +_require_xfs_mkfs_crc() +{ + _scratch_mkfs_xfs_supported -m crc=1 >/dev/null 2>&1 \ + || _notrun "mkfs.xfs doesn't have crc feature" +} + +# this test requires the xfs kernel support crc feature +# +_require_xfs_crc() +{ + _scratch_mkfs_xfs -m crc=1 >/dev/null 2>&1 + _scratch_mount >/dev/null 2>&1 \ + || _notrun "Kernel doesn't support crc feature" + _scratch_unmount +} + +# this test requires the xfs kernel support crc feature on scratch device +# +_require_scratch_xfs_crc() +{ + _scratch_mkfs_xfs >/dev/null 2>&1 + _scratch_mount >/dev/null 2>&1 \ + || _notrun "Kernel doesn't support crc feature" + xfs_info $SCRATCH_MNT | grep -q 'crc=1' || _notrun "crc feature not supported by this filesystem" + _scratch_unmount +} + +# this test requires the finobt feature to be available in mkfs.xfs +# +_require_xfs_mkfs_finobt() +{ + _scratch_mkfs_xfs_supported -m crc=1,finobt=1 >/dev/null 2>&1 \ + || _notrun "mkfs.xfs doesn't have finobt feature" +} + +# this test requires the xfs kernel support finobt feature +# +_require_xfs_finobt() +{ + _scratch_mkfs_xfs -m crc=1,finobt=1 >/dev/null 2>&1 + _scratch_mount >/dev/null 2>&1 \ + || _notrun "Kernel doesn't support finobt feature" + _scratch_unmount +} + +# this test requires xfs sysfs attribute support +# +_require_xfs_sysfs() +{ + attr=$1 + sysfsdir=/sys/fs/xfs + + if [ ! -e $sysfsdir ]; then + _notrun "no kernel support for XFS sysfs attributes" + fi + + if [ ! -z $1 ] && [ ! -e $sysfsdir/$attr ]; then + _notrun "sysfs attribute '$attr' is not supported" + fi +} + +# this test requires the xfs sparse inode feature +# +_require_xfs_sparse_inodes() +{ + _scratch_mkfs_xfs_supported -m crc=1 -i sparse > /dev/null 2>&1 \ + || _notrun "mkfs.xfs does not support sparse inodes" + _scratch_mkfs_xfs -m crc=1 -i sparse > /dev/null 2>&1 + _scratch_mount >/dev/null 2>&1 \ + || _notrun "kernel does not support sparse inodes" + _scratch_unmount +} + +# check that xfs_db supports a specific command +_require_xfs_db_command() +{ + if [ $# -ne 1 ] + then + echo "Usage: _require_xfs_db_command command" 1>&2 + exit 1 + fi + command=$1 + + _scratch_xfs_db -x -c "help" | grep $command > /dev/null || \ + _notrun "xfs_db $command support is missing" +} + +# run xfs_check and friends on a FS. +_check_xfs_filesystem() +{ + if [ $# -ne 3 ] + then + echo "Usage: _check_xfs_filesystem device <logdev>|none <rtdev>|none" 1>&2 + exit 1 + fi + + extra_mount_options="" + extra_log_options="" + extra_options="" + device=$1 + if [ -f $device ];then + extra_options="-f" + fi + + if [ "$2" != "none" ]; then + extra_log_options="-l$2" + extra_mount_options="-ologdev=$2" + fi + + if [ "$3" != "none" ]; then + extra_rt_options="-r$3" + extra_mount_options=$extra_mount_options" -ortdev=$3" + fi + extra_mount_options=$extra_mount_options" $MOUNT_OPTIONS" + + [ "$FSTYP" != xfs ] && return 0 + + type=`_fs_type $device` + ok=1 + + if [ "$type" = "xfs" ] + then + if [ -n "$TEST_XFS_SCRUB" ] && [ -x "$XFS_SCRUB_PROG" ]; then + "$XFS_SCRUB_PROG" $scrubflag -vd $device >>$seqres.full + if [ $? -ne 0 ]; then + echo "filesystem on $device failed scrub (see $seqres.full)" + ok=0 + fi + fi + # mounted ... + mountpoint=`_umount_or_remount_ro $device` + fi + + $XFS_LOGPRINT_PROG -t $extra_log_options $device 2>&1 \ + | tee $tmp.logprint | grep -q "<CLEAN>" + if [ $? -ne 0 -a "$HOSTOS" = "Linux" ] + then + echo "_check_xfs_filesystem: filesystem on $device has dirty log (see $seqres.full)" + + echo "_check_xfs_filesystem: filesystem on $device has dirty log" >>$seqres.full + echo "*** xfs_logprint -t output ***" >>$seqres.full + cat $tmp.logprint >>$seqres.full + echo "*** end xfs_logprint output" >>$seqres.full + + ok=0 + fi + + # xfs_check runs out of memory on large files, so even providing the test + # option (-t) to avoid indexing the free space trees doesn't make it pass on + # large filesystems. Avoid it. + if [ "$LARGE_SCRATCH_DEV" != yes ]; then + _xfs_check $extra_log_options $device 2>&1 |\ + _fix_malloc >$tmp.fs_check + fi + if [ -s $tmp.fs_check ] + then + echo "_check_xfs_filesystem: filesystem on $device is inconsistent (c) (see $seqres.full)" + + echo "_check_xfs_filesystem: filesystem on $device is inconsistent" >>$seqres.full + echo "*** xfs_check output ***" >>$seqres.full + cat $tmp.fs_check >>$seqres.full + echo "*** end xfs_check output" >>$seqres.full + + ok=0 + fi + + $XFS_REPAIR_PROG -n $extra_options $extra_log_options $extra_rt_options $device >$tmp.repair 2>&1 + if [ $? -ne 0 ] + then + echo "_check_xfs_filesystem: filesystem on $device is inconsistent (r) (see $seqres.full)" + + echo "_check_xfs_filesystem: filesystem on $device is inconsistent" >>$seqres.full + echo "*** xfs_repair -n output ***" >>$seqres.full + cat $tmp.repair | _fix_malloc >>$seqres.full + echo "*** end xfs_repair output" >>$seqres.full + + ok=0 + fi + rm -f $tmp.fs_check $tmp.logprint $tmp.repair + + # Optionally test the index rebuilding behavior. + if [ -n "$TEST_XFS_REPAIR_REBUILD" ]; then + $XFS_REPAIR_PROG $extra_options $extra_log_options $extra_rt_options $device >$tmp.repair 2>&1 + if [ $? -ne 0 ]; then + echo "_check_xfs_filesystem: filesystem on $device is inconsistent (rebuild) (see $seqres.full)" + + echo "_check_xfs_filesystem: filesystem on $device is inconsistent (rebuild)" >>$seqres.full + echo "*** xfs_repair output ***" >>$seqres.full + cat $tmp.repair | _fix_malloc >>$seqres.full + echo "*** end xfs_repair output" >>$seqres.full + + ok=0 + fi + rm -f $tmp.repair + + $XFS_REPAIR_PROG -n $extra_options $extra_log_options $extra_rt_options $device >$tmp.repair 2>&1 + if [ $? -ne 0 ]; then + echo "_check_xfs_filesystem: filesystem on $device is inconsistent (rebuild-reverify) (see $seqres.full)" + + echo "_check_xfs_filesystem: filesystem on $device is inconsistent (rebuild-reverify)" >>$seqres.full + echo "*** xfs_repair -n output ***" >>$seqres.full + cat $tmp.repair | _fix_malloc >>$seqres.full + echo "*** end xfs_repair output" >>$seqres.full + + ok=0 + fi + rm -f $tmp.repair + fi + + if [ $ok -eq 0 ] + then + echo "*** mount output ***" >>$seqres.full + _mount >>$seqres.full + echo "*** end mount output" >>$seqres.full + elif [ "$type" = "xfs" ] + then + _mount_or_remount_rw "$extra_mount_options" $device $mountpoint + fi + + if [ $ok -eq 0 ]; then + status=1 + if [ "$iam" != "check" ]; then + exit 1 + fi + return 1 + fi + + return 0 +} + +_check_xfs_test_fs() +{ + TEST_LOG="none" + TEST_RT="none" + [ "$USE_EXTERNAL" = yes -a ! -z "$TEST_LOGDEV" ] && \ + TEST_LOG="$TEST_LOGDEV" + + [ "$USE_EXTERNAL" = yes -a ! -z "$TEST_RTDEV" ] && \ + TEST_RT="$TEST_RTDEV" + + _check_xfs_filesystem $TEST_DEV $TEST_LOG $TEST_RT + + # check for ipath consistency + if $XFS_GROWFS_PROG -n $TEST_DIR | grep -q 'inode-paths=1'; then + # errors go to stderr + xfs_check_ipaths $TEST_DIR >/dev/null + xfs_repair_ipaths -n $TEST_DIR >/dev/null + fi +} + +_require_xfs_test_rmapbt() +{ + _require_test + + if [ "$(xfs_info "$TEST_DIR" | grep -c "rmapbt=1")" -ne 1 ]; then + _notrun "rmapbt not supported by test filesystem type: $FSTYP" + fi +} + +_require_xfs_scratch_rmapbt() +{ + _require_scratch + + _scratch_mkfs > /dev/null + _scratch_mount + if [ "$(xfs_info "$SCRATCH_MNT" | grep -c "rmapbt=1")" -ne 1 ]; then + _scratch_unmount + _notrun "rmapbt not supported by scratch filesystem type: $FSTYP" + fi + _scratch_unmount +} + +_xfs_bmapx_find() { + case "$1" in + "attr") + param="a" + ;; + "cow") + param="c" + ;; + *) + param="e" + ;; + esac + shift + file="$1" + shift + + $XFS_IO_PROG -c "bmap -${param}lpv" "$file" | grep -c "$@" +} + +# Reset all xfs error handling attributes, set them to original +# status. +# +# Only one argument, and it's mandatory: +# - dev: device name, e.g. $SCRATCH_DEV +# +# Note: this function only works for XFS +_reset_xfs_sysfs_error_handling() +{ + local dev=$1 + + if [ ! -b "$dev" -o "$FSTYP" != "xfs" ];then + _fail "Usage: reset_xfs_sysfs_error_handling <device>" + fi + + _set_fs_sysfs_attr $dev error/fail_at_unmount 1 + echo -n "error/fail_at_unmount=" + _get_fs_sysfs_attr $dev error/fail_at_unmount + + # Make sure all will be configured to retry forever by default, except + # for ENODEV, which is an unrecoverable error, so it will be configured + # to not retry on error by default. + for e in default EIO ENOSPC; do + _set_fs_sysfs_attr $dev \ + error/metadata/${e}/max_retries -1 + echo -n "error/metadata/${e}/max_retries=" + _get_fs_sysfs_attr $dev error/metadata/${e}/max_retries + + _set_fs_sysfs_attr $dev \ + error/metadata/${e}/retry_timeout_seconds 0 + echo -n "error/metadata/${e}/retry_timeout_seconds=" + _get_fs_sysfs_attr $dev \ + error/metadata/${e}/retry_timeout_seconds + done +} + +# Skip if we are running an older binary without the stricter input checks. +# Make multiple checks to be sure that there is no regression on the one +# selected feature check, which would skew the result. +# +# At first, make a common function that runs the tests and returns +# number of failed cases. +_xfs_mkfs_validation_check() +{ + local tmpfile=`mktemp` + local cmd="$MKFS_XFS_PROG -f -N -d file,name=$tmpfile,size=1g" + + $cmd -s size=2s >/dev/null 2>&1 + local sum=$? + + $cmd -l version=2,su=260k >/dev/null 2>&1 + sum=`expr $sum + $?` + + rm -f $tmpfile + return $sum +} + +# Skip the test if all calls passed - mkfs accepts invalid input +_require_xfs_mkfs_validation() +{ + _xfs_mkfs_validation_check + if [ "$?" -eq 0 ]; then + _notrun "Requires newer mkfs with stricter input checks: the oldest supported version of xfsprogs is 4.7." + fi +} + +# The opposite of _require_xfs_mkfs_validation. +_require_xfs_mkfs_without_validation() +{ + _xfs_mkfs_validation_check + if [ "$?" -ne 0 ]; then + _notrun "Requires older mkfs without strict input checks: the last supported version of xfsprogs is 4.5." + fi +} + +# XFS ability to change UUIDs on V5/CRC filesystems +# +_require_meta_uuid() +{ + # This will create a crc fs on $SCRATCH_DEV + _require_xfs_crc + + _scratch_xfs_db -x -c "uuid restore" 2>&1 \ + | grep -q "invalid UUID\|supported on V5 fs" \ + && _notrun "Userspace doesn't support meta_uuid feature" + + _scratch_xfs_db -x -c "uuid generate" >/dev/null 2>&1 + + _scratch_mount >/dev/null 2>&1 \ + || _notrun "Kernel doesn't support meta_uuid feature" + _scratch_unmount +}