mirror of
https://github.com/versity/scoutfs.git
synced 2026-09-30 03:36:29 +00:00
Test case for wedged full meta allocators.
Reproduce the freed-list commit deadlock and show a fixed server recovers. The alloc_fill_freed_list trigger stuffs both server_meta_freed heads to near-full in a single commit. It claims runs of free blocks and appends them straight into the head blocks, leaking whatever isn't used. Filling both heads in one commit makes the wedge reproducible. There's no window for the drain to empty one head before the other fills. An unfixed server is left with both heads full and wedges on the next commit. A fixed server drains them and stays live. Signed-off-by: Auke Kok <auke.kok@versity.com>
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
== make throwaway scratch fs
|
||||
== stuff both server freed heads full in one commit
|
||||
== confirm both heads were stuffed (not a no-op)
|
||||
both freed heads stuffed
|
||||
== a fixed server drains them and keeps making progress
|
||||
one
|
||||
two
|
||||
== cleanup scratch fs
|
||||
@@ -62,6 +62,7 @@ client-unmount-recovery.sh
|
||||
createmany-parallel-mounts.sh
|
||||
archive-light-cycle.sh
|
||||
block-stale-reads.sh
|
||||
freed-list-wedge.sh
|
||||
inode-deletion.sh
|
||||
renameat2-noreplace.sh
|
||||
xfstests.sh
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
#
|
||||
# Destructive: the alloc_fill_freed_list trigger claims free blocks and leaks
|
||||
# them into both server_meta_freed heads in one commit, filling them near-full.
|
||||
# Runs on a scratch fs; mkfs before re-use.
|
||||
#
|
||||
# A fixed server drains the full heads and stays live; an unfixed server wedges
|
||||
# on the next commit and hangs until the harness times it out.
|
||||
#
|
||||
|
||||
scr_counter() {
|
||||
cat "$(t_sysfs_path_from_mnt "$T_MSCR")/counters/$1"
|
||||
}
|
||||
|
||||
echo "== make throwaway scratch fs"
|
||||
t_scratch_mkfs
|
||||
t_scratch_mount
|
||||
|
||||
echo "== stuff both server freed heads full in one commit"
|
||||
old=$(scr_counter alloc_freed_fill)
|
||||
|
||||
echo 1 > "/sys/kernel/debug/scoutfs/$(t_ident_from_mnt "$T_MSCR")/trigger/alloc_fill_freed_list"
|
||||
echo one > "$T_MSCR/one"; sync
|
||||
|
||||
echo "== confirm both heads were stuffed (not a no-op)"
|
||||
filled=$(($(scr_counter alloc_freed_fill) - old))
|
||||
test "$filled" -ge 2 && echo "both freed heads stuffed" || \
|
||||
echo "stuff was a no-op ($filled heads)"
|
||||
|
||||
echo "== a fixed server drains them and keeps making progress"
|
||||
# an unfixed server wedges on this commit
|
||||
echo two > "$T_MSCR/two"; sync
|
||||
cat "$T_MSCR/one" "$T_MSCR/two"
|
||||
|
||||
rm -f "$T_MSCR/one" "$T_MSCR/two"; sync
|
||||
|
||||
echo "== cleanup scratch fs"
|
||||
t_scratch_umount
|
||||
|
||||
t_pass
|
||||
Reference in New Issue
Block a user