##/bin/bash # # Copyright (c) 2000-2003,2006 Silicon Graphics, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it would be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write the Free Software Foundation, # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # # # setup and check for config parameters, and in particular # # EMAIL - email of the script runner. # TEST_DIR - scratch test directory that is in an already # mounted XFS file system, needs to be be world # writeable # TEST_DEV - device for file system containing TEST_DIR # # and optionally: # SCRATCH_DEV - device you can make a scratch file system on # SCRATCH_MNT - mount point for scratch file system # SCRATCH_LOGDEV - scratch log device for external log testing # SCRATCH_RTDEV - scratch rt dev # TEST_LOGDEV - test log device for external log testing # TEST_RTDEV - test rt dev # TAPE_DEV - the tape device for the xfsdump tests # RMT_TAPE_DEV - the remote tape device for the xfsdump tests # RMT_IRIXTAPE_DEV- the IRIX remote tape device for the xfsdump tests # RMT_TAPE_USER - remote user for tape device # # - These can be added to $HOST_CONFIG_DIR (witch default to ./config) # below or a separate local configuration file can be used (using # the HOST_OPTIONS variable). # - This script is shared by the stress test system and the auto-qa # system # - TEST_DEV & TEST_DIR must be assigned. # - this script shouldn't make any assertions about filesystem # validity or mountedness. # # all tests should use a common language setting to prevent golden # output mismatches. export LANG=C export LC_ALL=C # Warning: don't put freeware before /usr/bsd on IRIX coz you'll # get the wrong hostname and set your system name to -s :) [ -d /usr/bsd ] && PATH=$PATH:/usr/bsd [ -d /usr/freeware/bin ] && PATH=$PATH:/usr/freeware/bin PATH=".:$PATH" export HOST=`hostname -s` export HOSTOS=`uname -s` [ "$HOSTOS" = "IRIX64" ] && export HOSTOS="IRIX" export MODULAR=0 # using XFS as a module or not export BOOT="/boot" # install target for kernels export EXTRA=${EXTRA:=xfs-qa} # general parameters (mainly for auto-qa) export SOAK_PROC=3 # -p option to fsstress export SOAK_STRESS=10000 # -n option to fsstress export SOAK_PASSES=-1 # count of repetitions of fsstress (while soaking) export EMAIL=root@localhost # where auto-qa will send its status messages export HOST_OPTIONS=${HOST_OPTIONS:=local.config} export CHECK_OPTIONS=${CHECK_OPTIONS:="-g auto"} export BENCH_PASSES=${BENCH_PASSES:=5} export XFS_MKFS_OPTIONS=${XFS_MKFS_OPTIONS:=-bsize=4096} export TIME_FACTOR=${TIME_FACTOR:=1} export LOAD_FACTOR=${LOAD_FACTOR:=1} export DEBUGFS_MNT=${DEBUGFS_MNT:="/sys/kernel/debug"} export OVERLAY_UPPER_DIR=${OVERLAY_UPPER_DIR:="upper"} export OVERLAY_LOWER_DIR=${OVERLAY_LOWER_DIR:="lower"} export OVERLAY_WORK_DIR=${OVERLAY_WORK_DIR:="work"} export PWD=`pwd` #export DEBUG=${DEBUG:=...} # arbitrary CFLAGS really. export MALLOCLIB=${MALLOCLIB:=/usr/lib/libefence.a} export LOCAL_CONFIGURE_OPTIONS=${LOCAL_CONFIGURE_OPTIONS:=--enable-readline=yes} export RECREATE_TEST_DEV=false # $1 = prog to look for, $2* = default pathnames if not found in $PATH set_prog_path() { p=`which $1 2> /dev/null` if [ -n "$p" -a -x "$p" ]; then echo $p return 0 fi p=$1 shift for f; do if [ -x $f ]; then echo $f return 0 fi done echo "" return 1 } # Handle mkfs.btrfs which does (or does not) require -f to overwrite set_btrfs_mkfs_prog_path_with_opts() { p=`set_prog_path mkfs.btrfs` if [ "$p" != "" ] && grep -q 'force overwrite' $p; then echo "$p -f" else echo $p fi } _fatal() { echo "$*" status=1 exit 1 } export MKFS_PROG="`set_prog_path mkfs`" [ "$MKFS_PROG" = "" ] && _fatal "mkfs not found" export MOUNT_PROG="`set_prog_path mount`" [ "$MOUNT_PROG" = "" ] && _fatal "mount not found" export UMOUNT_PROG="`set_prog_path umount`" [ "$UMOUNT_PROG" = "" ] && _fatal "umount not found" export FSSTRESS_PROG="./ltp/fsstress" [ ! -x $FSSTRESS_PROG ] && _fatal "fsstress not found or executable" export PERL_PROG="`set_prog_path perl`" [ "$PERL_PROG" = "" ] && _fatal "perl not found" export AWK_PROG="`set_prog_path awk`" [ "$AWK_PROG" = "" ] && _fatal "awk not found" export SED_PROG="`set_prog_path sed`" [ "$SED_PROG" = "" ] && _fatal "sed not found" export BC_PROG="`set_prog_path bc`" [ "$BC_PROG" = "" ] && _fatal "bc not found" export PS_ALL_FLAGS="-ef" export DF_PROG="`set_prog_path df`" [ "$DF_PROG" = "" ] && _fatal "df not found" [ "$HOSTOS" = "Linux" ] && export DF_PROG="$DF_PROG -T -P" export XFS_LOGPRINT_PROG="`set_prog_path xfs_logprint`" export XFS_REPAIR_PROG="`set_prog_path xfs_repair`" export XFS_DB_PROG="`set_prog_path xfs_db`" export XFS_GROWFS_PROG=`set_prog_path xfs_growfs` export XFS_IO_PROG="`set_prog_path xfs_io`" export XFS_SCRUB_PROG="`set_prog_path xfs_scrub`" export XFS_PARALLEL_REPAIR_PROG="`set_prog_path xfs_prepair`" export XFS_PARALLEL_REPAIR64_PROG="`set_prog_path xfs_prepair64`" export __XFSDUMP_PROG="`set_prog_path xfsdump`" if [ -n "$__XFSDUMP_PROG" ]; then export XFSDUMP_PROG="$__XFSDUMP_PROG -e" else export XFSDUMP_PROG="" fi export XFSRESTORE_PROG="`set_prog_path xfsrestore`" export XFSINVUTIL_PROG="`set_prog_path xfsinvutil`" export GETFATTR_PROG="`set_prog_path getfattr`" export SETFATTR_PROG="`set_prog_path setfattr`" export CHACL_PROG="`set_prog_path chacl`" export ATTR_PROG="`set_prog_path attr`" export QUOTA_PROG="`set_prog_path quota`" export XFS_QUOTA_PROG="`set_prog_path xfs_quota`" export KILLALL_PROG="`set_prog_path killall`" export INDENT_PROG="`set_prog_path indent`" export XFS_COPY_PROG="`set_prog_path xfs_copy`" export FSTRIM_PROG="`set_prog_path fstrim`" export DUMPE2FS_PROG="`set_prog_path dumpe2fs`" export FIO_PROG="`set_prog_path fio`" export FILEFRAG_PROG="`set_prog_path filefrag`" export E4DEFRAG_PROG="`set_prog_path e4defrag`" export LOGGER_PROG="`set_prog_path logger`" export DBENCH_PROG="`set_prog_path dbench`" export DMSETUP_PROG="`set_prog_path dmsetup`" export WIPEFS_PROG="`set_prog_path wipefs`" export DUMP_PROG="`set_prog_path dump`" export RESTORE_PROG="`set_prog_path restore`" export LVM_PROG="`set_prog_path lvm`" export CHATTR_PROG="`set_prog_path chattr`" export DEBUGFS_PROG="`set_prog_path debugfs`" export UUIDGEN_PROG="`set_prog_path uuidgen`" export GETRICHACL_PROG="`set_prog_path getrichacl`" export SETRICHACL_PROG="`set_prog_path setrichacl`" # use 'udevadm settle' or 'udevsettle' to wait for lv to be settled. # newer systems have udevadm command but older systems like RHEL5 don't. # But if neither one is available, just set it to "sleep 1" to wait for lv to # be settled UDEV_SETTLE_PROG="`set_prog_path udevadm`" if [ "$UDEV_SETTLE_PROG" == "" ]; then # try udevsettle command UDEV_SETTLE_PROG="`set_prog_path udevsettle`" else # udevadm is available, add 'settle' as subcommand UDEV_SETTLE_PROG="$UDEV_SETTLE_PROG settle" fi # neither command is available, use sleep 1 if [ "$UDEV_SETTLE_PROG" == "" ]; then UDEV_SETTLE_PROG="sleep 1" fi export UDEV_SETTLE_PROG # Generate a comparable xfsprogs version number in the form of # major * 10000 + minor * 100 + release # # $ xfs_db -V # xfs_db version 2.9.7 # # so, 2.9.7 = 20907 _version=`$XFS_DB_PROG -V | $AWK_PROG ' /version/ { if (split($3,ver,".") == 3) print (ver[1] * 10000) + (ver[2] * 100) + ver[3]; }'` [ -z "$_version" ] && _fatal "xfsprogs version cannot be found" export XFSPROGS_VERSION="$_version" case "$HOSTOS" in IRIX*) export MKFS_XFS_PROG="`set_prog_path mkfs_xfs`" export MKFS_UDF_PROG="`set_prog_path mkfs_udf`" export XFS_FSR_PROG="`set_prog_path /usr/etc/fsr_xfs`" export MKFS_NFS_PROG="false" export MKFS_CIFS_PROG="false" ;; Linux) export MKFS_XFS_PROG="`set_prog_path mkfs.xfs`" export MKFS_EXT4_PROG="`set_prog_path mkfs.ext4`" export MKFS_UDF_PROG="`set_prog_path mkudffs`" export MKFS_BTRFS_PROG="`set_btrfs_mkfs_prog_path_with_opts`" export MKFS_F2FS_PROG="`set_prog_path mkfs.f2fs`" export DUMP_F2FS_PROG="`set_prog_path dump.f2fs`" export BTRFS_UTIL_PROG="`set_prog_path btrfs`" export BTRFS_SHOW_SUPER_PROG="`set_prog_path btrfs-show-super`" export XFS_FSR_PROG="`set_prog_path xfs_fsr`" export MKFS_NFS_PROG="false" export MKFS_CIFS_PROG="false" export MKFS_OVERLAY_PROG="false" export MKFS_REISER4_PROG="`set_prog_path mkfs.reiser4`" ;; esac # 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" export SELINUX_MOUNT_OPTIONS fi # check if mkfs.xfs supports v5 xfs XFS_MKFS_HAS_NO_META_SUPPORT="" touch /tmp/crc_check.img $MKFS_XFS_PROG -N -d file,name=/tmp/crc_check.img,size=32m -m crc=0 \ >/dev/null 2>&1; if [ $? -ne 0 ]; then XFS_MKFS_HAS_NO_META_SUPPORT=true fi rm -f /tmp/crc_check.img export XFS_MKFS_HAS_NO_META_SUPPORT # new doesn't need config file parsed, we can stop here if [ "$iam" == "new" ]; then return 0 fi _mount_opts() { case $FSTYP in xfs) export MOUNT_OPTIONS=$XFS_MOUNT_OPTIONS ;; udf) export MOUNT_OPTIONS=$UDF_MOUNT_OPTIONS ;; nfs) export MOUNT_OPTIONS=$NFS_MOUNT_OPTIONS ;; cifs) export MOUNT_OPTIONS=$CIFS_MOUNT_OPTIONS ;; overlay) export MOUNT_OPTIONS=$OVERLAY_MOUNT_OPTIONS ;; ext2|ext3|ext4|ext4dev) # acls & xattrs aren't turned on by default on ext$FOO export MOUNT_OPTIONS="-o acl,user_xattr $EXT_MOUNT_OPTIONS" ;; f2fs) export MOUNT_OPTIONS="-o acl,user_xattr $F2FS_MOUNT_OPTIONS" ;; reiserfs) # acls & xattrs aren't turned on by default on reiserfs export MOUNT_OPTIONS="-o acl,user_xattr $REISERFS_MOUNT_OPTIONS" ;; reiser4) # acls & xattrs aren't supported by reiser4 export MOUNT_OPTIONS=$REISER4_MOUNT_OPTIONS ;; gfs2) # acls aren't turned on by default on gfs2 export MOUNT_OPTIONS="-o acl $GFS2_MOUNT_OPTIONS" ;; tmpfs) # We need to specify the size at mount, use 1G by default export MOUNT_OPTIONS="-o size=1G $TMPFS_MOUNT_OPTIONS" ;; *) ;; esac } _test_mount_opts() { case $FSTYP in cifs) export TEST_FS_MOUNT_OPTS=$CIFS_MOUNT_OPTIONS ;; *) ;; esac } _mkfs_opts() { case $FSTYP in xfs) export MKFS_OPTIONS=$XFS_MKFS_OPTIONS ;; udf) [ ! -z "$udf_fsize" ] && \ UDF_MKFS_OPTIONS="$UDF_MKFS_OPTIONS -s $udf_fsize" export MKFS_OPTIONS=$UDF_MKFS_OPTIONS ;; nfs) export MKFS_OPTIONS=$NFS_MKFS_OPTIONS ;; cifs) export MKFS_OPTIONS=$CIFS_MKFS_OPTIONS ;; reiserfs) export MKFS_OPTIONS="$REISERFS_MKFS_OPTIONS -q" ;; reiser4) export MKFS_OPTIONS=$REISER4_MKFS_OPTIONS ;; gfs2) export MKFS_OPTIONS="$GFS2_MKFS_OPTIONS -O -p lock_nolock" ;; jfs) export MKFS_OPTIONS="$JFS_MKFS_OPTIONS -q" ;; f2fs) export MKFS_OPTIONS="$F2FS_MKFS_OPTIONS" ;; *) ;; esac } _fsck_opts() { case $FSTYP in ext2|ext3|ext4|ext4dev) export FSCK_OPTIONS="-nf" ;; reiser*) export FSCK_OPTIONS="--yes" ;; f2fs) export FSCK_OPTIONS="" ;; *) export FSCK_OPTIONS="-n" ;; esac } known_hosts() { [ "$HOST_CONFIG_DIR" ] || HOST_CONFIG_DIR=`pwd`/configs [ -f /etc/xfsqa.config ] && export HOST_OPTIONS=/etc/xfsqa.config [ -f $HOST_CONFIG_DIR/$HOST ] && export HOST_OPTIONS=$HOST_CONFIG_DIR/$HOST [ -f $HOST_CONFIG_DIR/$HOST.config ] && export HOST_OPTIONS=$HOST_CONFIG_DIR/$HOST.config } # Returns a list of sections in config file # Each section starts with the section name in the format # [section_name1]. Only alphanumeric characters and '_' is allowed # in the section name otherwise the section will not be resognised. # Section name must be contained between square brackets. get_config_sections() { sed -n -e "s/^\[\([[:alnum:]_]*\)\]/\1/p" < $1 } if [ ! -f "$HOST_OPTIONS" ]; then known_hosts fi export HOST_OPTIONS_SECTIONS="-no-sections-" export OPTIONS_HAVE_SECTIONS=false if [ -f "$HOST_OPTIONS" ]; then export HOST_OPTIONS_SECTIONS=`get_config_sections $HOST_OPTIONS` if [ -z "$HOST_OPTIONS_SECTIONS" ]; then . $HOST_OPTIONS export HOST_OPTIONS_SECTIONS="-no-sections-" else export OPTIONS_HAVE_SECTIONS=true fi fi _check_device() { local name=$1 local dev_needed=$2 local dev=$3 if [ -z "$dev" ]; then if [ "$dev_needed" == "required" ]; then _fatal "common/config: $name is required but not defined!" fi return fi echo $dev | grep -qE ":|//" > /dev/null 2>&1 network_dev=$? if [ "$FSTYP" == "overlay" ]; then if [ ! -d "$dev" ]; then _fatal "common/config: $name ($dev) is not a directory for overlay" fi elif [ ! -b "$dev" -a "$network_dev" != "0" ]; then _fatal "common/config: $name ($dev) is not a block device or a network filesystem" fi } # Parse config section options. This function will parse all the configuration # within a single section which name is passed as an argument. For section # name format see comments in get_config_sections(). # Empty lines and everything after '#' will be ignored. # Configuration options should be defined in the format # # CONFIG_OPTION=value # # This 'CONFIG_OPTION' variable and will be exported as an environment variable. parse_config_section() { SECTION=$1 if ! $OPTIONS_HAVE_SECTIONS; then return 0 fi eval `sed -e 's/[[:space:]]*\=[[:space:]]*/=/g' \ -e 's/#.*$//' \ -e 's/[[:space:]]*$//' \ -e 's/^[[:space:]]*//' \ -e "s/^\([^=]*\)=\"\?'\?\([^\"']*\)\"\?'\?$/export \1=\"\2\"/" \ < $HOST_OPTIONS \ | sed -n -e "/^\[$SECTION\]/,/^\s*\[/{/^[^#].*\=.*/p;}"` } get_next_config() { if [ ! -z "$CONFIG_INCLUDED" ] && ! $OPTIONS_HAVE_SECTIONS; then return 0 fi local OLD_FSTYP=$FSTYP local OLD_MOUNT_OPTIONS=$MOUNT_OPTIONS local OLD_TEST_FS_MOUNT_OPTS=$TEST_FS_MOUNT_OPTS local OLD_MKFS_OPTIONS=$MKFS_OPTIONS local OLD_FSCK_OPTIONS=$FSCK_OPTIONS local OLD_USE_EXTERNAL=$USE_EXTERNAL unset MOUNT_OPTIONS unset MKFS_OPTIONS unset FSCK_OPTIONS unset USE_EXTERNAL # We might have deduced SCRATCH_DEV from the SCRATCH_DEV_POOL in the previous # run, so we have to unset it now. if [ "$SCRATCH_DEV_NOT_SET" == "true" ]; then unset SCRATCH_DEV fi parse_config_section $1 if [ ! -z "$OLD_FSTYP" ] && [ $OLD_FSTYP != $FSTYP ]; then [ -z "$MOUNT_OPTIONS" ] && _mount_opts [ -z "$TEST_FS_MOUNT_OPTS" ] && _test_mount_opts [ -z "$MKFS_OPTIONS" ] && _mkfs_opts [ -z "$FSCK_OPTIONS" ] && _fsck_opts # clear the external devices if we are not using them if [ -z "$USE_EXTERNAL" ]; then unset TEST_RTDEV unset TEST_LOGDEV unset SCRATCH_RTDEV unset SCRATCH_LOGDEV fi else [ -z "$MOUNT_OPTIONS" ] && export MOUNT_OPTIONS=$OLD_MOUNT_OPTIONS [ -z "$TEST_FS_MOUNT_OPTS" ] && export TEST_FS_MOUNT_OPTS=$OLD_TEST_FS_MOUNT_OPTS [ -z "$MKFS_OPTIONS" ] && export MKFS_OPTIONS=$OLD_MKFS_OPTIONS [ -z "$FSCK_OPTIONS" ] && export FSCK_OPTIONS=$OLD_FSCK_OPTIONS [ -z "$USE_EXTERNAL" ] && export USE_EXTERNAL=$OLD_USE_EXTERNAL fi # set default RESULT_BASE if [ -z "$RESULT_BASE" ]; then export RESULT_BASE="$here/results/" fi # Mandatory Config values. MC="" [ -z "$EMAIL" ] && MC="$MC EMAIL" [ -z "$TEST_DIR" ] && MC="$MC TEST_DIR" [ -z "$TEST_DEV" ] && MC="$MC TEST_DEV" if [ -n "$MC" ]; then echo "Warning: need to define parameters for host $HOST" echo " or set variables:" echo " $MC" exit 1 fi _check_device TEST_DEV required $TEST_DEV if [ ! -d "$TEST_DIR" ]; then echo "common/config: Error: \$TEST_DIR ($TEST_DIR) is not a directory" exit 1 fi # a btrfs tester will set only SCRATCH_DEV_POOL, we will put first of its dev # to SCRATCH_DEV and rest to SCRATCH_DEV_POOL to maintain the backward compatibility if [ ! -z "$SCRATCH_DEV_POOL" ]; then if [ ! -z "$SCRATCH_DEV" ]; then echo "common/config: Error: \$SCRATCH_DEV ($SCRATCH_DEV) should be unset when \$SCRATCH_DEV_POOL ($SCRATCH_DEV_POOL) is set" exit 1 fi SCRATCH_DEV=`echo $SCRATCH_DEV_POOL | awk '{print $1}'` export SCRATCH_DEV export SCRATCH_DEV_NOT_SET=true fi _check_device SCRATCH_DEV optional $SCRATCH_DEV if [ ! -z "$SCRATCH_MNT" -a ! -d "$SCRATCH_MNT" ]; then echo "common/config: Error: \$SCRATCH_MNT ($SCRATCH_MNT) is not a directory" exit 1 fi if [ -n "$USE_EXTERNAL" ]; then _check_device TEST_RTDEV optional $TEST_RTDEV _check_device TEST_LOGDEV optional $TEST_LOGDEV _check_device SCRATCH_RTDEV optional $SCRATCH_RTDEV _check_device SCRATCH_LOGDEV optional $SCRATCH_LOGDEV fi } if [ -z "$CONFIG_INCLUDED" ]; then get_next_config `echo $HOST_OPTIONS_SECTIONS | cut -f1 -d" "` export CONFIG_INCLUDED=true # Autodetect fs type based on what's on $TEST_DEV unless it's been set # externally if [ -z "$FSTYP" ] && \ [ "$HOSTOS" == "Linux" -o "$OSTYPE" == "linux-gnu" ] && \ [ ! -z "$TEST_DEV" ]; then FSTYP=`blkid -c /dev/null -s TYPE -o value $TEST_DEV` fi FSTYP=${FSTYP:=xfs} export FSTYP [ -z "$MOUNT_OPTIONS" ] && _mount_opts [ -z "$TEST_FS_MOUNT_OPTS" ] && _test_mount_opts [ -z "$MKFS_OPTIONS" ] && _mkfs_opts [ -z "$FSCK_OPTIONS" ] && _fsck_opts fi # canonicalize the mount points # this follows symlinks and removes all trailing "/"s export TEST_DIR=`readlink -e "$TEST_DIR"` export SCRATCH_MNT=`readlink -e "$SCRATCH_MNT"` # make sure this script returns success /bin/true