#!/bin/sh
# DF-3116 focused wedge run -- ON THE GUEST as root.
# Attribution-clean: no orphans, no prior umount -f, fresh image.
# Race 30s (deep-chain dir renames + creates), then verify racers are
# DEAD and try to unmount with a watchdog.  A clean msdosfs mount
# unmounts instantly when no process holds it.
set -u
IMG=/tmp/df3116.img
VND=/dev/vn0
MNT=/fatrace
P1=$MNT/p1
T=/tmp/df3116
DEPTH=100
SECS=30

uname -a
dd if=/dev/zero of=$IMG bs=1m count=512 2>&1 | tail -1
vnconfig -c $VND $IMG
newfs_msdos -F 32 -c 8 $VND || exit 9
mkdir -p $MNT
mount_msdos -u 65534 -g 65534 -m 0777 $VND $MNT || exit 9
mkdir -p $P1
D=$MNT/deep; i=0
while [ $i -lt $DEPTH ]; do i=$((i+1)); D=$D/l$i; done
mkdir -p $D
P2=$D

echo "--- RACE start $(date) ---"
su -m nobody -c "$T/trigger bouncer $P1 $P2 $SECS" > /tmp/b.log 2>&1 &
BP=$!
su -m nobody -c "$T/trigger creator $P2 $SECS" > /tmp/c2.log 2>&1 &
C2=$!
su -m nobody -c "$T/trigger creator $P1 $SECS" > /tmp/c1.log 2>&1 &
C1=$!
wait $C2; echo "c2 rc=$?"
wait $C1; echo "c1 rc=$?"
wait $BP; echo "bp rc=$?"
cat /tmp/b.log /tmp/c1.log /tmp/c2.log
echo "--- racers done $(date); leftover procs: ---"
ps aux | grep trigger | grep -v grep || echo none
sleep 2
echo "--- umount with 20s watchdog ---"
( umount $MNT ) &
UP=$!
n=0
while [ $n -lt 20 ]; do
	kill -0 $UP 2>/dev/null || break
	sleep 1; n=$((n+1))
done
if kill -0 $UP 2>/dev/null; then
	echo "WEDGE-CONFIRMED: umount still hanging after ${n}s with zero holders"
	kill -9 $UP 2>/dev/null
	dmesg | tail -20 > /tmp/dmesg.wedge
	tail -20 /tmp/dmesg.wedge
	echo "--- guest still alive? ---"
	date
	ps aux | head -3
else
	wait $UP; URC=$?
	echo "umount completed rc=$URC after ${n}s"
	fsck_msdosfs -p $VND; echo "fsck rc=$?"
	vnconfig -u $VND
fi
