| ##/bin/bash |
| # SPDX-License-Identifier: GPL-2.0 |
| # Copyright (c) 2000-2003,2006 Silicon Graphics, Inc. All Rights Reserved. |
| # |
| # 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 |
| # SELINUX_MOUNT_OPTIONS - Options to use when SELinux is enabled. |
| # KEEP_DMESG - whether to keep all dmesg for each test case. |
| # yes: keep all dmesg |
| # no: only keep dmesg with error/warning (default) |
| # |
| # - 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. |
| # |
| |
| . common/test_names |
| |
| # all tests should use a common language setting to prevent golden |
| # output mismatches. |
| export LANG=C |
| export LC_ALL=C |
| |
| PATH=".:$PATH" |
| |
| export HOST=`hostname -s` |
| test `uname -s` = "Linux" || _fatal "fstests only supports Linux" |
| |
| 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 TIME_FACTOR=${TIME_FACTOR:=1} |
| export LOAD_FACTOR=${LOAD_FACTOR:=1} |
| export DEBUGFS_MNT=${DEBUGFS_MNT:="/sys/kernel/debug"} |
| |
| # some constants for overlayfs setup |
| export OVL_UPPER="ovl-upper" |
| export OVL_LOWER="ovl-lower" |
| export OVL_WORK="ovl-work" |
| # overlay mount point parent must be the base fs root |
| export OVL_MNT="ovl-mnt" |
| # By default unionmount-testsuite is expected under src |
| export UNIONMOUNT_TESTSUITE=${UNIONMOUNT_TESTSUITE:=$here/src/unionmount-testsuite} |
| |
| # From e2fsprogs/e2fsck/e2fsck.h: |
| # Exit code used by fsck-type programs |
| export FSCK_OK=0 |
| export FSCK_NONDESTRUCT=1 |
| export FSCK_REBOOT=2 |
| export FSCK_UNCORRECTED=4 |
| export FSCK_ERROR=8 |
| export FSCK_USAGE=16 |
| export FSCK_CANCELED=32 |
| export FSCK_LIBRARY=128 |
| |
| 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 |
| |
| # Handle mkfs.$fstyp which does (or does not) require -f to overwrite |
| set_mkfs_prog_path_with_opts() |
| { |
| local fstyp=$1 |
| local p=$(type -P mkfs.$fstyp) |
| |
| # Note: mkfs.f2fs doesn't support the --help option yet, but it doesn't |
| # matter since it also prints the help when an invalid option is given. |
| if [ "$p" != "" ] && \ |
| $p --help |& grep -q "[[:space:]]-f[[:space:]|]"; then |
| echo "$p -f" |
| else |
| echo $p |
| fi |
| } |
| |
| _fatal() |
| { |
| echo "$*" |
| status=1 |
| exit 1 |
| } |
| |
| export MKFS_PROG="$(type -P mkfs)" |
| [ "$MKFS_PROG" = "" ] && _fatal "mkfs not found" |
| |
| export MOUNT_PROG="$(type -P mount)" |
| [ "$MOUNT_PROG" = "" ] && _fatal "mount not found" |
| |
| export UMOUNT_PROG="$(type -P umount)" |
| [ "$UMOUNT_PROG" = "" ] && _fatal "umount not found" |
| |
| export FSSTRESS_PROG="./ltp/fsstress" |
| [ ! -x $FSSTRESS_PROG ] && _fatal "fsstress not found or executable" |
| |
| export PERL_PROG="$(type -P perl)" |
| [ "$PERL_PROG" = "" ] && _fatal "perl not found" |
| |
| export AWK_PROG="$(type -P awk)" |
| [ "$AWK_PROG" = "" ] && _fatal "awk not found" |
| |
| export SED_PROG="$(type -P sed)" |
| [ "$SED_PROG" = "" ] && _fatal "sed not found" |
| |
| export BC_PROG="$(type -P bc)" |
| [ "$BC_PROG" = "" ] && _fatal "bc not found" |
| |
| export PS_ALL_FLAGS="-ef" |
| |
| export DF_PROG="$(type -P df)" |
| [ "$DF_PROG" = "" ] && _fatal "df not found" |
| export DF_PROG="$DF_PROG -T -P" # Linux |
| |
| export XFS_IO_PROG="$(type -P xfs_io)" |
| [ "$XFS_IO_PROG" = "" ] && _fatal "xfs_io not found" |
| |
| export MKSWAP_PROG="$(type -P mkswap)" |
| # mkswap from util-linux v2.17.2 or older needs "-f" option to force to erase |
| # bootbits sectors |
| MKSWAP_PROG="$MKSWAP_PROG -f" |
| |
| export XFS_LOGPRINT_PROG="$(type -P xfs_logprint)" |
| export XFS_REPAIR_PROG="$(type -P xfs_repair)" |
| export XFS_DB_PROG="$(type -P xfs_db)" |
| export XFS_METADUMP_PROG="$(type -P xfs_metadump)" |
| export XFS_ADMIN_PROG="$(type -P xfs_admin)" |
| export XFS_GROWFS_PROG=$(type -P xfs_growfs) |
| export XFS_SPACEMAN_PROG="$(type -P xfs_spaceman)" |
| export XFS_SCRUB_PROG="$(type -P xfs_scrub)" |
| export XFS_PARALLEL_REPAIR_PROG="$(type -P xfs_prepair)" |
| export XFS_PARALLEL_REPAIR64_PROG="$(type -P xfs_prepair64)" |
| export __XFSDUMP_PROG="$(type -P xfsdump)" |
| if [ -n "$__XFSDUMP_PROG" ]; then |
| export XFSDUMP_PROG="$__XFSDUMP_PROG -e" |
| else |
| export XFSDUMP_PROG="" |
| fi |
| export XFSRESTORE_PROG="$(type -P xfsrestore)" |
| export XFSINVUTIL_PROG="$(type -P xfsinvutil)" |
| export GETFATTR_PROG="$(type -P getfattr)" |
| export SETFATTR_PROG="$(type -P setfattr)" |
| export CHACL_PROG="$(type -P chacl)" |
| export ATTR_PROG="$(type -P attr)" |
| export QUOTA_PROG="$(type -P quota)" |
| export XFS_QUOTA_PROG="$(type -P xfs_quota)" |
| export KILLALL_PROG="$(type -P killall)" |
| export INDENT_PROG="$(type -P indent)" |
| export XFS_COPY_PROG="$(type -P xfs_copy)" |
| export FSTRIM_PROG="$(type -P fstrim)" |
| export DUMPE2FS_PROG="$(type -P dumpe2fs)" |
| export RESIZE2FS_PROG="$(type -P resize2fs)" |
| export F2FS_IO_PROG="$(type -P f2fs_io)" |
| export FIO_PROG="$(type -P fio)" |
| export FILEFRAG_PROG="$(type -P filefrag)" |
| export E4DEFRAG_PROG="$(type -P e4defrag)" |
| export LOGGER_PROG="$(type -P logger)" |
| export DBENCH_PROG="$(type -P dbench)" |
| export DMSETUP_PROG="$(type -P dmsetup)" |
| export WIPEFS_PROG="$(type -P wipefs)" |
| export BLKDISCARD_PROG="$(type -P blkdiscard)" |
| export DUMP_PROG="$(type -P dump)" |
| export RESTORE_PROG="$(type -P restore)" |
| export LVM_PROG="$(type -P lvm)" |
| export LSATTR_PROG="$(type -P lsattr)" |
| export CHATTR_PROG="$(type -P chattr)" |
| export DEBUGFS_PROG="$(type -P debugfs)" |
| export UUIDGEN_PROG="$(type -P uuidgen)" |
| export GETRICHACL_PROG="$(type -P getrichacl)" |
| export SETRICHACL_PROG="$(type -P setrichacl)" |
| export KEYCTL_PROG="$(type -P keyctl)" |
| export XZ_PROG="$(type -P xz)" |
| export LZ4_PROG="$(type -P lz4)" |
| export FLOCK_PROG="$(type -P flock)" |
| export LDD_PROG="$(type -P ldd)" |
| export TIMEOUT_PROG="$(type -P timeout)" |
| export MAN_PROG="$(type -P man)" |
| export NFS4_SETFACL_PROG="$(type -P nfs4_setfacl)" |
| export NFS4_GETFACL_PROG="$(type -P nfs4_getfacl)" |
| export UBIUPDATEVOL_PROG="$(type -P ubiupdatevol)" |
| export THIN_CHECK_PROG="$(type -P thin_check)" |
| export PYTHON2_PROG="$(type -P python2)" |
| export SQLITE3_PROG="$(type -P sqlite3)" |
| export TIMEOUT_PROG="$(type -P timeout)" |
| export SETCAP_PROG="$(type -P setcap)" |
| export GETCAP_PROG="$(type -P getcap)" |
| export CAPSH_PROG="$(type -P capsh)" |
| export CHECKBASHISMS_PROG="$(type -P checkbashisms)" |
| export XFS_INFO_PROG="$(type -P xfs_info)" |
| export DUPEREMOVE_PROG="$(type -P duperemove)" |
| export CC_PROG="$(type -P cc)" |
| export FSVERITY_PROG="$(type -P fsverity)" |
| export OPENSSL_PROG="$(type -P openssl)" |
| export ACCTON_PROG="$(type -P accton)" |
| export E2IMAGE_PROG="$(type -P e2image)" |
| export BLKZONE_PROG="$(type -P blkzone)" |
| export GZIP_PROG="$(type -P gzip)" |
| export BTRFS_IMAGE_PROG="$(type -P btrfs-image)" |
| |
| # 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="$(type -P udevadm)" |
| if [ "$UDEV_SETTLE_PROG" == "" ]; then |
| # try udevsettle command |
| UDEV_SETTLE_PROG="$(type -P udevsettle)" |
| else |
| # udevadm is available, add 'settle' as subcommand |
| UDEV_SETTLE_PROG="$UDEV_SETTLE_PROG settle" |
| fi |
| # neither command is available, use sleep 1 |
| # |
| # Udev events are sent via netlink to userspace through |
| # kobject_uevent_net_broadcast(), and udev in userspace is in charge of |
| # handling the events. The command `udevadm settle` just checks if |
| # /run/udev/queue is 0, however, a kernel without CONFIG_NET will have |
| # kobject_uevent_net_broadcast() be a no-op, and so /run/udev/queue may not |
| # exist or always be 0. We check for /proc/net to see CONFIG_NET was enabled. |
| if [[ "$UDEV_SETTLE_PROG" == "" || ! -d /proc/net ]]; then |
| UDEV_SETTLE_PROG="sleep 1" |
| fi |
| export UDEV_SETTLE_PROG |
| |
| # Set MODPROBE_PATIENT_RM_TIMEOUT_SECONDS to "forever" if you want the patient |
| # modprobe removal to run forever trying to remove a module. |
| MODPROBE_REMOVE_PATIENT="" |
| modprobe --help >& /dev/null && modprobe --help | grep -q -1 "remove-patiently" |
| if [[ $? -ne 0 ]]; then |
| if [[ -z "$MODPROBE_PATIENT_RM_TIMEOUT_SECONDS" ]]; then |
| # We will open code our own implementation of patient module |
| # remover in fstests. Use a 50 second default. |
| export MODPROBE_PATIENT_RM_TIMEOUT_SECONDS="50" |
| fi |
| else |
| MODPROBE_RM_PATIENT_TIMEOUT_ARGS="" |
| if [[ ! -z "$MODPROBE_PATIENT_RM_TIMEOUT_SECONDS" ]]; then |
| if [[ "$MODPROBE_PATIENT_RM_TIMEOUT_SECONDS" != "forever" ]]; then |
| MODPROBE_PATIENT_RM_TIMEOUT_MS="$((MODPROBE_PATIENT_RM_TIMEOUT_SECONDS * 1000))" |
| MODPROBE_RM_PATIENT_TIMEOUT_ARGS="-t $MODPROBE_PATIENT_RM_TIMEOUT_MS" |
| fi |
| else |
| # We export MODPROBE_PATIENT_RM_TIMEOUT_SECONDS here for parity |
| # with environments without support for modprobe -p, but we |
| # only really need it exported right now for environments which |
| # don't have support for modprobe -p to implement our own |
| # patient module removal support within fstests. |
| export MODPROBE_PATIENT_RM_TIMEOUT_SECONDS="50" |
| MODPROBE_PATIENT_RM_TIMEOUT_MS="$((MODPROBE_PATIENT_RM_TIMEOUT_SECONDS * 1000))" |
| MODPROBE_RM_PATIENT_TIMEOUT_ARGS="-t $MODPROBE_PATIENT_RM_TIMEOUT_MS" |
| fi |
| MODPROBE_REMOVE_PATIENT="modprobe -p $MODPROBE_RM_PATIENT_TIMEOUT_ARGS" |
| fi |
| export MODPROBE_REMOVE_PATIENT |
| |
| export MKFS_XFS_PROG=$(type -P mkfs.xfs) |
| export MKFS_EXT4_PROG=$(type -P mkfs.ext4) |
| export MKFS_UDF_PROG=$(type -P mkudffs) |
| export MKFS_BTRFS_PROG=$(set_mkfs_prog_path_with_opts btrfs) |
| export MKFS_F2FS_PROG=$(set_mkfs_prog_path_with_opts f2fs) |
| export DUMP_F2FS_PROG=$(type -P dump.f2fs) |
| export F2FS_IO_PROG=$(type -P f2fs_io) |
| export BTRFS_UTIL_PROG=$(type -P btrfs) |
| export BTRFS_SHOW_SUPER_PROG=$(type -P btrfs-show-super) |
| export BTRFS_CONVERT_PROG=$(type -P btrfs-convert) |
| export BTRFS_TUNE_PROG=$(type -P btrfstune) |
| export XFS_FSR_PROG=$(type -P xfs_fsr) |
| export MKFS_NFS_PROG="false" |
| export MKFS_CIFS_PROG="false" |
| export MKFS_OVERLAY_PROG="false" |
| export MKFS_REISER4_PROG=$(type -P mkfs.reiser4) |
| export E2FSCK_PROG=$(type -P e2fsck) |
| export TUNE2FS_PROG=$(type -P tune2fs) |
| export FSCK_OVERLAY_PROG=$(type -P fsck.overlay) |
| |
| # SELinux adds extra xattrs which can mess up our expected output. |
| # So, mount with a context, and they won't be created. |
| # |
| # Since the context= option only accepts contexts defined in the SELinux |
| # policy, and different systems may have different policies with |
| # different context names, use the context of an existing directory. |
| # Assume that any valid context is fine, since xfstests should really |
| # only be run from an "unconfined" process, or with SELinux in permissive |
| # mode. But if not, just specify your own SELINUX_MOUNT_OPTIONS. |
| if [ -x /usr/sbin/selinuxenabled ] && /usr/sbin/selinuxenabled; then |
| : ${SELINUX_MOUNT_OPTIONS:="-o context=$(stat -c %C /)"} |
| export SELINUX_MOUNT_OPTIONS |
| fi |
| |
| # check if mkfs.xfs supports v5 xfs |
| if [ "$FSTYP" == "xfs" ]; then |
| 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 |
| fi |
| |
| _mount_opts() |
| { |
| case $FSTYP in |
| 9p) |
| export MOUNT_OPTIONS=$PLAN9_MOUNT_OPTIONS |
| ;; |
| 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 |
| ;; |
| ceph) |
| export MOUNT_OPTIONS=$CEPHFS_MOUNT_OPTIONS |
| ;; |
| glusterfs) |
| export MOUNT_OPTIONS=$GLUSTERFS_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" |
| ;; |
| ubifs) |
| export MOUNT_OPTIONS=$UBIFS_MOUNT_OPTIONS |
| ;; |
| *) |
| ;; |
| esac |
| } |
| |
| _test_mount_opts() |
| { |
| case $FSTYP in |
| 9p) |
| export TEST_FS_MOUNT_OPTS=$PLAN9_MOUNT_OPTIONS |
| ;; |
| cifs) |
| export TEST_FS_MOUNT_OPTS=$CIFS_MOUNT_OPTIONS |
| ;; |
| ceph) |
| export TEST_FS_MOUNT_OPTS=$CEPHFS_MOUNT_OPTIONS |
| ;; |
| nfs) |
| export TEST_FS_MOUNT_OPTS=$NFS_MOUNT_OPTIONS |
| ;; |
| glusterfs) |
| export TEST_FS_MOUNT_OPTS=$GLUSTERFS_MOUNT_OPTIONS |
| ;; |
| ext2|ext3|ext4|ext4dev) |
| # acls & xattrs aren't turned on by default on older ext$FOO |
| export TEST_FS_MOUNT_OPTS="-o acl,user_xattr $EXT_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 |
| ;; |
| ceph) |
| export MKFS_OPTIONS=$CEPHFS_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" |
| ;; |
| btrfs) |
| export MKFS_OPTIONS="$BTRFS_MKFS_OPTIONS" |
| ;; |
| bcachefs) |
| export MKFS_OPTIONS=$BCACHEFS_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 0 |
| fi |
| |
| if [ -b "$dev" ] || ( echo $dev | grep -qE ":|//" ); then |
| # block device or a network url |
| return 0 |
| fi |
| |
| case "$FSTYP" in |
| 9p|tmpfs|virtiofs) |
| # 9p and virtiofs mount tags are just plain strings, so anything is allowed |
| # tmpfs doesn't use mount source, ignore |
| ;; |
| ceph) |
| # ceph has two different possible syntaxes for mount devices. The |
| # network URL check above catches the legacy syntax. Check for the |
| # new-style syntax here. |
| if ( echo $dev | grep -qEv "=/" ); then |
| _fatal "common/config: $name ($dev) is not a valid ceph mount string" |
| fi |
| ;; |
| overlay) |
| if [ ! -d "$dev" ]; then |
| _fatal "common/config: $name ($dev) is not a directory for overlay" |
| fi |
| ;; |
| ubifs) |
| if [ ! -c "$dev" ]; then |
| _fatal "common/config: $name ($dev) is not a character device" |
| fi |
| ;; |
| *) |
| _fatal "common/config: $name ($dev) is not a block device or a network filesystem" |
| esac |
| } |
| |
| # check and return a canonical mount point path |
| _canonicalize_mountpoint() |
| { |
| local name=$1 |
| local dir=$2 |
| |
| if [ -d "$dir" ]; then |
| # this follows symlinks and removes all trailing "/"s |
| readlink -e "$dir" |
| return 0 |
| fi |
| |
| if [ "$FSTYP" != "overlay" ] || [[ "$name" == OVL_BASE_* ]]; then |
| _fatal "common/config: $name ($dir) is not a directory" |
| fi |
| |
| # base fs may not be mounted yet, so just check that parent dir |
| # exists (where base fs will be mounted) because we are going to |
| # mkdir the overlay mount point dir anyway |
| local base=`basename $dir` |
| local parent=`dirname $dir` |
| parent=`_canonicalize_mountpoint OVL_BASE_$name "$parent"` |
| |
| # prepend the overlay mount point to canonical parent path |
| echo "$parent/$base" |
| } |
| |
| # On check -overlay, for the non multi section config case, this |
| # function is called on every test, before init_rc(). |
| # When SCRATCH/TEST_* vars are defined in config file, config file |
| # is sourced on every test and this function overrides the vars |
| # every time. |
| # When SCRATCH/TEST_* vars are defined in evironment and not |
| # in config file, this function is called after vars have already |
| # been overriden in the previous test. |
| # In that case, TEST_DEV is a directory and not a blockdev/chardev and |
| # the function will return without overriding the SCRATCH/TEST_* vars. |
| _overlay_config_override() |
| { |
| # There are 2 options for configuring overlayfs tests: |
| # |
| # 1. (legacy) SCRATCH/TEST_DEV point to existing directories |
| # on an already mounted fs. In this case, the new |
| # OVL_BASE_SCRATCH/TEST_* vars are set to use the legacy |
| # vars values (even though they may not be mount points). |
| # |
| [ ! -d "$TEST_DEV" ] || export OVL_BASE_TEST_DIR="$TEST_DEV" |
| [ ! -d "$SCRATCH_DEV" ] || export OVL_BASE_SCRATCH_MNT="$SCRATCH_DEV" |
| |
| # 2. SCRATCH/TEST_DEV point to the base fs partitions. In this case, |
| # the new OVL_BASE_SCRATCH/TEST_DEV/MNT vars are set to the values |
| # of the configured base fs and SCRATCH/TEST_DEV vars are set to the |
| # overlayfs base and mount dirs inside base fs mount. |
| [ -b "$TEST_DEV" ] || [ -c "$TEST_DEV" ] || return 0 |
| |
| # Config file may specify base fs type, but we obay -overlay flag |
| [ "$FSTYP" == overlay ] || export OVL_BASE_FSTYP="$FSTYP" |
| export FSTYP=overlay |
| |
| # Store original base fs vars |
| export OVL_BASE_TEST_DEV="$TEST_DEV" |
| export OVL_BASE_TEST_DIR="$TEST_DIR" |
| # If config does not set MOUNT_OPTIONS, its value may be |
| # leftover from previous _overlay_config_override, so |
| # don't use that value for base fs mount |
| [ "$MOUNT_OPTIONS" != "$OVERLAY_MOUNT_OPTIONS" ] || unset MOUNT_OPTIONS |
| export OVL_BASE_MOUNT_OPTIONS="$MOUNT_OPTIONS" |
| |
| # Set TEST vars to overlay base and mount dirs inside base fs |
| export TEST_DEV="$OVL_BASE_TEST_DIR" |
| export TEST_DIR="$OVL_BASE_TEST_DIR/$OVL_MNT" |
| export MOUNT_OPTIONS="$OVERLAY_MOUNT_OPTIONS" |
| |
| [ -b "$SCRATCH_DEV" ] || [ -c "$SCRATCH_DEV" ] || return 0 |
| |
| # Store original base fs vars |
| export OVL_BASE_SCRATCH_DEV="$SCRATCH_DEV" |
| export OVL_BASE_SCRATCH_MNT="$SCRATCH_MNT" |
| |
| # Set SCRATCH vars to overlay base and mount dirs inside base fs |
| export SCRATCH_DEV="$OVL_BASE_SCRATCH_MNT" |
| export SCRATCH_MNT="$OVL_BASE_SCRATCH_MNT/$OVL_MNT" |
| |
| # Set fsck options, use default if user not set directly. |
| export FSCK_OPTIONS="$OVERLAY_FSCK_OPTIONS" |
| [ -z "$FSCK_OPTIONS" ] && _fsck_opts |
| export IDMAPPED_MOUNTS="$IDMAPPED_MOUNTS" |
| } |
| |
| _overlay_config_restore() |
| { |
| export OVERLAY=true |
| [ -z "$OVL_BASE_FSTYP" ] || export FSTYP=$OVL_BASE_FSTYP |
| [ -z "$OVL_BASE_TEST_DEV" ] || export TEST_DEV=$OVL_BASE_TEST_DEV |
| [ -z "$OVL_BASE_TEST_DIR" ] || export TEST_DIR=$OVL_BASE_TEST_DIR |
| [ -z "$OVL_BASE_SCRATCH_DEV" ] || export SCRATCH_DEV=$OVL_BASE_SCRATCH_DEV |
| [ -z "$OVL_BASE_SCRATCH_MNT" ] || export SCRATCH_MNT=$OVL_BASE_SCRATCH_MNT |
| [ -z "$OVL_BASE_MOUNT_OPTIONS" ] || export MOUNT_OPTIONS=$OVL_BASE_MOUNT_OPTIONS |
| } |
| |
| # 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 |
| |
| # We might have overriden FSTYP and TEST/SCRATCH vars with overlay values |
| # in the previous section, so restore them to original values stored in |
| # OVL_BASE_*. |
| # We need to do this *before* old FSTYP and MOUNT_OPTIONS are recorded |
| # and *before* SCRATCH_DEV and MOUNT_OPTIONS are unset |
| if [ "$FSTYP" == "overlay" ]; then |
| _overlay_config_restore |
| 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 TEST_FS_MOUNT_OPTS |
| 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 |
| |
| if [ "$FSTYP" == "tmpfs" ]; then |
| if [ -z "TEST_DEV" ]; then |
| export TEST_DEV=tmpfs_test |
| fi |
| if [ -z "SCRATCH_DEV" ]; then |
| export TEST_DEV=tmpfs_scratch |
| fi |
| 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 |
| export TEST_DIR=`_canonicalize_mountpoint TEST_DIR $TEST_DIR` |
| |
| # 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 |
| export SCRATCH_MNT=`_canonicalize_mountpoint SCRATCH_MNT $SCRATCH_MNT` |
| |
| 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 |
| |
| # Override FSTYP from config when running ./check -overlay |
| # and maybe override base fs TEST/SCRATCH_DEV with overlay base dirs. |
| # We need to do this *after* default mount options are set by base FSTYP |
| # and *after* SCRATCH_DEV is deduced from SCRATCH_DEV_POOL |
| if [ "$OVERLAY" == "true" -o "$FSTYP" == "overlay" ]; then |
| _overlay_config_override |
| 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" ] && [ ! -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 |
| else |
| # We get here for the non multi section case, on every test that sources |
| # common/rc after re-sourcing the HOST_OPTIONS config file. |
| # Because of this re-sourcing, we need to re-canonicalize the configured |
| # mount points and re-override TEST/SCRATCH_DEV overlay vars. |
| |
| # canonicalize the mount points |
| # this follows symlinks and removes all trailing "/"s |
| export TEST_DIR=`_canonicalize_mountpoint TEST_DIR $TEST_DIR` |
| export SCRATCH_MNT=`_canonicalize_mountpoint SCRATCH_MNT $SCRATCH_MNT` |
| |
| # Override FSTYP from config when running ./check -overlay |
| # and maybe override base fs TEST/SCRATCH_DEV with overlay base dirs |
| if [ "$OVERLAY" == "true" -o "$FSTYP" == "overlay" ]; then |
| _overlay_config_override |
| fi |
| fi |
| |
| # make sure this script returns success |
| /bin/true |