#!/bin/sh
# DF-2642 canonical run (host side; drives the guest stage-by-stage via
# vm.sh run_root so a wedged stage cannot eat the whole run).
#
# Stages on the guest are logged to /root/df2642/*.log and pulled back
# into this evidence pack at the end.
set -x
cd "$(dirname "$0")/../../.."
VM=dfbsd-qemu/vm.sh
PK=findings/poc/DF-2642
SSH="ssh -F dfbsd-qemu/config -o ConnectTimeout=8 -o BatchMode=yes dfbsd"

vm() { $VM run_root "$@"; }

# 0. push + build
vm 'mkdir -p /root/df2642'
$SSH 'cat > /root/df2642/zero2642.c' < $PK/zero2642.c
vm 'cd /root/df2642 && cc -O2 -o zero2642 zero2642.c && echo BUILD_OK' \
    > $PK/build.log 2>&1 || exit 1

# 1. fresh SMALL image (64MB -> free_reserved ~3MB, cutoff ~1.6MB: the
#    stale-cache crossing gap is small enough to hit deterministically)
vm 'umount /mnt/h42 2>/dev/null; vnconfig -u vn1 2>/dev/null;
    rm -f /tmp/h42.img; truncate -s 64M /tmp/h42.img;
    vnconfig -c vn1 /tmp/h42.img;
    newfs_hammer2 -L DATA /dev/vn1 >/dev/null;
    mkdir -p /mnt/h42; mount_hammer2 /dev/vn1@DATA /mnt/h42;
    df /mnt/h42; cd /root/df2642 && ./zero2642 setup /mnt/h42 64' \
    > $PK/stage1_prep.log 2>&1 || exit 1

# 2. fill to <=8MB free (the fill loop's own stop condition)
vm 'cd /root/df2642 && rm -f fill.log fill2.log &&
    ./zero2642 fill /mnt/h42 90000 > fill.log 2>&1;
    echo FILL_DONE_SYNC' >> $PK/stage2_fillstart.log 2>&1 || exit 1

# 3. adaptive overwrite (foreground; races the descent through the wall)
timeout 900 $VM run_root 'cd /root/df2642 && ./zero2642 overwrite /mnt/h42 64' \
    > $PK/stage3_ov.log 2>&1

# 4. wait for the slow fill to finish
timeout 600 $VM run_root 'cd /root/df2642;
    i=0; while [ $i -lt 110 ]; do
        grep -q FILL_DONE fill.log 2>/dev/null && break;
        sleep 5; i=$((i+5));
    done; tail -3 fill.log; df /mnt/h42 || true' \
    > $PK/stage4_fillwait.log 2>&1

# 5. readback (cached view; expect ZEROS for OV_OK victims)
timeout 300 $VM run_root 'cd /root/df2642 && ./zero2642 readback /mnt/h42 64' \
    > $PK/stage5_rb_cached.log 2>&1

# 6. churn buffer cache via ROOT fs reads (bypasses the wedged mount)
timeout 1200 $VM run_root 'cd /root/df2642 && ./zero2642 churnroot /usr/src 900' \
    > $PK/stage6_churnroot.log 2>&1

# 6b. VM pressure hog (anonymous memory) to force clean-buffer recycling
timeout 200 $VM run_root 'cd /root/df2642 &&
    ( nohup ./zero2642 hog 350 > hog.log 2>&1 & ); echo HOG_STARTED' \
    > $PK/stage6b_hog.log 2>&1
sleep 15

# 7. decisive readback
timeout 300 $VM run_root 'cd /root/df2642 && ./zero2642 readback /mnt/h42 64' \
    > $PK/stage7_rb_final.log 2>&1

# 8. console evidence
$VM log 200 > $PK/console.txt 2>&1 || true

# 9. offline media proof: settle, snapshot the raw image, pull it back
timeout 400 $VM run_root 'ls -i /mnt/h42 | head -40; sleep 45;
    dd if=/tmp/h42.img of=/root/h42_final.img bs=4m 2>&1 | tail -1;
    md5 /tmp/h42.img /root/h42_final.img' \
    > $PK/stage8_media.log 2>&1
timeout 120 scp -F dfbsd-qemu/config -o ConnectTimeout=8 \
    -o BatchMode=yes dfbsd:/root/h42_final.img $PK/h42_final.img \
    >/dev/null 2>&1 || echo "scp failed"

echo "=== stage5 (cached) ==="; cat $PK/stage5_rb_cached.log
echo "=== stage7 (final)  ==="; cat $PK/stage7_rb_final.log
echo "=== ov summary ==="; grep -E "OV_OK|OV_GIVEUP|OV_WRITE_ERR" $PK/stage3_ov.log
