#! /bin/bash # SPDX-License-Identifier: GPL-2.0 # Copyright (c) 2020-2021 Red Hat, Inc. All Rights Reserved. # # FS QA Test No. 168 # # XFS online shrinkfs stress test # # This test attempts to shrink unused space as much as possible with # background fsstress workload. It will decrease the shrink size if # larger size fails. And totally repeat 2 * TIME_FACTOR times. # seq=`basename $0` seqres=$RESULT_DIR/$seq echo "QA output created by $seq" here=`pwd` tmp=/tmp/$$ status=1 # failure is the default! trap "rm -f $tmp.*; exit \$status" 0 1 2 3 15 # get standard environment, filters and checks . ./common/rc . ./common/filter create_scratch() { _scratch_mkfs_xfs $@ | tee -a $seqres.full | \ _filter_mkfs 2>$tmp.mkfs >/dev/null . $tmp.mkfs _scratch_mount # fix the reserve block pool to a known size so that the enospc # calculations work out correctly. _scratch_resvblks 1024 > /dev/null 2>&1 } fill_scratch() { $XFS_IO_PROG -f -c "falloc 0 $1" $SCRATCH_MNT/resvfile } stress_scratch() { local procs=3 local nops=1000 # -w ensures that the only ops are ones which cause write I/O local FSSTRESS_ARGS=`_scale_fsstress_args -d $SCRATCH_MNT -w \ -p $procs -n $nops $FSSTRESS_AVOID` $FSSTRESS_PROG $FSSTRESS_ARGS >> $seqres.full 2>&1 } # real QA test starts here _supported_fs xfs _require_scratch_xfs_shrink _require_xfs_io_command "falloc" rm -f $seqres.full _scratch_mkfs_xfs | tee -a $seqres.full | _filter_mkfs 2>$tmp.mkfs >/dev/null . $tmp.mkfs # extract blocksize and data size for scratch device endsize=`expr 125 \* 1048576` # stop after shrinking this big [ `expr $endsize / $dbsize` -lt $dblocks ] || _notrun "Scratch device too small" nags=2 totalcount=$((2 * TIME_FACTOR)) while [ $totalcount -gt 0 ]; do size=`expr 1010 \* 1048576` # 1010 megabytes initially logblks=$(_scratch_find_xfs_min_logblocks -dsize=${size} -dagcount=${nags}) create_scratch -lsize=${logblks}b -dsize=${size} -dagcount=${nags} for i in `seq 125 -1 90`; do fillsize=`expr $i \* 1048576` out="$(fill_scratch $fillsize 2>&1)" echo "$out" | grep -q 'No space left on device' && continue test -n "${out}" && echo "$out" break done # shrink in chunks of this size at most decsize=`expr 41 \* 1048576 + 1 + $RANDOM \* $RANDOM % 1048576` while [ $size -gt $endsize ]; do stress_scratch & sleep 1 decb=`expr $decsize / $dbsize` # in data blocks while [ $decb -gt 0 ]; do sizeb=`expr $size / $dbsize - $decb` $XFS_GROWFS_PROG -D ${sizeb} $SCRATCH_MNT \ >> $seqres.full 2>&1 && break [ $decb -gt 100 ] && decb=`expr $decb + $RANDOM % 10` decb=`expr $decb / 2` done wait [ $decb -eq 0 ] && break # get latest dblocks $XFS_INFO_PROG $SCRATCH_MNT 2>&1 | _filter_mkfs 2>$tmp.growfs >/dev/null . $tmp.growfs size=`expr $dblocks \* $dbsize` _scratch_unmount _scratch_xfs_repair -n >> $seqres.full 2>&1 || \ _fail "xfs_repair failed with shrinking $sizeb" _scratch_mount done _scratch_unmount _scratch_xfs_repair -n >> $seqres.full 2>&1 || \ _fail "xfs_repair failed with shrinking $sizeb" totalcount=`expr $totalcount - 1` done echo "Silence is golden" status=0 exit