#!/bin/sh
# DF-2997 run_fixed2.sh - fix validation on the PATCHED kernel (run as root).
# Same rig as run.sh, but wedge probes are verified to EXIT (not wedge),
# vnlru health is checked under reclaim pressure, and the documented
# pre-existing umount/VNON panic is triggered LAST (see VERDICT.md).
D=/root/df2997
cd $D
USER=maxx
UP=/tmp/df2997

vnodecount() {
	sysctl -n debug.numvnodes 2>/dev/null || echo -1
}

echo "=== DF-2997 fix-validation run $(date) ==="
uname -v
pkill fakesrv 2>/dev/null || true
sleep 1
(VERBOSE=1 ./fakesrv > $D/fakesrv2.log 2>&1 &)
sleep 1
pgrep -x fakesrv >/dev/null && echo FAKESRV_UP

mkdir -p /mnt0 /mnt1 /mnt2
chmod 0777 /mnt0 /mnt1 /mnt2
mkdir -p $UP && cp probe $UP/probe && chmod 0755 $UP/probe

# reclaim pressure from the start (A/B vs stock run.sh's end-phase only)
sysctl kern.maxvnodes=700

# ---------------- phase C: control (A/B vs baseline) ----------------
mount_nfs -o port=2049,udp 127.0.0.1:/ct /mnt0 && echo MOUNT_CT_OK
su -m $USER -c "$UP/probe m /mnt0/okdir"
su -m $USER -c "$UP/probe s /mnt0/okdir"
su -m $USER -c "$UP/probe w /mnt0/okfile"
su -m $USER -c "ls -la /mnt0"
umount /mnt0 && echo UMOUNT_CT_OK

# ---------------- phase L/M: the two leak triggers ----------------
mount_nfs -o port=2049,udp 127.0.0.1:/lk /mnt1 && echo MOUNT_LK_OK
mount_nfs -o port=2049,udp 127.0.0.1:/mk /mnt2 && echo MOUNT_MK_OK
echo "NVN base: $(vnodecount)"
su -m $USER -c "$UP/probe w /mnt1/w0"
su -m $USER -c "$UP/probe m /mnt2/m0"

# ---------------- phase W: wedge regression probes ----------------
echo "--- wedge probe 1: repeat touch on lkmal name (MUST FAIL FAST) ---"
su -m $USER -c "$UP/probe w /mnt1/w0" && echo PROBE1_EXITED_RC=$?
echo "--- wedge probe 2: repeat mkdir on mkmal name (MUST FAIL FAST) ---"
su -m $USER -c "$UP/probe m /mnt2/m0" && echo PROBE2_EXITED_RC=$?
echo "--- wedge probe 3: plain stat after neg-cache expiry ---"
sleep 5
su -m $USER -c "$UP/probe s /mnt2/m0" && echo PROBE3_EXITED_RC=$?
ps -ax -o pid,stat,wchan,comm | grep -E '[p]robe' && echo "D-STATE PROBE STILL PRESENT (BAD)" || echo "NO_PROBE_PROCESSES (GOOD)"

# ---------------- phase G: growth + reclaim under pressure ----------------
echo "NVN before G: $(vnodecount)"
i=0
while [ $i -lt 80 ]; do
	n=$(printf g%02d $i)
	su -m $USER -c "$UP/probe m /mnt2/$n" | tail -1
	i=$((i + 1))
done | sort | uniq -c
echo "NVN after  G: $(vnodecount)"
sleep 20
echo "NVN after  G+20s: $(vnodecount)"

# ---------------- phase V: vnlru health under hard pressure ----------------
/bin/ps -ax >/dev/null 2>&1; /sbin/sysctl -n debug.numvnodes >/dev/null 2>&1
/bin/sleep 0.1; /bin/cat /dev/null; /usr/bin/grep x /dev/null
N=$(vnodecount)
T=$((N * 85 / 100))
[ $T -lt 50 ] && T=50
echo "vnlru BEFORE: $(/bin/ps -ax -o pid,stat,wchan,comm | /usr/bin/grep -i '[v]nlru')"
echo "--- lowering kern.maxvnodes $N -> $T ---"
/sbin/sysctl kern.maxvnodes=$T
/bin/sleep 12
echo "vnlru AFTER:  $(/bin/ps -ax -o pid,stat,wchan,comm | /usr/bin/grep -i '[v]nlru')"
echo "--- innocent create under pressure (MUST COMPLETE + EXIT) ---"
su -m $USER -c "$UP/probe m /mnt2/gzz" && echo PROBE4_COMPLETED
/bin/sleep 4
/bin/ps -ax -o pid,stat,wchan,comm > $D/fixed.ps 2>&1
/usr/bin/grep -E '[p]robe|[c]ron' $D/fixed.ps || echo "no wedged probe/cron (GOOD)"
echo "NVN end: $(vnodecount)"
sync
echo "=== about to run the umount that hits the PRE-EXISTING VNON panic ==="
sync
umount -f /mnt2
echo "UMOUNT_SURVIVED (unexpected - see VERDICT)"
