xfstests: support post-udev device mapper nodes
[xfstests-dev.git] / common.rc
index 7354357884dd61d970a43bae6af93d7b7a334a95..e634fbb359392808ffb25888504742b3a1f46655 100644 (file)
--- a/common.rc
+++ b/common.rc
@@ -1,4 +1,4 @@
-##/bin/sh
+##/bin/bash
 #-----------------------------------------------------------------------
 #  Copyright (c) 2000-2006 Silicon Graphics, Inc.  All Rights Reserved.
 #  This program is free software; you can redistribute it and/or modify
@@ -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)
@@ -91,9 +107,25 @@ _mkfs_opts()
     esac
 }
 
+_fsck_opts()
+{
+    case $FSTYP in
+    ext2|ext3|ext4)
+       export FSCK_OPTIONS="-nf"
+       ;;
+    reiserfs)
+       export FSCK_OPTIONS="--yes"
+       ;;
+    *)
+       export FSCK_OPTIONS="-n"
+       ;;
+    esac
+}
+
 [ -z "$FSTYP" ] && FSTYP=xfs
 [ -z "$MOUNT_OPTIONS" ] && _mount_opts
 [ -z "$MKFS_OPTIONS" ] && _mkfs_opts
+[ -z "$FSCK_OPTIONS" ] && _fsck_opts
 
 
 # we need common.config
@@ -190,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()
@@ -198,10 +230,21 @@ _scratch_mount()
     _mount -t $FSTYP `_scratch_mount_options $*`
 }
 
+_scratch_unmount()
+{
+    $UMOUNT_PROG $SCRATCH_DEV
+}
+
+_scratch_remount()
+{
+    _scratch_unmount
+    _scratch_mount
+}
+
 _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()
@@ -265,11 +308,73 @@ _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()
 {
     SCRATCH_OPTIONS=""
@@ -330,14 +435,6 @@ _get_pids_by_name()
        -e "/[0-9]:[0-9][0-9]  *$1 /s/ .*//p"
 }
 
-# fqdn for localhost
-#
-_get_fqdn()
-{
-    host=`hostname`
-    $NSLOOKUP_PROG $host | $AWK_PROG '{ if ($1 == "Name:") print $2 }'
-}
-
 # fix malloc libs output
 #
 _fix_malloc()
@@ -490,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
@@ -609,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
 
@@ -681,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
@@ -695,12 +805,38 @@ _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."
 }
 
@@ -708,14 +844,72 @@ _require_user()
 # 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
+{
+       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
 #
@@ -832,7 +1026,7 @@ _check_generic_filesystem()
         mountpoint=`_umount_or_remount_ro $device`
     fi
 
-    fsck -t $FSTYP -n $device >$tmp.fsck 2>&1
+    fsck -t $FSTYP $FSCK_OPTIONS $device >$tmp.fsck 2>&1
     if [ $? -ne 0 ]
     then
         echo "_check_generic_filesystem: filesystem on $device is inconsistent (see $seq.full)"
@@ -858,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
 }
 
@@ -951,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
 }