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 seqres=$RESULT_DIR/$seq
18 echo "QA output created by $seq"
22 status=1 # failure is the default!
23 trap "_cleanup; exit \$status" 0 1 2 3 15
31 # get standard environment, filters and checks
36 # real QA test starts here
38 _require_scratch_nocheck
39 _require_scratch_xfs_crc # needsrepair only exists for v5
40 _require_populate_commands
41 _require_libxfs_debug_flag LIBXFS_DEBUG_WRITE_CRASH
45 # Populate the filesystem
46 _scratch_populate_cached nofill >> $seqres.full 2>&1
48 max_writes=200 # 200 loops should be enough for anyone
49 nr_incr=$((13 / TIME_FACTOR))
50 test $nr_incr -lt 1 && nr_incr=1
51 for ((nr_writes = 1; nr_writes < max_writes; nr_writes += nr_incr)); do
52 # Add a tiny bit of randomness into each run
53 allowed_writes=$(( nr_writes + (RANDOM % 7) ))
54 echo "Setting debug hook to crash after $allowed_writes writes." >> $seqres.full
56 # Start a repair and force it to abort after some number of writes
57 LIBXFS_DEBUG_WRITE_CRASH=ddev=$allowed_writes \
58 _scratch_xfs_repair 2>> $seqres.full
60 if [ $res -ne 0 ] && [ $res -ne 137 ]; then
61 echo "repair failed with $res??"
63 elif [ $res -eq 0 ]; then
64 [ $nr_writes -eq 1 ] && \
65 echo "ran to completion on the first try?"
69 # Check the state of NEEDSREPAIR after repair fails. If it isn't set
70 # but repair -n says the fs is clean, then it's possible that the
71 # injected error caused it to abort immediately after the write that
72 # cleared NEEDSREPAIR.
73 if ! _check_scratch_xfs_features NEEDSREPAIR > /dev/null &&
74 ! _scratch_xfs_repair -n &>> $seqres.full; then
75 echo "NEEDSREPAIR should be set on corrupt fs"
79 # If NEEDSREPAIR is still set on the filesystem, ensure that a full run
80 # cleans everything up.
81 if _check_scratch_xfs_features NEEDSREPAIR > /dev/null; then
82 echo "Clearing NEEDSREPAIR" >> $seqres.full
83 _scratch_xfs_repair 2>> $seqres.full
84 _check_scratch_xfs_features NEEDSREPAIR > /dev/null && \
85 echo "Repair failed to clear NEEDSREPAIR on the $nr_writes writes test"
89 echo Silence is golden.