From 99d6b8f83070507407130a86610df9dbec1fcb57 Mon Sep 17 00:00:00 2001 From: Kroese Date: Mon, 20 Jul 2026 16:31:21 +0200 Subject: [PATCH] feat: Preserve graceful shutdown for interactive console (#1312) --- src/entry.sh | 2 +- src/power.sh | 106 +++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 82 insertions(+), 26 deletions(-) diff --git a/src/entry.sh b/src/entry.sh index a00198f..4b76284 100755 --- a/src/entry.sh +++ b/src/entry.sh @@ -36,7 +36,7 @@ if ! interactive; then "${cmd[@]}" ${ARGS:+ $ARGS} & else startConsole - setsid -w "${cmd[@]}" ${ARGS:+ $ARGS} = 50 )) && return 1 + done + + _pid="$value" return 0 } forceKillQemu() { local reason="$1" - local pid="" - local display + local pid="" display ! readQemuPid pid && return 0 ! isAlive "$pid" && return 0 @@ -108,8 +145,7 @@ cleanupHelpers() { startConsole() { local output="${1:-/dev/tty}" - local cnt=0 - local pid="" + local cnt=0 pid="" rm -f -- "$CONSOLE_SOCKET" "$CONSOLE_PID" @@ -154,10 +190,34 @@ stopConsole() { return 0 } +startQemu() { + + rm -f -- "$QEMU_START_PID" + + ( + trap '' INT QUIT + + # shellcheck disable=SC2016 + exec setsid -f -w sh -c ' + file=$1 + shift + + "$@" & + pid=$! + printf "%s\n" "$pid" > "$file" || exit 1 + + rc=0 + wait "$pid" 2>/dev/null || rc=$? + exit "$rc" + ' sh "$QEMU_START_PID" "$@" + ) /dev/null <<<'system_powerdown' || : @@ -218,9 +277,6 @@ normalizeTimeout() { local term_grace=3 # seconds before loop ends to send SIGTERM local cleanup_grace=3 # seconds reserved after the loop for cleanup - local elapsed - local timeout_left - local min TIMEOUT=$(strip "$TIMEOUT") if [[ ! "$TIMEOUT" =~ ^[0-9]+$ ]]; then @@ -235,10 +291,10 @@ normalizeTimeout() { cleanup_grace=4 fi - elapsed=$((SECONDS - start)) - timeout_left=$((TIMEOUT - elapsed)) + local elapsed=$((SECONDS - start)) + local timeout_left=$((TIMEOUT - elapsed)) - min=$((term_grace + cleanup_grace + 1)) + local min=$((term_grace + cleanup_grace + 1)) (( timeout_left < min )) && timeout_left=$min wait_until=$((timeout_left - cleanup_grace)) @@ -252,18 +308,17 @@ waitForShutdown() { local cnt=0 local pid="$1" local name="$APP" - local slp while (( cnt <= wait_until && SHUTDOWN_SKIP == 0 )); do sleep 1 & - slp=$! + local slp=$! # Stop waiting if the process has exited ! isAlive "$pid" && break # Workaround for stale/zombie QEMU pid file - [ ! -s "$QEMU_PID" ] && break + [ ! -s "$QEMU_START_PID" ] && [ ! -s "$QEMU_PID" ] && break if (( cnt == sigterm_at )); then info "${name^} is still running, sending SIGTERM... ($cnt/$wait_until)" @@ -283,8 +338,7 @@ waitForShutdown() { graceful_shutdown() { local sig="$1" - local pid="" - local code=0 + local pid="" code=0 [[ $BASHPID != "$TRAP_PID" ]] && return @@ -310,8 +364,10 @@ graceful_shutdown() { echo && info "Received $sig signal, sending shutdown command..." if ! readQemuPid pid; then - warn "QEMU PID file ($QEMU_PID) does not exist?" - finish "$code" + if ! interactive || ! waitQemuPid pid; then + warn "QEMU PID file does not exist?" + finish "$code" + fi fi if [ -z "$pid" ] || ! isAlive "$pid"; then