diff options
| author | Bruce Ashfield <bruce.ashfield@gmail.com> | 2026-06-08 18:32:15 +0000 |
|---|---|---|
| committer | Bruce Ashfield <bruce.ashfield@gmail.com> | 2026-06-12 02:58:55 +0000 |
| commit | f989375e12f60b2e9627dddb01ecfa1f11ff7fa3 (patch) | |
| tree | b18eae7041aa3890c9b9f34a7e6323a858264406 | |
| parent | 23da02f0189cc046def58a43117b50d7918e62e1 (diff) | |
| download | meta-virtualization-f989375e12f60b2e9627dddb01ecfa1f11ff7fa3.tar.gz | |
vrunner: use QMP quit before SIGTERM in daemon_stop escalation
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 <bruce.ashfield@gmail.com>
| -rwxr-xr-x | recipes-containers/vcontainer/files/vrunner.sh | 18 |
1 files changed, 17 insertions, 1 deletions
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() { | |||
| 633 | done | 633 | done |
| 634 | fi | 634 | fi |
| 635 | 635 | ||
| 636 | # If still running after the graceful window, escalate. | 636 | # If still running after the graceful window, escalate via QMP quit. |
| 637 | # Functionally similar to SIGTERM at the QEMU-process level (both | ||
| 638 | # converge on qemu_system_killed and a block-layer flush), but goes | ||
| 639 | # through QEMU's monitor interface — the same path hv_idle_shutdown() | ||
| 640 | # uses. Keeps the two escalation paths consistent. | ||
| 641 | if kill -0 "$pid" 2>/dev/null; then | ||
| 642 | local qmp_sock="$DAEMON_SOCKET_DIR/qmp.sock" | ||
| 643 | if [ -S "$qmp_sock" ]; then | ||
| 644 | log "INFO" "Sending QMP quit..." | ||
| 645 | echo '{"execute":"qmp_capabilities"}{"execute":"quit"}' | \ | ||
| 646 | socat - "UNIX-CONNECT:$qmp_sock" >/dev/null 2>&1 || true | ||
| 647 | sleep 2 | ||
| 648 | fi | ||
| 649 | fi | ||
| 650 | |||
| 651 | # If QMP quit didn't take (or no QMP socket — older configs), fall | ||
| 652 | # back to SIGTERM. | ||
| 637 | if kill -0 "$pid" 2>/dev/null; then | 653 | if kill -0 "$pid" 2>/dev/null; then |
| 638 | log "INFO" "Sending SIGTERM..." | 654 | log "INFO" "Sending SIGTERM..." |
| 639 | kill "$pid" 2>/dev/null || true | 655 | kill "$pid" 2>/dev/null || true |
