xfs/{422,517}: kill background jobs on test termination
[xfstests-dev.git] / tests / xfs / 422
1 #! /bin/bash
2 # SPDX-License-Identifier: GPL-2.0
3 # Copyright (c) 2017 Oracle, Inc.  All Rights Reserved.
4 #
5 # FS QA Test No. 422
6 #
7 # Race freeze and rmapbt repair for a while to see if we crash or livelock.
8 # rmapbt repair requires us to freeze the filesystem to stop all filesystem
9 # activity, so we can't have userspace wandering in and thawing it.
10 #
11 . ./common/preamble
12 _begin_fstest dangerous_scrub dangerous_online_repair freeze
13
14 _register_cleanup "_cleanup" BUS
15
16 # First kill and wait the freeze loop so it won't try to freeze fs again
17 # Then make sure fs is not frozen
18 # Then kill and wait for the rest of the workers
19 # Because if fs is frozen a killed writer will never exit
20 kill_loops() {
21         local sig=$1
22
23         [ -n "$freeze_pid" ] && kill $sig $freeze_pid
24         wait $freeze_pid
25         unset freeze_pid
26         $XFS_IO_PROG -x -c 'thaw' $SCRATCH_MNT
27         [ -n "$stress_pid" ] && kill $sig $stress_pid
28         [ -n "$repair_pid" ] && kill $sig $repair_pid
29         wait
30         unset stress_pid
31         unset repair_pid
32 }
33
34 # Override the default cleanup function.
35 _cleanup()
36 {
37         kill_loops -9 > /dev/null 2>&1
38         cd /
39         rm -rf $tmp.*
40 }
41
42 # Import common functions.
43 . ./common/filter
44 . ./common/fuzzy
45 . ./common/inject
46
47 # real QA test starts here
48 _supported_fs xfs
49 _require_xfs_scratch_rmapbt
50 _require_xfs_io_command "scrub"
51 _require_xfs_io_error_injection "force_repair"
52 _require_command "$KILLALL_PROG" killall
53 _require_freeze
54
55 echo "Format and populate"
56 _scratch_mkfs > "$seqres.full" 2>&1
57 _scratch_mount
58
59 STRESS_DIR="$SCRATCH_MNT/testdir"
60 mkdir -p $STRESS_DIR
61
62 for i in $(seq 0 9); do
63         mkdir -p $STRESS_DIR/$i
64         for j in $(seq 0 9); do
65                 mkdir -p $STRESS_DIR/$i/$j
66                 for k in $(seq 0 9); do
67                         echo x > $STRESS_DIR/$i/$j/$k
68                 done
69         done
70 done
71
72 cpus=$(( $($here/src/feature -o) * 4 * LOAD_FACTOR))
73
74 echo "Concurrent repair"
75 filter_output() {
76         egrep -v '(Device or resource busy|Invalid argument)'
77 }
78 freeze_loop() {
79         end="$1"
80
81         while [ "$(date +%s)" -lt $end ]; do
82                 $XFS_IO_PROG -x -c 'freeze' -c 'thaw' $SCRATCH_MNT 2>&1 | filter_output
83         done
84 }
85 repair_loop() {
86         end="$1"
87
88         while [ "$(date +%s)" -lt $end ]; do
89                 $XFS_IO_PROG -x -c 'repair rmapbt 0' -c 'repair rmapbt 1' $SCRATCH_MNT 2>&1 | filter_output
90         done
91 }
92 stress_loop() {
93         end="$1"
94
95         FSSTRESS_ARGS=$(_scale_fsstress_args -p 4 -d $SCRATCH_MNT -n 2000 $FSSTRESS_AVOID)
96         while [ "$(date +%s)" -lt $end ]; do
97                 $FSSTRESS_PROG $FSSTRESS_ARGS >> $seqres.full
98         done
99 }
100 $XFS_IO_PROG -x -c 'inject force_repair' $SCRATCH_MNT
101
102 start=$(date +%s)
103 end=$((start + (30 * TIME_FACTOR) ))
104
105 echo "Loop started at $(date --date="@${start}"), ending at $(date --date="@${end}")" >> $seqres.full
106 stress_loop $end &
107 stress_pid=$!
108 freeze_loop $end &
109 freeze_pid=$!
110 repair_loop $end &
111 repair_pid=$!
112
113 # Wait until 2 seconds after the loops should have finished...
114 while [ "$(date +%s)" -lt $((end + 2)) ]; do
115         sleep 1
116 done
117
118 # ...and clean up after the loops in case they didn't do it themselves.
119 kill_loops >> $seqres.full 2>&1
120
121 echo "Loop finished at $(date)" >> $seqres.full
122 echo "Test done"
123
124 # success, all done
125 status=0
126 exit