From f989375e12f60b2e9627dddb01ecfa1f11ff7fa3 Mon Sep 17 00:00:00 2001 From: Bruce Ashfield Date: Mon, 8 Jun 2026 18:32:15 +0000 Subject: vrunner: use QMP quit before SIGTERM in daemon_stop escalation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the SHUTDOWN-via-virtio-serial poll window expires and the QEMU process is still alive, send a QMP quit before SIGTERMing. Functionally near-equivalent to SIGTERM at the process level (both converge on qemu_system_killed() and a block-layer flush) but goes through QEMU's monitor interface, which is the same mechanism hv_idle_shutdown() already uses for idle-timeout shutdowns. Unifying the two escalation paths makes the code easier to reason about — one channel for "ask QEMU to exit cleanly," one fallback for "the monitor isn't responding." QMP quit is NOT a replacement for the virtio-serial ===SHUTDOWN=== command: it stops QEMU without giving the guest a chance to run its own graceful_shutdown() (which is what cleanly unmounts the state disk). It's only an improvement over SIGTERM as the *fallback* when the guest hasn't responded to the SHUTDOWN command within the poll window. The full architectural fix — QMP system_powerdown driving an ACPI handler in the guest that calls graceful_shutdown() — needs guest-side acpid wiring and is tracked separately. SIGTERM and SIGKILL remain as further fallbacks for cases where QMP itself is unresponsive (e.g. older configs without a QMP socket, or QEMU hung in a state where the monitor stops servicing commands). Signed-off-by: Bruce Ashfield --- recipes-containers/vcontainer/files/vrunner.sh | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/recipes-containers/vcontainer/files/vrunner.sh b/recipes-containers/vcontainer/files/vrunner.sh index 92db55d2..680fe509 100755 --- a/recipes-containers/vcontainer/files/vrunner.sh +++ b/recipes-containers/vcontainer/files/vrunner.sh @@ -633,7 +633,23 @@ daemon_stop() { done fi - # If still running after the graceful window, escalate. + # If still running after the graceful window, escalate via QMP quit. + # Functionally similar to SIGTERM at the QEMU-process level (both + # converge on qemu_system_killed and a block-layer flush), but goes + # through QEMU's monitor interface — the same path hv_idle_shutdown() + # uses. Keeps the two escalation paths consistent. + if kill -0 "$pid" 2>/dev/null; then + local qmp_sock="$DAEMON_SOCKET_DIR/qmp.sock" + if [ -S "$qmp_sock" ]; then + log "INFO" "Sending QMP quit..." + echo '{"execute":"qmp_capabilities"}{"execute":"quit"}' | \ + socat - "UNIX-CONNECT:$qmp_sock" >/dev/null 2>&1 || true + sleep 2 + fi + fi + + # If QMP quit didn't take (or no QMP socket — older configs), fall + # back to SIGTERM. if kill -0 "$pid" 2>/dev/null; then log "INFO" "Sending SIGTERM..." kill "$pid" 2>/dev/null || true -- cgit v1.2.3-54-g00ecf