diff --git a/install.sh b/install.sh index 567b4d1..cf5ed62 100644 --- a/install.sh +++ b/install.sh @@ -137,6 +137,9 @@ fi rm -rf $MOUNT +# Store agent version +echo "2" > "$IMG"/agent.ver + mv -f "$BOOT" "$IMG"/"$BASE".boot.img mv -f "$SYSTEM" "$IMG"/"$BASE".system.img diff --git a/power.sh b/power.sh index bf26ff9..bd043d7 100644 --- a/power.sh +++ b/power.sh @@ -5,36 +5,64 @@ set -eu QEMU_MONPORT=7100 QEMU_POWERDOWN_TIMEOUT=30 +_QEMU_PID=/run/qemu.pid +_QEMU_SHUTDOWN_COUNTER=/run/qemu.counter -_graceful_shutdown() { +# Allows for troubleshooting signals sent to the process +_trap(){ + func="$1" ; shift + for sig ; do + trap "$func $sig" "$sig" + done +} + +_graceful_shutdown(){ - local COUNT=0 local QEMU_MONPORT="${QEMU_MONPORT:-7100}" local QEMU_POWERDOWN_TIMEOUT="${QEMU_POWERDOWN_TIMEOUT:-120}" set +e - echo "Trying to shutdown gracefully.." + echo "Trapped $1 signal" + echo 0 > "${_QEMU_SHUTDOWN_COUNTER}" - # Send a NMI interrupt which will be detected by the agent - # echo 'nmi' | nc -q 1 localhost "${QEMU_MONPORT}">/dev/null 2>&1 - - echo 'system_powerdown' | nc -q 1 localhost "${QEMU_MONPORT}">/dev/null 2>&1 - echo "" - - while echo 'info version'|nc -q 1 localhost "${QEMU_MONPORT:-7100}">/dev/null 2>&1 && [ "${COUNT}" -lt "${QEMU_POWERDOWN_TIMEOUT}" ]; do - (( COUNT++ )) || true - echo "Shutting down, waiting... (${COUNT}/${QEMU_POWERDOWN_TIMEOUT})" - sleep 1 - done - - if echo 'info version'|nc -q 1 localhost "${QEMU_MONPORT:-7100}">/dev/null 2>&1; then - echo "Killing the VM.." - echo 'quit' | nc -q 1 localhost "${QEMU_MONPORT}">/dev/null 2>&1 || true + FILE="${IMG}/agent.ver" + if [ ! -f "$FILE" ]; then + AGENT_VERSION="1" + echo "$AGENT_VERSION" > "$IMG"/agent.ver + else + AGENT_VERSION=$(cat "${FILE}") fi - echo "Exiting..." + # Don't send the powerdown signal because Synology ignores it + # echo 'system_powerdown' | nc -q 1 -w 1 localhost "${QEMU_MONPORT}">/dev/null + + if (($AGENT_VERSION < 2)); then + echo "Please update the agent to allow gracefull shutdowns..." + pkill -f qemu-system-x86_64 + else + # Send a NMI interrupt which will be detected by the agent + echo 'nmi' | nc -q 1 -w 1 localhost "${QEMU_MONPORT}">/dev/null + fi + + while [ "$(cat ${_QEMU_SHUTDOWN_COUNTER})" -lt "${QEMU_POWERDOWN_TIMEOUT}" ]; do + + # Increase the counter + echo $(($(cat ${_QEMU_SHUTDOWN_COUNTER})+1)) > ${_QEMU_SHUTDOWN_COUNTER} + + # Try to connect to qemu + if echo 'info version'| nc -q 1 -w 1 localhost "${QEMU_MONPORT:-7100}">/dev/null; then + + sleep 1 + #echo "Shutting down, waiting... ($(cat ${_QEMU_SHUTDOWN_COUNTER})/${QEMU_POWERDOWN_TIMEOUT})" + + fi + done + + echo 'quit' | nc -q 1 -w 1 localhost "${QEMU_MONPORT}">/dev/null || true + + return } -trap _graceful_shutdown SIGINT SIGTERM SIGHUP +_trap _graceful_shutdown SIGTERM SIGHUP SIGINT SIGABRT SIGQUIT KVM_MON_OPTS="-monitor telnet:localhost:${QEMU_MONPORT:-7100},server,nowait,nodelay" diff --git a/run.sh b/run.sh index 7323265..09bc070 100755 --- a/run.sh +++ b/run.sh @@ -36,6 +36,14 @@ fi EXTRA_OPTS="-nographic -object rng-random,id=rng0,filename=/dev/urandom -device virtio-rng-pci,rng=rng0 -device virtio-balloon-pci,id=balloon0,bus=pcie.0,addr=0x4" ARGS="-m ${RAM_SIZE} -smp ${CPU_CORES} -machine type=q35${KVM_ACC_OPTS} ${EXTRA_OPTS} ${KVM_MON_OPTS} ${KVM_SERIAL_OPTS} ${KVM_NET_OPTS} ${KVM_DISK_OPTS}" -qemu-system-x86_64 ${ARGS} & +set -m +( + for _SIGNAL in {1..64}; do trap "echo Caught trap ${_SIGNAL} for the QEMU process" "${_SIGNAL}"; done + qemu-system-x86_64 ${ARGS} & echo $! > ${_QEMU_PID} +) +set +m -wait $! +# Since we have to start the process with -m, we need to poll every intervall if it's still running +while [ -d "/proc/$(cat ${_QEMU_PID})" ]; do + sleep 1 +done diff --git a/serial.sh b/serial.sh index 97ce545..b0f35f1 100644 --- a/serial.sh +++ b/serial.sh @@ -7,7 +7,6 @@ permanent="DSM" serialstart="2000" -IMG="/storage" [ ! -d "$IMG" ] && echo "Storage folder (${IMG}) not found!" && exit 69 #If environment variabele not set fall back to file