#!/bin/sh
# DF-2645 race stress driver (stock kernel).
# Build a directory tree deep enough for nested indirect blocks, sparsify
# it (mass delete), then race appends against continuous syncs so the
# flusher's indirect_maintenance collapse overlaps a concurrent child
# (file inode) chain modify.
#
# Expected on race win: panic with KKASSERT at hammer2_chain_repchange
# (hammer2_chain.c:2314) or "hammer2: debug repchange" prints followed by
# a crash; serial console captures it.
#
# usage: sh run_df2645.sh <minutes> <mode>
set -e
MIN=${1:-10}
MODE=${2:-1}
cd /root/df2645
cc -O2 -o stress2645 stress2645.c
cc -O2 -o mknames mknames.c

truncate -s 512M /root/h2645.img
vnconfig -c -S 512m -T vn2 /root/h2645.img
newfs_hammer2 -L DATA /dev/vn2 >/dev/null 2>&1
mkdir -p /mnt/h2645
mount_hammer2 /dev/vn2@DATA /mnt/h2645

echo "building 6000-file tree (random dirhash spread)..."
./mknames 6000 > /root/n2645.txt
mkdir -p /mnt/h2645/d
./mkfiles /mnt/h2645/d /root/n2645.txt 4000
sync
echo "tree built: $(ls /mnt/h2645/d | wc -l) entries"

echo "sparsifying: deleting 97% in randomized order..."
./delsome /mnt/h2645/d /root/n2645.txt 70
sync
echo "survivors: $(ls /mnt/h2645/d | wc -l)"

echo "starting stress (mode $MODE, ${MIN} min)..."
./stress2645 /mnt/h2645/d 4 $MODE > /root/stress2645.log 2>&1 &
SPID=$!
( while :; do sync; sleep 0.05; done ) > /root/syncloop.log 2>&1 &
LPID=$!
sleep $((MIN*60))
kill $SPID $LPID 2>/dev/null || true
pkill -f stress2645 2>/dev/null || true
sleep 2
sync || true
echo "stress done without panic"
ls /mnt/h2645/d | wc -l
umount /mnt/h2645 && echo UMOUNT_OK
vnconfig -u vn2
