From 31770bec44927f97c62a4cdc90c91cc35f57f6fe Mon Sep 17 00:00:00 2001 From: Kroese Date: Tue, 21 Jul 2026 04:30:56 +0200 Subject: [PATCH] feat: Use QEMU helpers from base image (#1914) --- src/power.sh | 291 ++------------------------------------------------- 1 file changed, 8 insertions(+), 283 deletions(-) diff --git a/src/power.sh b/src/power.sh index 6e510765..d3b56cd7 100644 --- a/src/power.sh +++ b/src/power.sh @@ -15,112 +15,6 @@ CONSOLE_PID="$QEMU_DIR/console.pid" CONSOLE_SOCKET="$QEMU_DIR/console.sock" QEMU_START_PID="$QEMU_DIR/qemu.start.pid" -_trap() { - - local func="$1"; shift - local sig - - TRAP_PID=$BASHPID - - for sig; do - # Capture the local callback and signal while registering the trap. - # shellcheck disable=SC2064 - trap "$func $sig" "$sig" - done - - return 0 -} - -signalCode() { - - local sig="$1" - - case "$sig" in - SIGHUP) echo 129 ;; - SIGINT) echo 130 ;; - SIGQUIT) echo 131 ;; - SIGABRT) echo 134 ;; - SIGTERM) echo 143 ;; - *) echo 0 ;; - esac - - return 0 -} - -displayReason() { - - local reason="$1" - - case "$reason" in - 129 ) echo "SIGHUP" ;; - 130 ) echo "SIGINT" ;; - 131 ) echo "SIGQUIT" ;; - 134 ) echo "SIGABRT" ;; - 143 ) echo "SIGTERM" ;; - * ) echo "$reason" ;; - esac - - return 0 -} - -readQemuPid() { - - local -n _pid="$1" - local file - - for file in "$QEMU_START_PID" "$QEMU_PID"; do - if [ -s "$file" ] && read -r _pid < "$file"; then - return 0 - fi - done - - return 1 -} - -qemuPidFile() { - - local -n _file="$1" - - _file="$QEMU_PID" - [ -s "$QEMU_START_PID" ] && _file="$QEMU_START_PID" - - return 0 -} - -terminateQemu() { - - local file="" - - qemuPidFile file - sKill "$file" - - return 0 -} - -waitQemuExit() { - - local timeout="${1:-10}" - local file="" - - qemuPidFile file - waitPidFile "$file" "$timeout" -} - -waitQemuPid() { - - local -n _pid="$1" - local cnt=0 value="" - - while ! readQemuPid value; do - sleep 0.02 - cnt=$((cnt + 1)) - (( cnt >= 50 )) && return 1 - done - - _pid="$value" - return 0 -} - bootFailed() { local fail="" @@ -181,21 +75,6 @@ ready() { return 1 } -forceKillQemu() { - - local reason="$1" - local pid="" display - - ! readQemuPid pid && return 0 - ! isAlive "$pid" && return 0 - - display=$(displayReason "$reason") - error "Forcefully terminating $(app), reason: $display..." - { disown "$pid" || :; kill -9 -- "$pid" || :; } 2>/dev/null - - return 0 -} - markWindowsBooted() { local file="$STORAGE/windows.boot" @@ -225,92 +104,6 @@ markWindowsBooted() { return 0 } -cleanupHelpers() { - - local pids=( "${SMB_PID:-}" "${NMB_PID:-}" "${DDN_PID:-}" \ - "${TPM_PID:-}" "${WSD_PID:-}" "${WEB_PID:-}" \ - "${AUX_PID:-}" "${AUDIO_PID:-}" "${CONSOLE_PID:-}" \ - "${PASST_PID:-}" "${DNSMASQ_PID:-}" "${BALLOONING_PID:-}" ) - - mKill "${pids[@]}" - - closeNetwork - return 0 -} - -startConsole() { - - local output="${1:-/dev/tty}" - local cnt=0 pid="" - - rm -f -- "$CONSOLE_SOCKET" "$CONSOLE_PID" - - if ! stty -icanon -echo isig -ixon min 1 time 0 "$output" - ) & - - pid=$! - echo "$pid" > "$CONSOLE_PID" - - while [ ! -S "$CONSOLE_SOCKET" ]; do - - if ! isAlive "$pid"; then - rm -f -- "$CONSOLE_PID" - error "Serial console relay exited unexpectedly!" - return 1 - fi - - sleep 0.02 - cnt=$((cnt + 1)) - - if (( cnt > 100 )); then - error "Failed to start serial console relay!" - return 1 - fi - - done - - return 0 -} - -stopConsole() { - - mKill "$CONSOLE_PID" - - 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" "$@" - ) = 30 )); then - term_grace=5 - cleanup_grace=5 - elif (( TIMEOUT >= 15 )); then - term_grace=4 - cleanup_grace=4 - fi - - local min=$((term_grace + cleanup_grace + 1)) - (( TIMEOUT < min )) && (( TIMEOUT = min )) - - wait_until=$((TIMEOUT - cleanup_grace)) - sigterm_at=$((wait_until - term_grace)) - - return 0 -} - -sendAcpiShutdown() { - - [ ! -S "$QEMU_DIR/monitor.sock" ] && return 0 - - # Send ACPI shutdown signal - nc -q 1 -w 1 -U "$QEMU_DIR/monitor.sock" &> /dev/null <<<'system_powerdown' || : - - return 0 -} - abortDuringSetup() { local code="$1" @@ -396,41 +155,7 @@ abortDuringSetup() { finish "$code" } -waitForShutdown() { - - local pid="$1" - local name="$APP" - local slp cnt=0 - - while (( cnt <= wait_until && SHUTDOWN_SKIP == 0 )); do - - sleep 1 & - slp=$! - - # Stop waiting if the process has exited - ! isAlive "$pid" && break - - # Workaround for stale/zombie QEMU pid file - [ ! -s "$QEMU_START_PID" ] && [ ! -s "$QEMU_PID" ] && break - - if (( cnt == sigterm_at )); then - info "${name^} is still running, sending SIGTERM... ($cnt/$wait_until)" - kill -15 -- "$pid" 2>/dev/null || : - elif (( cnt > 0 )); then - info "Waiting for $name to shut down... ($cnt/$wait_until)" - fi - - sendAcpiShutdown - - wait "$slp" || : - (( cnt++ )) - - done - - return 0 -} - -graceful_shutdown() { +gracefulShutdown() { local sig="$1" local pid="" code=0 @@ -473,7 +198,7 @@ graceful_shutdown() { abortDuringSetup "$code" fi - normalizeTimeout + normalizeTimeout 105 waitForShutdown "$pid" finish "$code" @@ -483,9 +208,9 @@ graceful_shutdown() { [ -n "${QEMU_TIMEOUT:-}" ] && TIMEOUT="$QEMU_TIMEOUT" if interactive; then - _trap graceful_shutdown SIGINT + _trap gracefulShutdown SIGINT fi -_trap graceful_shutdown SIGTERM SIGHUP SIGABRT SIGQUIT +_trap gracefulShutdown SIGTERM SIGHUP SIGABRT SIGQUIT return 0