From e37f1d6278cc2e867626da69d38e4a9ccc0071ff Mon Sep 17 00:00:00 2001 From: Tinic Uro Date: Thu, 1 Oct 2026 10:00:19 -0700 Subject: [PATCH 1/2] tools: winuae-run.sh claims its drive; launcher_order covers WinUAE winuae-run.sh wiped its staging drive (rm -rf "$HD", before staging and again before the copy back) with no drive claim. It now claims the drive right after HD is set, before the ROM push and the first wipe. Backend is none: the guest's network, bridged or not, lives on the Windows host, so there is no local bridge to claim and a host without flock(1) degrades with a warning rather than refusing. bridge-lock-selftest launcher_order: - emulator start lines come from an EMU_START table (amiberry, winuae); discovery is the union of the rows - drive claim < emulator start is asserted for every launcher, not only bridged ones - drive claim < first destructive line, where lines run through ssh act on the remote host and are skipped - a discovered launcher with no non-comment start fails (no-emulator-start); amiberry-run, run-workbench and winuae-run must be discovered (not-discovered otherwise) Co-Authored-By: Claude Opus 5.5 --- tools/bridge-lock-selftest.sh | 41 +++++++++++++++++++++++------------ tools/winuae-run.sh | 11 ++++++++++ 2 files changed, 38 insertions(+), 14 deletions(-) diff --git a/tools/bridge-lock-selftest.sh b/tools/bridge-lock-selftest.sh index e348aa58a..fba4360a2 100755 --- a/tools/bridge-lock-selftest.sh +++ b/tools/bridge-lock-selftest.sh @@ -654,14 +654,26 @@ else fi echo "lock_order_took_s=$took" -# EVERY LAUNCHER, statically: any script that starts the emulator claims its +# EVERY LAUNCHER, statically: any script that starts an emulator claims its # drive before its first destructive step (a wipe, an extraction, a mkdir or # cp restage, the shared Workbench build, Xvfb, tcpdump, a kill or the -# emulator), and a bridged one claims the bridge after the drive and before -# the emulator. Found by what they do, so a new launcher with no claim fails -# here rather than waiting for a reviewer to spot it. -START='(exec|setsid) +(setsid +)?"[$]AMIBERRY"|"[$]AMIBERRY" +(--log +)?-f|start_emulator "' -DESTRUCTIVE_ALL="$DESTRUCTIVE|lha +x|tar x" +# emulator) and before the emulator itself, and a bridged one claims the +# bridge after the drive and before the emulator. Found by what they do, so +# a new launcher with no claim fails here rather than waiting for a reviewer +# to spot it. A line run through ssh acts on the remote host, not on this +# host's drive, and is not a destructive step here. +# +# Emulator -> the line that starts it. Discovery is the union of the rows; +# a launcher's emulator line is its first non-comment match of any row. +declare -A EMU_START=( + [amiberry]='(exec|setsid) +(setsid +)?"[$]AMIBERRY"|"[$]AMIBERRY" +(--log +)?-f|start_emulator "' + [winuae]='ssh .*powershell .*run[.]ps1 -Config ' +) +# Launchers discovery must find; a pattern that drifts from one fails here. +KNOWN_LAUNCHERS="tools/amiberry-run.sh install/test/run-workbench.sh tools/winuae-run.sh" +START="" +for emu in "${!EMU_START[@]}"; do START="${START:+$START|}${EMU_START[$emu]}"; done +DESTRUCTIVE_ALL="$DESTRUCTIVE|lha +x|tar x|$START" lo_bad="" launchers=$(cd "$ROOT" && grep -rlE "$START" --include='*.sh' tools tests install | grep -v '^tools/bridge-lock-selftest\.sh$' | sort) @@ -669,24 +681,25 @@ for f in $launchers; do from=1 [ "$f" != tests/tools/console-instance.sh ] || from=$(grep -n '^esac' "$ROOT/$f" | head -1 | cut -d: -f1) - first() { awk -v from="$from" -v re="$1" ' - NR >= from && $0 !~ /^[[:space:]]*#/ && $0 ~ re { print NR; exit }' "$ROOT/$f"; } + first() { awk -v from="$from" -v re="$1" -v skip="${2:-^$}" ' + NR >= from && $0 !~ /^[[:space:]]*#/ && $0 !~ skip && $0 ~ re { print NR; exit }' "$ROOT/$f"; } d=$(first '^[[:space:]]*rig_claim_drive ') b=$(first '^[[:space:]]*rig_claim_bridge ') - x=$(first "$DESTRUCTIVE_ALL") + x=$(first "$DESTRUCTIVE_ALL" '^[[:space:]]*ssh ') e=$(first "$START") echo "launcher_$(basename "$f" .sh)=drive:${d:-none} bridge:${b:-none} first_destructive:${x:-none} emulator:${e:-none}" + [ -n "$e" ] || { lo_bad="$lo_bad $f:no-emulator-start"; continue; } [ -n "$d" ] || { lo_bad="$lo_bad $f:no-drive-claim"; continue; } + [ "$d" -lt "$e" ] || lo_bad="$lo_bad $f:drive($d)>=emulator($e)" [ -z "$x" ] || [ "$d" -lt "$x" ] || lo_bad="$lo_bad $f:drive($d)>=destructive($x)" if [ -n "$b" ]; then [ "$d" -lt "$b" ] || lo_bad="$lo_bad $f:bridge($b)-before-drive($d)" - [ -z "$e" ] || [ "$b" -lt "$e" ] || lo_bad="$lo_bad $f:bridge($b)>=emulator($e)" + [ "$b" -lt "$e" ] || lo_bad="$lo_bad $f:bridge($b)>=emulator($e)" fi done -case "$launchers" in - *tools/amiberry-run.sh*install/test/run-workbench.sh*|*install/test/run-workbench.sh*tools/amiberry-run.sh*) ;; - *) lo_bad="$lo_bad discovery-missed-known-launchers" ;; -esac +for f in $KNOWN_LAUNCHERS; do + grep -qxF "$f" <<< "$launchers" || lo_bad="$lo_bad $f:not-discovered" +done if [ -z "$lo_bad" ]; then kv launcher_order ok else diff --git a/tools/winuae-run.sh b/tools/winuae-run.sh index a467548ea..1bf8c67d2 100755 --- a/tools/winuae-run.sh +++ b/tools/winuae-run.sh @@ -166,6 +166,17 @@ HD="$ROOT/build/winuae-testhd-$TAG" RRUN="$RROOT\\run\\$TAG" RRUN_FWD="$RROOT_FWD/run/$TAG" +# THE DRIVE, before the staging below wipes it and before the copy back +# wipes it again (tools/emu-rig-lock.sh, rig_claim_drive). Only the local +# staging directory is arbitrated here: the guest's network, bridged or not, +# is on $HOST, where this host's locks mean nothing -- hence no bridge claim +# and backend none, which degrades with a warning rather than refusing on a +# host with no flock(1). +# shellcheck source=emu-rig-lock.sh +. "$ROOT/tools/emu-rig-lock.sh" +rig_claim_drive "$HD" "winuae $TAG (${AMINETXDUO_WINUAE_A2065:-slirp} on $HOST) in $ROOT" \ + none || exit $? + # ------------------------------------------------------------------- models -- # # chipmem_size and friends are in 512 KB units despite what WinUAE's own help From 44c9dff7f47cd9ed83d706892db1be2f85d7f966 Mon Sep 17 00:00:00 2001 From: Tinic Uro Date: Thu, 1 Oct 2026 10:06:49 -0700 Subject: [PATCH 2/2] rig: rig_claim_drive refuses an omitted backend An omitted or empty backend read as unbridged, so a caller that forgot it got the no-flock warning and an unlocked drive. It now returns 2; every caller already passes one. noflock_drive asserts the refusal. Co-Authored-By: Claude Opus 5.5 --- tools/bridge-lock-selftest.sh | 10 ++++++---- tools/emu-rig-lock.sh | 1 + 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/tools/bridge-lock-selftest.sh b/tools/bridge-lock-selftest.sh index fba4360a2..d3fc66e51 100755 --- a/tools/bridge-lock-selftest.sh +++ b/tools/bridge-lock-selftest.sh @@ -259,24 +259,26 @@ else fi # The drive lock degrades without flock(1) when nothing is on the wire: one -# warning and 0, unlocked. On a bridged backend it stays strict. Through +# warning and 0, unlocked. On a bridged backend it stays strict, and an +# omitted backend is refused rather than read as unbridged. Through # amiberry-run.sh a SLIRP run gets past the drive with the warning; its 2 is # rig_claim_port's, which needs flock(1) on main as well. dn=$(PATH="$S/noflock" AMINETXDUO_BRIDGE_LOCK="$S/bridge.lock" bash -c ' . "$1/tools/emu-rig-lock.sh" rig_claim_drive "$2/nf-drive" nf slirp 2> "$2/nf-slirp.err"; a=$? rig_claim_drive "$2/nf-drive" nf ens18 2> /dev/null; b=$? - echo "$a,$b"' _ "$ROOT" "$S") + rig_claim_drive "$2/nf-drive" nf 2> /dev/null; c=$? + echo "$a,$b,$c"' _ "$ROOT" "$S") : > "$EV" PATH="$S/noflock" run C noflockslirp slirp -if [ "$dn" = 0,2 ] && +if [ "$dn" = 0,2,2 ] && grep -q '^no flock: drive .*nf-drive not locked; do not run two of this tag at once$' \ "$S/nf-slirp.err" && grep -q '^no flock: drive .*amiberry-testhd-ifsurvive not locked' "$S/noflockslirp.out" && ! grep -q 'drive lock' "$S/noflockslirp.out"; then kv noflock_drive ok else - kv noflock_drive "wrong:slirp,bridged=$dn:run=$(cat "$S/noflockslirp.rc")" + kv noflock_drive "wrong:slirp,bridged,omitted=$dn:run=$(cat "$S/noflockslirp.rc")" fi : > "$EV" diff --git a/tools/emu-rig-lock.sh b/tools/emu-rig-lock.sh index ff031f3ed..d41ce3002 100755 --- a/tools/emu-rig-lock.sh +++ b/tools/emu-rig-lock.sh @@ -417,6 +417,7 @@ rig_drive_path() { # dir rig_claim_drive() { # dir who backend [wait] [ -n "${1:-}" ] || { echo "rig_claim_drive: no drive named" >&2; return 2; } + [ -n "${3:-}" ] || { echo "rig_claim_drive: no backend given" >&2; return 2; } [ -z "$RIG_DRIVE_FD" ] || return 0 if ! rig_have_flock; then rig_backend_bridged "${3:-}" && { rig_no_flock; return 2; }