From 6928925968faf8c8c07e6e955b6864e11f614f77 Mon Sep 17 00:00:00 2001 From: Aisha Tammy Date: Mon, 24 Jan 2022 13:50:37 +0000 Subject: [PATCH] allow shutdown via guest agent socket This allows shutdown events to be sent via qemu guest agent, which works for BSD agents which don't handle ACPI events correctly. Tested with OpenBSD 7.0. Signed-off-by: Aisha Tammy --- qemu.initd | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/qemu.initd b/qemu.initd index a80d291..8756080 100644 --- a/qemu.initd +++ b/qemu.initd @@ -25,6 +25,7 @@ VM_NAME="${RC_SVCNAME#qemu.}" : ${vnc_listen:=0.0.0.0} : ${hugepages_path:=/dev/hugepages} : ${monitor_socket:=/run/qemu/${VM_NAME}/monitor.sock} +: ${guest_agent_socket:=/run/qemu/${VM_NAME}/ga.sock} : ${extra_args:=} name="VM $VM_NAME" @@ -53,7 +54,9 @@ command_args=" -vga $vga -device virtio-rng-pci -device virtio-scsi-pci,id=scsi - -monitor unix:$monitor_socket,server,nowait" + -monitor unix:$monitor_socket,server,nowait + -chardev socket,path=$guest_agent_socket,server,nowait,id=qga0 + -device isa-serial,chardev=qga0" command_background='yes' start_stop_daemon_args=" @@ -125,10 +128,22 @@ stop() { ebegin "Stopping $name" + if is_running && qemush "${guest_agent_socket}" "{'execute': 'guest-exec', 'arguments': {'path': '/sbin/halt', 'arg': ['-p']}}"; then + count="$shutdown_timeout" + + printf " Waiting $count seconds for VM shutdown via guest agent " + while is_running && [ $count -gt 0 ]; do + sleep 1 + printf '.' + count=$(( count - 1 )) + done + printf '\n' + fi + if is_running && qemush 'system_powerdown'; then count="$shutdown_timeout" - printf " Waiting $count seconds for VM shutdown " + printf " Waiting $count seconds for VM shutdown via ACPI" while is_running && [ $count -gt 0 ]; do sleep 1 printf '.' @@ -281,12 +296,20 @@ check_bridge() { qemush() { local IFS=$'\n' - printf "%b\n" "$*" | socat - "UNIX-CONNECT:${monitor_socket}" 1>/dev/null + socket_path="${monitor_socket}" + case "$1" in + /*) socket_path="$1"; shift; + esac + printf "%b\n" "$*" | socat - "UNIX-CONNECT:${socket_path}" 1>/dev/null } qemush_show() { local IFS=$'\n' - printf "%b\n" "$*" | socat - "UNIX-CONNECT:${monitor_socket}" | tail -n +3 | head -n -1 + socket_path="${monitor_socket}" + case "$1" in + /*) socket_path="$1"; shift; + esac + printf "%b\n" "$*" | socat - "UNIX-CONNECT:${socket_path}" | tail -n +3 | head -n -1 } gen_macaddr() {