mirror of
https://github.com/dockur/windows.git
synced 2026-08-03 12:37:20 +01:00
feat: Preserve graceful shutdown for interactive console (#1876)
This commit is contained in:
@@ -53,13 +53,19 @@ if ! enabled "$SHUTDOWN"; then
|
||||
exec "${cmd[@]}" ${ARGS:+ $ARGS} >"$pipe" 2>&1
|
||||
fi
|
||||
|
||||
if ! interactive; then
|
||||
"${cmd[@]}" ${ARGS:+ $ARGS} >"$pipe" 2>&1 &
|
||||
else
|
||||
startConsole "$pipe"
|
||||
setsid -w "${cmd[@]}" ${ARGS:+ $ARGS} </dev/null >"$pipe" 2>&1 &
|
||||
fi
|
||||
|
||||
pid=$!
|
||||
( sleep 30; boot ) &
|
||||
|
||||
rc=0
|
||||
wait "$pid" || rc=$?
|
||||
interactive && stopConsole
|
||||
wait "$output" || :
|
||||
|
||||
[ -f "$QEMU_END" ] && exit "$rc"
|
||||
|
||||
+75
-7
@@ -6,13 +6,19 @@ set -Eeuo pipefail
|
||||
|
||||
# Configure QEMU for graceful shutdown
|
||||
|
||||
SHUTDOWN_SKIP=0
|
||||
SHUTDOWN_SIGNAL=0
|
||||
|
||||
QEMU_PTY="$QEMU_DIR/qemu.pty"
|
||||
QEMU_END="$QEMU_DIR/qemu.end"
|
||||
CONSOLE_PID="$QEMU_DIR/console.pid"
|
||||
CONSOLE_SOCKET="$QEMU_DIR/console.sock"
|
||||
|
||||
_trap() {
|
||||
|
||||
local func="$1"; shift
|
||||
local sig
|
||||
|
||||
TRAP_PID=$BASHPID
|
||||
|
||||
for sig; do
|
||||
@@ -174,8 +180,8 @@ cleanupHelpers() {
|
||||
|
||||
local pids=( "${SMB_PID:-}" "${NMB_PID:-}" "${DDN_PID:-}" \
|
||||
"${TPM_PID:-}" "${WSD_PID:-}" "${WEB_PID:-}" \
|
||||
"${AUX_PID:-}" "${AUDIO_PID:-}" "${PASST_PID:-}" \
|
||||
"${DNSMASQ_PID:-}" "${BALLOONING_PID:-}" )
|
||||
"${AUX_PID:-}" "${AUDIO_PID:-}" "${CONSOLE_PID:-}" \
|
||||
"${PASST_PID:-}" "${DNSMASQ_PID:-}" "${BALLOONING_PID:-}" )
|
||||
|
||||
mKill "${pids[@]}"
|
||||
|
||||
@@ -183,6 +189,55 @@ cleanupHelpers() {
|
||||
return 0
|
||||
}
|
||||
|
||||
startConsole() {
|
||||
|
||||
local cnt=0
|
||||
local pid=""
|
||||
local output="${1:-/dev/tty}"
|
||||
|
||||
rm -f -- "$CONSOLE_SOCKET" "$CONSOLE_PID"
|
||||
|
||||
if ! stty -icanon -echo isig -ixon min 1 time 0 </dev/tty; then
|
||||
error "Failed to configure serial console terminal!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
(
|
||||
trap '' INT QUIT
|
||||
exec nc -lU "$CONSOLE_SOCKET" </dev/tty >"$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
|
||||
}
|
||||
|
||||
finish() {
|
||||
|
||||
local reason=$1
|
||||
@@ -276,7 +331,7 @@ waitForShutdown() {
|
||||
local name="$APP"
|
||||
local slp
|
||||
|
||||
while (( cnt <= wait_until )); do
|
||||
while (( cnt <= wait_until && SHUTDOWN_SKIP == 0 )); do
|
||||
|
||||
sleep 1 &
|
||||
slp=$!
|
||||
@@ -296,7 +351,7 @@ waitForShutdown() {
|
||||
|
||||
sendAcpiShutdown
|
||||
|
||||
wait "$slp"
|
||||
wait "$slp" || :
|
||||
(( cnt++ ))
|
||||
|
||||
done
|
||||
@@ -315,20 +370,29 @@ graceful_shutdown() {
|
||||
code=$(signalCode "$sig")
|
||||
|
||||
if [ -f "$QEMU_END" ]; then
|
||||
echo && info "Received $1 signal while already shutting down..."
|
||||
|
||||
if (( code == 130 && SHUTDOWN_SIGNAL == code )); then
|
||||
SHUTDOWN_SKIP=1
|
||||
echo && info "Received SIGINT again, forcing shutdown..."
|
||||
return
|
||||
fi
|
||||
|
||||
echo && info "Received $sig signal while already shutting down..."
|
||||
return
|
||||
fi
|
||||
|
||||
set +e
|
||||
SHUTDOWN_SIGNAL=$code
|
||||
|
||||
touch "$QEMU_END"
|
||||
echo && info "Received $1 signal, sending ACPI shutdown signal..."
|
||||
echo && info "Received $sig signal, sending ACPI shutdown signal..."
|
||||
|
||||
if ! readQemuPid pid; then
|
||||
warn "QEMU PID file ($QEMU_PID) does not exist?"
|
||||
finish "$code"
|
||||
fi
|
||||
|
||||
if ! isAlive "$pid"; then
|
||||
if [ -z "$pid" ] || ! isAlive "$pid"; then
|
||||
warn "QEMU process with PID $pid does not exist?"
|
||||
finish "$code"
|
||||
fi
|
||||
@@ -346,6 +410,10 @@ graceful_shutdown() {
|
||||
! enabled "$SHUTDOWN" && return 0
|
||||
[ -n "${QEMU_TIMEOUT:-}" ] && TIMEOUT="$QEMU_TIMEOUT"
|
||||
|
||||
if interactive; then
|
||||
_trap graceful_shutdown SIGINT
|
||||
fi
|
||||
|
||||
_trap graceful_shutdown SIGTERM SIGHUP SIGABRT SIGQUIT
|
||||
|
||||
return 0
|
||||
|
||||
Reference in New Issue
Block a user