#!/bin/sh
# DF-4760 — FIX v2 validation.
#  A) no daemon, malicious holder: kldunload waits (bounded, ~5s), then
#     EBUSY with NOTHING torn down, at most ONE daemonrq_return queued
#     (devbuf +1 node), module intact; after holder closes -> clean unload.
#  B) legit daemon alive (started by `vinum create`): kldunload asks it to
#     leave ONCE; daemon exits and closes; unload proceeds (rc 0).
#  C) DF-4758 still fixed on the same binary (swapon sd -> ENXIO, vol -> OK).
set -x
date; uname -a

echo '==== A: malicious holder, no daemon ===='
vmstat -m | grep -i devbuf
/tmp/hold_daemon 20 > /tmp/v2_holder.log 2>&1 &
sleep 2
T0=$(date +%s)
kldunload vinum; RC=$?
T1=$(date +%s)
echo "KLDUNLOAD_RC=$RC elapsed=$((T1-T0))s (expect rc=1, ~5s)"
kldstat | grep -i vinum && echo "module intact (correct)"
vmstat -m | grep -i devbuf
ps -axww -o pid,stat,wchan,command | grep '[k]ldunload' || echo "no stuck kldunload"
sleep 20				# let holder finish
kldunload vinum; echo "KLDUNLOAD_RC2=$? (expect 0 after close)"
kldstat | grep -i vinum || echo "module gone cleanly"

echo '==== B: legit daemon path ===='
dd if=/tmp/label.bin of=/dev/md0 bs=512 seek=1 conv=notrunc; sleep 1
printf 'drive d1 device /dev/md0s0a\n' > /tmp/v2c1
printf 'volume v0\nplex name p0 org concat\nsd name s0 drive d1 plex p0 len 1m\nsd name s1 drive d1 plex p0 len 1m\nsd name s2 drive d1 plex p0 len 1m\nsd name s3 drive d1 plex p0 len 1m\nsd name s4 drive d1 plex p0 len 1m\nsd name s5 drive d1 plex p0 len 1m\n' > /tmp/v2c2
vinum create -f /tmp/v2c1; sleep 2
vinum create -f /tmp/v2c2; sleep 2
ps -axww | grep '[v]inum daemon' && echo "daemon running"
vmstat -m | grep -i devbuf
T0=$(date +%s)
kldunload vinum; RC=$?
T1=$(date +%s)
echo "KLDUNLOAD_RC=$RC elapsed=$((T1-T0))s (expect rc=0, few s)"
kldstat | grep -i vinum || echo "module gone cleanly (daemon asked once, left)"
ps -axww | grep '[v]inum daemon' || echo "daemon exited"
vmstat -m | grep -i devbuf
dmesg | tail -3

echo '==== C: DF-4758 still fixed on this binary ===='
kldload vinum; sleep 1
vinum create -f /tmp/v2c1; sleep 2
vinum create -f /tmp/v2c2; sleep 2
/tmp/df4758_swapon /dev/vinum/sd/s0 /dev/vinum/sd/s4 /dev/vinum/vol/v0
swapoff /dev/vinum/vol/v0 2>&1
date
