From 495c4ea70ba76716515ea2317ac562f49d00f4b6 Mon Sep 17 00:00:00 2001 From: Albrecht Lohofener Date: Fri, 23 Oct 2026 20:47:15 +0200 Subject: [PATCH] Fix endless wait in qemu_qmp.sh when a qemu-ga status response is lost The qga socket is shared by several clients (healthcheck, web backend, after-boot command script). qemu-ga reports "exited": true only once and drops the PID afterwards, so if that response is lost every further guest-exec-status fails and 'qemu_qmp.sh -c' loops forever. This made run_command_after_openwrt_boot.sh never detect the OpenWrt boot and test_openwrt_after_boot_cmd fail sporadically. Abort on error responses and add a timeout to the boot detection poll. Co-Authored-By: Claude Opus 5.5 --- src/qemu_qmp.sh | 6 ++++++ src/run_command_after_openwrt_boot.sh | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/qemu_qmp.sh b/src/qemu_qmp.sh index d173e72..0068ddc 100644 --- a/src/qemu_qmp.sh +++ b/src/qemu_qmp.sh @@ -79,6 +79,12 @@ while getopts ":hvrqsSVRc" option; do while true; do # Wait for command exit RETURN_JSON=`echo '{"execute": "guest-exec-status", "arguments": { "pid": '${PID}'}}' | nc -w 1 -U /run/qga.sock` #echo >&2 "RETURN_JSON: $RETURN_JSON" + # qemu-ga drops the PID after reporting "exited": true once. If that response got lost (e.g. received by + # another client of the shared socket), every further status request fails and we would wait forever. + if echo "$RETURN_JSON" | grep -q '"error"'; then + echo >&2 "Command error: guest-exec-status failed! RETURN_JSON: $RETURN_JSON" + exit 1 + fi export EXITCODE=`echo $RETURN_JSON | sed -n 's/.*"exitcode": \([0-9]*\).*/\1/p'` export OUT_DATA=`echo $RETURN_JSON | sed -n 's/.*"out-data": "\([^"]*\).*/\1/p' | base64 -d -w 0` export ERR_DATA=`echo $RETURN_JSON | sed -n 's/.*"err-data": "\([^"]*\).*/\1/p' | base64 -d -w 0` diff --git a/src/run_command_after_openwrt_boot.sh b/src/run_command_after_openwrt_boot.sh index ff4423c..f827e52 100644 --- a/src/run_command_after_openwrt_boot.sh +++ b/src/run_command_after_openwrt_boot.sh @@ -36,7 +36,8 @@ fi set +e # Enable that the next command can fail while true; do # Check if OpenWrt is booted - /run/qemu_qmp.sh -c 'logread | grep "procd: - init complete"' >/dev/null 2>&1 + # Use a timeout to never get stuck in a single poll + timeout 30 /run/qemu_qmp.sh -c 'logread | grep "procd: - init complete"' >/dev/null 2>&1 if [ $? -eq 0 ]; then echo "Detected OpenWrt is booted" break