xfstests: support post-udev device mapper nodes
[xfstests-dev.git] / common.rc
index 642487102b8ae5a50d0ccbf366dd4658d9a5b049..e634fbb359392808ffb25888504742b3a1f46655 100644 (file)
--- a/common.rc
+++ b/common.rc
@@ -37,10 +37,26 @@ dd()
    fi
 }
 
+# ls -l w/ selinux sometimes puts a dot at the end:
+# -rwxrw-r--. id1 id2 file1
+
+_ls_l()
+{
+       ls -l $* | sed "s/\(^[-rwxdlbcpsStT]*\)\. /\1 /"
+}
+
 _mount_opts()
 {
+    # SELinux adds extra xattrs which can mess up our expected output.
+    # So, mount with a context, and they won't be created
+    # nfs_t is a "liberal" context so we can use it.
+    if [ -x /usr/sbin/selinuxenabled ] && /usr/sbin/selinuxenabled; then
+       SELINUX_MOUNT_OPTIONS="-o context=system_u:object_r:nfs_t:s0"
+    fi
+
     case $FSTYP in
     xfs)
+       export SELINUX_MOUNT_OPTIONS
        export MOUNT_OPTIONS=$XFS_MOUNT_OPTIONS
        ;;
     udf)
@@ -206,7 +222,7 @@ _scratch_mount_options()
 {
     _scratch_options mount
 
-    echo $SCRATCH_OPTIONS $MOUNT_OPTIONS $* $SCRATCH_DEV $SCRATCH_MNT
+    echo $SCRATCH_OPTIONS $MOUNT_OPTIONS $SELINUX_MOUNT_OPTIONS $* $SCRATCH_DEV $SCRATCH_MNT
 }
 
 _scratch_mount()
@@ -228,7 +244,7 @@ _scratch_remount()
 _test_mount()
 {
     _test_options mount
-    _mount -t $FSTYP $TEST_OPTIONS $TEST_FS_MOUNT_OPTS $* $TEST_DEV $TEST_DIR
+    _mount -t $FSTYP $TEST_OPTIONS $TEST_FS_MOUNT_OPTS $SELINUX_MOUNT_OPTIONS $* $TEST_DEV $TEST_DIR
 }
 
 _scratch_mkfs_options()
@@ -292,9 +308,71 @@ _scratch_mkfs()
         $MKFS_UDF_PROG $MKFS_OPTIONS $* $SCRATCH_DEV > /dev/null
        ;;
     *)
-       /sbin/mkfs -t $FSTYP -- $MKFS_OPTIONS $* $SCRATCH_DEV > /dev/null
+       /sbin/mkfs -t $FSTYP -- $MKFS_OPTIONS $* $SCRATCH_DEV
+       ;;
+    esac
+}
+
+# Create fs of certain size on scratch device
+# _scratch_mkfs_sized <size in bytes> [optional blocksize]
+_scratch_mkfs_sized()
+{
+    fssize=$1
+    blocksize=$2
+    [ -z "$blocksize" ] && blocksize=4096
+    blocks=`expr $fssize / $blocksize`
+
+    case $FSTYP in
+    xfs)
+       _scratch_mkfs_xfs -d size=$fssize -b size=$blocksize
+       ;;
+    ext2|ext3|ext4)
+       /sbin/mkfs.$FSTYP $MKFS_OPTIONS -b $blocksize $SCRATCH_DEV $blocks
+       ;;
+     btrfs)
+       /sbin/mkfs.$FSTYP $MKFS_OPTIONS $SCRATCH_DEV -b $fssize
+       ;;
+    *)
+       _notrun "Filesystem $FSTYP not supported in _scratch_mkfs_sized"
+       ;;
+    esac
+}
+
+# Emulate an N-data-disk stripe w/ various stripe units
+# _scratch_mkfs_geom <sunit bytes> <swidth multiplier> [optional blocksize]
+_scratch_mkfs_geom()
+{
+    sunit_bytes=$1
+    swidth_mult=$2
+    blocksize=$3
+    [ -z "$blocksize" ] && blocksize=4096
+
+    let sunit_blocks=$sunit_bytes/$blocksize
+    let swidth_blocks=$sunit_blocks*$swidth_mult
+
+    case $FSTYP in
+    xfs)
+       MKFS_OPTIONS+=" -b size=$blocksize, -d su=$sunit_bytes,sw=$swidth_mult"
+       ;;
+    ext4)
+       MKFS_OPTIONS+=" -b $blocksize -E stride=$sunit_blocks,stripe_width=$swidth_blocks"
+       ;;
+    *)
+       _notrun "can't mkfs $FSTYP with geometry"
        ;;
     esac
+    _scratch_mkfs
+}
+
+_scratch_resvblks()
+{
+       case $FSTYP in
+       xfs)
+               xfs_io -x -c "resblks $1" $SCRATCH_MNT
+               ;;
+       *)
+               ;;
+       esac
 }
 
 _scratch_xfs_db_options()
@@ -509,7 +587,14 @@ _is_block_dev()
        exit 1
     fi
 
-    [ -b $1 ] && src/lstat64 $1 | $AWK_PROG '/Device type:/ { print $9 }'
+    _dev=$1
+    if [ -L "${_dev}" ]; then
+        _dev=`readlink -f ${_dev}`
+    fi
+
+    if [ -b "${_dev}" ]; then
+        src/lstat64 ${_dev} | $AWK_PROG '/Device type:/ { print $9 }'
+    fi
 }
 
 # Do a command, log it to $seq.full, optionally test return status
@@ -628,6 +713,10 @@ _require_scratch()
                 then
                     _notrun "this test requires a valid \$SCRATCH_DEV"
                 fi
+               if [ ! -d "$SCRATCH_MNT" ]
+               then
+                    _notrun "this test requires a valid \$SCRATCH_MNT"
+               fi
                 ;;
     esac
 
@@ -700,10 +789,12 @@ _require_realtime()
 }
 
 # this test requires that a specified command (executable) exists
+# $1 - command, $2 - name for error message
 #
 _require_command()
 {
-    [ -x "$1" ] || _notrun "$1 utility required, skipped this test"
+    [ -n "$1" ] && _cmd="$1" || _cmd="$2"
+    [ -n "$1" -a -x "$1" ] || _notrun "$_cmd utility required, skipped this test"
 }
 
 # this test requires that external log/realtime devices are not in use
@@ -714,27 +805,111 @@ _require_nonexternal()
        _notrun "External device testing in progress, skipped this test"
 }
 
+# indicate whether YP/NIS is active or not
+#
+_yp_active()
+{
+       local dn
+       dn=$(domainname 2>/dev/null)
+       test -n "${dn}" -a "${dn}" != "(none)"
+       echo $?
+}
+
+# cat the password file
+#
+_cat_passwd()
+{
+       [ $(_yp_active) -eq 0 ] && ypcat passwd
+       cat /etc/passwd
+}
+
+# cat the group file
+#
+_cat_group()
+{
+       [ $(_yp_active) -eq 0 ] && ypcat group
+       cat /etc/group
+}
+
 # check for the fsgqa user on the machine
 #
 _require_user()
 {
     qa_user=fsgqa
-    cat /etc/passwd | grep -q $qa_user
+    _cat_passwd | grep -q $qa_user
     [ "$?" == "0" ] || _notrun "$qa_user user not defined."
 }
 
 # check that xfs_io, glibc, kernel, and filesystem all (!) support
 # fallocate
 #
-_require_xfs_io_falloc() {
-       testio=`$XFS_IO_PROG -F -f -c "falloc 0 1m" $TEST_DIR/$tmp.io 2>&1`
-       rm -f $TEST_DIR/$tmp.io 2>&1 > /dev/null
+_require_xfs_io_falloc()
+{
+       testfile=$TEST_DIR/$$.falloc
+       testio=`$XFS_IO_PROG -F -f -c "falloc 0 1m" $testfile 2>&1`
+       rm -f $testfile 2>&1 > /dev/null
        echo $testio | grep -q "not found" && \
                _notrun "xfs_io fallocate support is missing"
        echo $testio | grep -q "Operation not supported" && \
                _notrun "xfs_io fallocate command failed (old kernel/wrong fs?)"
 }
 
+# check that xfs_io, kernel and filesystem all support fallocate with hole
+# punching
+_require_xfs_io_falloc_punch()
+{
+       testfile=$TEST_DIR/$$.falloc
+       testio=`$XFS_IO_PROG -F -f -c "pwrite 0 20k" -c "fsync" \
+               -c "fpunch 4k 8k" $testfile 2>&1`
+       rm -f $testfile 2>&1 > /dev/null
+       echo $testio | grep -q "not found" && \
+               _notrun "xfs_io fallocate punch support is missing"
+       echo $testio | grep -q "Operation not supported" && \
+               _notrun "xfs_io fallocate punch command failed (no fs support?)"
+}
+
+# check that xfs_io, kernel and filesystem support fiemap
+_require_xfs_io_fiemap()
+{
+       testfile=$TEST_DIR/$$.fiemap
+       testio=`$XFS_IO_PROG -F -f -c "pwrite 0 20k" -c "fsync" \
+               -c "fiemap -v" $testfile 2>&1`
+       rm -f $testfile 2>&1 > /dev/null
+       echo $testio | grep -q "not found" && \
+               _notrun "xfs_io fiemap support is missing"
+       echo $testio | grep -q "Operation not supported" && \
+               _notrun "xfs_io fiemap command failed (no fs support?)"
+}
+
+# Check that a fs has enough free space (in 1024b blocks)
+#
+_require_fs_space()
+{
+       MNT=$1
+       BLOCKS=$2       # in units of 1024
+       let GB=$BLOCKS/1024/1024
+
+       FREE_BLOCKS=`df -klP $MNT | grep -v Filesystem | awk '{print $4}'`
+       [ $FREE_BLOCKS -lt $BLOCKS ] && \
+               _notrun "This test requires at least ${GB}GB free on $MNT to run"
+}
+
+#
+# Check if the filesystem supports sparse files.
+#
+# Unfortunately there is no better way to do this than a manual black list.
+#
+_require_sparse_files()
+{
+    case $FSTYP in
+    hfsplus)
+        _notrun "Sparse files not supported by this filesystem type: $FSTYP"
+       ;;
+    *)
+        ;;
+    esac
+}
+
 # check that a FS on a device is mounted
 # if so, return mount point
 #
@@ -877,7 +1052,11 @@ _check_generic_filesystem()
        ok=$?
     fi
 
-    [ $ok -eq 0 ] && exit 1
+    if [ $ok -eq 0 ]; then
+       status=1
+       exit 1
+    fi
+
     return 0
 }
 
@@ -970,7 +1149,11 @@ _check_xfs_filesystem()
        _mount_or_remount_rw "$extra_mount_options" $device $mountpoint
     fi
 
-    [ $ok -eq 0 ] && exit 1
+    if [ $ok -eq 0 ]; then
+       status=1
+       exit 1
+    fi
+
     return 0
 }