common/fuzzy: if the fuzz verb is random, keep fuzzing until we get a new value
[xfstests-dev.git] / common / xfs
index 53cd4de78d64d503cc3385c491fd7c395a938244..799a545de72523f1e3c9b8d55972062eccc6228c 100644 (file)
@@ -55,7 +55,7 @@ _scratch_mkfs_xfs_opts()
 
        _scratch_options mkfs
 
-       $MKFS_XFS_PROG $SCRATCH_OPTIONS $mkfs_opts $SCRATCH_DEV
+       echo "$MKFS_XFS_PROG $SCRATCH_OPTIONS $mkfs_opts"
 }
 
 
@@ -79,38 +79,21 @@ _scratch_mkfs_xfs_supported()
 
 _scratch_mkfs_xfs()
 {
-       # extra mkfs options can be added by tests
-       local extra_mkfs_options=$*
+       local mkfs_cmd="`_scratch_mkfs_xfs_opts`"
+       local mkfs_filter="sed -e '/less than device physical sector/d' \
+                              -e '/switching to logical sector/d' \
+                              -e '/Default configuration/d'"
+       local tmp=`mktemp -u`
+       local mkfs_status
 
-       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=$?
+       _scratch_do_mkfs "$mkfs_cmd" "$mkfs_filter" $* 2>$tmp.mkfserr 1>$tmp.mkfsstd
+       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 '
+               fs_size=`cat $tmp.mkfsstd | perl -ne '
                        if (/^data\s+=\s+bsize=(\d+)\s+blocks=(\d+)/) {
                                my $size = $1 * $2;
                                print STDOUT "$size\n";
@@ -119,13 +102,10 @@ _scratch_mkfs_xfs()
                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
+       # output mkfs stdout and stderr
+       cat $tmp.mkfsstd
+       cat $tmp.mkfserr >&2
+       rm -f $tmp.mkfserr $tmp.mkfsstd
 
        return $mkfs_status
 }
@@ -318,6 +298,30 @@ _require_xfs_db_command()
                _notrun "xfs_db $command support is missing"
 }
 
+# Does the filesystem mounted from a particular device support scrub?
+_supports_xfs_scrub()
+{
+       local mountpoint="$1"
+       local device="$2"
+
+       if [ ! -b "$device" ] || [ ! -e "$mountpoint" ]; then
+               echo "Usage: _supports_xfs_scrub mountpoint device"
+               exit 1
+       fi
+
+       test "$FSTYP" = "xfs" || return 1
+       test -x "$XFS_SCRUB_PROG" || return 1
+
+       # Probe for kernel support...
+       $XFS_IO_PROG -c 'help scrub' 2>&1 | grep -q 'types are:.*probe' || return 1
+       $XFS_IO_PROG -c "scrub probe 0" "$mountpoint" 2>&1 | grep -q "Inappropriate ioctl" && return 1
+
+       # Scrub can't run on norecovery mounts
+       _fs_options "$device" | grep -q "norecovery" && return 1
+
+       return 0
+}
+
 # run xfs_check and friends on a FS.
 _check_xfs_filesystem()
 {
@@ -350,14 +354,21 @@ _check_xfs_filesystem()
        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
+       # Run online scrub if we can.
+       mntpt="$(_is_mounted $device)"
+       if [ -n "$mntpt" ] && _supports_xfs_scrub "$mntpt" "$device"; then
+               "$XFS_SCRUB_PROG" $scrubflag -v -d -n $device > $tmp.scrub 2>&1
+               if [ $? -ne 0 ]; then
+                       _log_err "_check_xfs_filesystem: filesystem on $device failed scrub"
+                       echo "*** xfs_scrub $scrubflag -v -d -n output ***" >> $seqres.full
+                       cat $tmp.scrub >> $seqres.full
+                       echo "*** end xfs_scrub output" >> $serqres.full
+                       ok=0
                fi
+               rm -f $tmp.scrub
+       fi
+
+       if [ "$type" = "xfs" ]; then
                # mounted ...
                mountpoint=`_umount_or_remount_ro $device`
        fi
@@ -365,9 +376,7 @@ _check_xfs_filesystem()
        $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
+               _log_err "_check_xfs_filesystem: filesystem on $device has dirty log"
                echo "*** xfs_logprint -t output ***"   >>$seqres.full
                cat $tmp.logprint                       >>$seqres.full
                echo "*** end xfs_logprint output"      >>$seqres.full
@@ -383,9 +392,7 @@ _check_xfs_filesystem()
                        _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
+               _log_err "_check_xfs_filesystem: filesystem on $device is inconsistent (c)"
                echo "*** xfs_check output ***"         >>$seqres.full
                cat $tmp.fs_check                       >>$seqres.full
                echo "*** end xfs_check output"         >>$seqres.full
@@ -395,9 +402,7 @@ _check_xfs_filesystem()
 
        $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
+               _log_err "_check_xfs_filesystem: filesystem on $device is inconsistent (r)"
                echo "*** xfs_repair -n output ***"     >>$seqres.full
                cat $tmp.repair | _fix_malloc           >>$seqres.full
                echo "*** end xfs_repair output"        >>$seqres.full
@@ -410,9 +415,7 @@ _check_xfs_filesystem()
        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
+                       _log_err "_check_xfs_filesystem: filesystem on $device is inconsistent (rebuild)"
                        echo "*** xfs_repair output ***"        >>$seqres.full
                        cat $tmp.repair | _fix_malloc           >>$seqres.full
                        echo "*** end xfs_repair output"        >>$seqres.full
@@ -423,9 +426,7 @@ _check_xfs_filesystem()
 
                $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
+                       _log_err "_check_xfs_filesystem: filesystem on $device is inconsistent (rebuild-reverify)"
                        echo "*** xfs_repair -n output ***"     >>$seqres.full
                        cat $tmp.repair | _fix_malloc           >>$seqres.full
                        echo "*** end xfs_repair output"        >>$seqres.full
@@ -465,13 +466,7 @@ _check_xfs_test_fs()
                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
+       return $?
 }
 
 _require_xfs_test_rmapbt()
@@ -563,7 +558,7 @@ _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
+       $cmd -s size=8s >/dev/null 2>&1
        local sum=$?
 
        $cmd -l version=2,su=260k >/dev/null 2>&1
@@ -608,3 +603,24 @@ _require_meta_uuid()
           || _notrun "Kernel doesn't support meta_uuid feature"
        _scratch_unmount
 }
+
+# this test requires mkfs.xfs have case-insensitive naming support
+_require_xfs_mkfs_ciname()
+{
+       _scratch_mkfs_xfs_supported -n version=ci >/dev/null 2>&1 \
+               || _notrun "need case-insensitive naming support in mkfs.xfs"
+}
+
+# XFS_DEBUG requirements
+_require_xfs_debug()
+{
+       if grep -q "debug 0" /proc/fs/xfs/stat; then
+               _notrun "Require XFS built with CONFIG_XFS_DEBUG"
+       fi
+}
+_require_no_xfs_debug()
+{
+       if grep -q "debug 1" /proc/fs/xfs/stat; then
+               _notrun "Require XFS built without CONFIG_XFS_DEBUG"
+       fi
+}