From 45b923dfacae0d907e1472033275901538dabcd2 Mon Sep 17 00:00:00 2001 From: Krzysztof kuhy Rudnicki Date: Sat, 22 Aug 2026 21:28:02 +0200 Subject: [PATCH] vmbox: wait for qemu to release the overlay before recreating it `vm reset` killed the VM and immediately recreated the overlay, without waiting for the process to actually exit. The next boot then read a half-detached file and failed with "sandbox did not become reachable" -- a symptom that appears one step AFTER the cause and says nothing about it. Reset itself was always correct (verified by hand: after `rm -rf --no-preserve-root /etc /usr`, a reset guest reports NAME="Arch Linux" and has /usr/bin/bash back). This only bit when a reset followed a still-shutting-down VM closely enough to race it, which is exactly what the destructive demo does. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01VdyMBGCrGVGDWtJ9xe48f3 --- vmbox/lib/overlay.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/vmbox/lib/overlay.sh b/vmbox/lib/overlay.sh index b1f7e5f..f50e78e 100644 --- a/vmbox/lib/overlay.sh +++ b/vmbox/lib/overlay.sh @@ -94,6 +94,16 @@ overlay_reset() { vm_is_running "$name" && _overlay_stop "$name" + # Wait for the qemu process to actually release the overlay. Recreating it + # while the old process still has it open leaves the next boot reading a + # half-detached file, which surfaces much later as "did not become + # reachable" rather than as an error here. + local waited=0 pid + pid="$(cat "$(vm_pidfile "$name")" 2>/dev/null || true)" + while [[ -n "$pid" ]] && kill -0 "$pid" 2>/dev/null && (( waited < 30 )); do + sleep 1; waited=$(( waited + 1 )) + done + # Discard everything the guest did: the overlay holds 100% of its writes. _overlay_create_disk "$name" rm -f "$(vm_dir "$name")"/serial.*.log "$(vm_events "$name")" "$(vm_pidfile "$name")"