2 # SPDX-License-Identifier: GPL-2.0-or-later
3 # Copyright (c) 2021 Oracle. All Rights Reserved.
7 # Populate a filesystem with all types of metadata, then run repair with the
8 # libxfs write failure trigger set to go after a single write. Check that the
9 # injected error trips, causing repair to abort, that needsrepair is set on the
10 # fs, the kernel won't mount; and that a non-injecting repair run clears
11 # needsrepair and makes the filesystem mountable again.
13 # Repeat with the trip point set to successively higher numbers of writes until
14 # we hit ~200 writes or repair manages to run to completion without tripping.
17 _begin_fstest auto repair
19 # Import common functions.
23 # real QA test starts here
25 _require_scratch_nocheck
26 _require_scratch_xfs_crc # needsrepair only exists for v5
27 _require_populate_commands
28 _require_libxfs_debug_flag LIBXFS_DEBUG_WRITE_CRASH
30 # Populate the filesystem
31 _scratch_populate_cached nofill >> $seqres.full 2>&1
33 max_writes=200 # 200 loops should be enough for anyone
34 nr_incr=$((13 / TIME_FACTOR))
35 test $nr_incr -lt 1 && nr_incr=1
36 for ((nr_writes = 1; nr_writes < max_writes; nr_writes += nr_incr)); do
37 # Add a tiny bit of randomness into each run
38 allowed_writes=$(( nr_writes + (RANDOM % 7) ))
39 echo "Setting debug hook to crash after $allowed_writes writes." >> $seqres.full
41 # Start a repair and force it to abort after some number of writes
42 LIBXFS_DEBUG_WRITE_CRASH=ddev=$allowed_writes \
43 _scratch_xfs_repair 2>> $seqres.full
45 if [ $res -ne 0 ] && [ $res -ne 137 ]; then
46 echo "repair failed with $res??"
48 elif [ $res -eq 0 ]; then
49 [ $nr_writes -eq 1 ] && \
50 echo "ran to completion on the first try?"
54 # Check the state of NEEDSREPAIR after repair fails. If it isn't set
55 # but repair -n says the fs is clean, then it's possible that the
56 # injected error caused it to abort immediately after the write that
57 # cleared NEEDSREPAIR.
58 if ! _check_scratch_xfs_features NEEDSREPAIR > /dev/null &&
59 ! _scratch_xfs_repair -n &>> $seqres.full; then
60 echo "NEEDSREPAIR should be set on corrupt fs"
64 # If NEEDSREPAIR is still set on the filesystem, ensure that a full run
65 # cleans everything up.
66 if _check_scratch_xfs_features NEEDSREPAIR > /dev/null; then
67 echo "Clearing NEEDSREPAIR" >> $seqres.full
68 _scratch_xfs_repair 2>> $seqres.full
69 _check_scratch_xfs_features NEEDSREPAIR > /dev/null && \
70 echo "Repair failed to clear NEEDSREPAIR on the $nr_writes writes test"
74 echo Silence is golden.