#!/bin/csh
# DF-2832 stock-kernel race harness (run as ROOT inside the guest).
#
# Unprivileged side : nobody runs dirty_writer on the hammer2 test mount,
#                     driving hammer2_pfs_memory_wait() -> trigger_syncer*().
# Privileged side   : this script loops `umount -f` + remount, tearing down
#                     and re-creating the syncer ctx (vn_syncer_thr_stop ->
#                     hashdestroy+kfree) while the unpriv trigger storm runs.
#
# usage: csh race_stock.csh <iterations>
set IMG=/root/h2img
set MNT=/mnt/t
if ($#argv > 0) then
	set ITER=$1
else
	set ITER=40
endif

# one-time setup: vn-backed hammer2 filesystem
rm -f $IMG
dd if=/dev/zero of=$IMG bs=1m count=0 seek=512 >&/dev/null
vnconfig -u vn0 >&/dev/null
vnconfig -c -S 512m vn0 $IMG
newfs_hammer2 /dev/vn0 >&/dev/null
mkdir -p $MNT

# root setup: make hammer2_pfs_memory_wait() stall trivially so the
# unprivileged writer drives trigger_syncer()/trigger_syncer_start()
sysctl vfs.hammer2.limit_dirty_chains=32 >&/dev/null
sysctl vfs.hammer2.limit_dirty_inodes=8 >&/dev/null

@ n = 0
while ($n < $ITER)
	# unprivileged writer storm (4 threads, survive mount cycling)
	foreach i (1 2 3 4)
		su -m nobody -c "/tmp/df2832/dirty_writer /mnt/t/w$i.dat 300 >&/dev/null &"
	end

	mount_hammer2 /dev/vn0 /mnt/t >&/dev/null
	if ($status != 0) then
		echo "[$n] mount failed"
		sleep 1
		umount -f /mnt/t >&/dev/null
		@ n = $n + 1
		continue
	endif
	chmod 777 $MNT
	sleep 1			# let dirty chains pile up past the low limit
	umount -f /mnt/t
	@ n = $n + 1
end

# cleanup
killall -u nobody dirty_writer >&/dev/null
vnconfig -u vn0 >&/dev/null
echo "race_stock: done after $ITER iterations"
