#! /bin/bash # SPDX-License-Identifier: GPL-2.0 # Copyright (c) 2017 Oracle, Inc. All Rights Reserved. # # FS QA Test No. 422 # # Race freeze and rmapbt repair for a while to see if we crash or livelock. # rmapbt repair requires us to freeze the filesystem to stop all filesystem # activity, so we can't have userspace wandering in and thawing it. # . ./common/preamble _begin_fstest dangerous_scrub dangerous_online_repair freeze _register_cleanup "_cleanup" BUS # First kill and wait the freeze loop so it won't try to freeze fs again # Then make sure fs is not frozen # Then kill and wait for the rest of the workers # Because if fs is frozen a killed writer will never exit kill_loops() { local sig=$1 [ -n "$freeze_pid" ] && kill $sig $freeze_pid wait $freeze_pid unset freeze_pid $XFS_IO_PROG -x -c 'thaw' $SCRATCH_MNT [ -n "$stress_pid" ] && kill $sig $stress_pid [ -n "$repair_pid" ] && kill $sig $repair_pid wait unset stress_pid unset repair_pid } # Override the default cleanup function. _cleanup() { kill_loops -9 > /dev/null 2>&1 cd / rm -rf $tmp.* } # Import common functions. . ./common/filter . ./common/fuzzy . ./common/inject # real QA test starts here _supported_fs xfs _require_xfs_scratch_rmapbt _require_xfs_io_command "scrub" _require_xfs_io_error_injection "force_repair" _require_command "$KILLALL_PROG" killall _require_freeze echo "Format and populate" _scratch_mkfs > "$seqres.full" 2>&1 _scratch_mount STRESS_DIR="$SCRATCH_MNT/testdir" mkdir -p $STRESS_DIR for i in $(seq 0 9); do mkdir -p $STRESS_DIR/$i for j in $(seq 0 9); do mkdir -p $STRESS_DIR/$i/$j for k in $(seq 0 9); do echo x > $STRESS_DIR/$i/$j/$k done done done cpus=$(( $($here/src/feature -o) * 4 * LOAD_FACTOR)) echo "Concurrent repair" filter_output() { egrep -v '(Device or resource busy|Invalid argument)' } freeze_loop() { end="$1" while [ "$(date +%s)" -lt $end ]; do $XFS_IO_PROG -x -c 'freeze' -c 'thaw' $SCRATCH_MNT 2>&1 | filter_output done } repair_loop() { end="$1" while [ "$(date +%s)" -lt $end ]; do $XFS_IO_PROG -x -c 'repair rmapbt 0' -c 'repair rmapbt 1' $SCRATCH_MNT 2>&1 | filter_output done } stress_loop() { end="$1" FSSTRESS_ARGS=$(_scale_fsstress_args -p 4 -d $SCRATCH_MNT -n 2000 $FSSTRESS_AVOID) while [ "$(date +%s)" -lt $end ]; do $FSSTRESS_PROG $FSSTRESS_ARGS >> $seqres.full done } $XFS_IO_PROG -x -c 'inject force_repair' $SCRATCH_MNT start=$(date +%s) end=$((start + (30 * TIME_FACTOR) )) echo "Loop started at $(date --date="@${start}"), ending at $(date --date="@${end}")" >> $seqres.full stress_loop $end & stress_pid=$! freeze_loop $end & freeze_pid=$! repair_loop $end & repair_pid=$! # Wait until 2 seconds after the loops should have finished... while [ "$(date +%s)" -lt $((end + 2)) ]; do sleep 1 done # ...and clean up after the loops in case they didn't do it themselves. kill_loops >> $seqres.full 2>&1 echo "Loop finished at $(date)" >> $seqres.full echo "Test done" # success, all done status=0 exit