Add test exercising the totl recompute ioctl.

Basic validation for the recompute-xattr-total ioctl through the
totl-delta-inject ioctl. Takes a few different corrective actions that
are plausible - simple drifted values, and a stray orphan totl.

The test validates that the kmod dmesg output matches what was
expected since that's our proof that repair happened, but the actual
warnings are filtered from logs during test to not fail our test
case otherwise.

Signed-off-by: Auke Kok <auke.kok@versity.com>
This commit is contained in:
Auke Kok
2026-04-30 16:14:38 -07:00
parent 1e5cc26bda
commit 85ecc136c7
4 changed files with 108 additions and 0 deletions

View File

@@ -171,6 +171,9 @@ t_filter_dmesg()
# orphan log trees reclaim is handled, not an error
re="$re|scoutfs .* reclaiming orphan log trees"
# recompute-xattr-total logs every corrective delta it applies
re="$re|scoutfs .* warning: totl recompute applying delta .*"
# fencing tests force unmounts and trigger timeouts
re="$re|scoutfs .* forcing unmount"
re="$re|scoutfs .* reconnect timed out"

View File

@@ -0,0 +1,23 @@
== setup three files contributing to totl 8888.0.0
== merge baseline into fs_root
8888.0.0 = 42, 3
== recompute on a clean baseline is a no-op
8888.0.0 = 42, 3
== inject (+128, +2) corrupts totl 8888.0.0
8888.0.0 = 170, 5
== recompute restores 8888.0.0
totl recompute applying delta total=-128 count=-2 to key 12.8888.0.0.0.0 (was total=170 count=5, recomputed total=42 count=3)
8888.0.0 = 42, 3
== inject (-50, +1) corrupts totl 8888.0.0 again
8888.0.0 = -8, 4
== recompute restores 8888.0.0
totl recompute applying delta total=50 count=-1 to key 12.8888.0.0.0.0 (was total=-8 count=4, recomputed total=42 count=3)
8888.0.0 = 42, 3
== recompute on an unused key is a no-op
8888.0.0 = 42, 3
== inject (+7, +1) at unused key 8888.1.1 then recompute clears it
8888.0.0 = 42, 3
8888.1.1 = 7, 1
totl recompute applying delta total=-7 count=-1 to key 12.8888.0.1.1.0 (was total=7 count=1, recomputed total=0 count=0)
8888.0.0 = 42, 3
== cleanup

View File

@@ -30,6 +30,7 @@ basic-xattr-indx.sh
quota.sh
totl-merge-read.sh
totl-delta-inject.sh
totl-recompute.sh
lock-refleak.sh
lock-shrink-consistency.sh
lock-shrink-read-race.sh

View File

@@ -0,0 +1,81 @@
#
# Exercise scoutfs recompute-xattr-total. Uses totl-delta-inject(1) to seed
# corruption.
#
t_require_commands setfattr scoutfs sync rm touch totl-delta-inject
# force a log merge then read-xattr-totals filtered to our own keys
read_totals()
{
t_force_log_merge
sync
echo 1 > $(t_debugfs_path)/drop_weak_item_cache
scoutfs read-xattr-totals -p "$T_M0" | \
grep -E '^8888\.' || true
}
# Print recompute warnings emitted since the last snapshot, with the
# volatile timestamp/fsid/rid prefix stripped, for golden comparison.
DMESG_SNAP="$T_TMPDIR/dmesg.recompute.snap"
dmesg > "$DMESG_SNAP"
recompute_warn()
{
local cur="$T_TMPDIR/dmesg.recompute.cur"
dmesg > "$cur"
diff "$DMESG_SNAP" "$cur" | \
sed -n 's/^> \[ *[0-9.]\+\] scoutfs [^ ]\+ warning: \(totl recompute applying delta .*\)$/\1/p'
mv "$cur" "$DMESG_SNAP"
}
echo "== setup three files contributing to totl 8888.0.0"
touch "$T_D0/f1" "$T_D0/f2" "$T_D0/f3"
setfattr -n scoutfs.totl.inj.8888.0.0 -v 2 "$T_D0/f1"
setfattr -n scoutfs.totl.inj.8888.0.0 -v 8 "$T_D0/f2"
setfattr -n scoutfs.totl.inj.8888.0.0 -v 32 "$T_D0/f3"
echo "== merge baseline into fs_root"
read_totals
echo "== recompute on a clean baseline is a no-op"
scoutfs recompute-xattr-total -p "$T_M0" 8888.0.0
recompute_warn
read_totals
echo "== inject (+128, +2) corrupts totl 8888.0.0"
totl-delta-inject "$T_M0" 8888.0.0 128 2
read_totals
echo "== recompute restores 8888.0.0"
scoutfs recompute-xattr-total -p "$T_M0" 8888.0.0
recompute_warn
read_totals
echo "== inject (-50, +1) corrupts totl 8888.0.0 again"
totl-delta-inject "$T_M0" 8888.0.0 -50 1
read_totals
echo "== recompute restores 8888.0.0"
scoutfs recompute-xattr-total -p "$T_M0" 8888.0.0
recompute_warn
read_totals
echo "== recompute on an unused key is a no-op"
scoutfs recompute-xattr-total -p "$T_M0" 8888.1.1
recompute_warn
read_totals
echo "== inject (+7, +1) at unused key 8888.1.1 then recompute clears it"
totl-delta-inject "$T_M0" 8888.1.1 7 1
read_totals
scoutfs recompute-xattr-total -p "$T_M0" 8888.1.1
recompute_warn
read_totals
echo "== cleanup"
rm -f "$T_D0/f1" "$T_D0/f2" "$T_D0/f3"
read_totals
t_pass