The missing piece is libvirt-guests.service - this is the systemd unit that handles graceful VM shutdown or suspend when the host powers off. Without it configured, the kernel simply kills all processes including qemu instances when shutdown is initiated, which is why the VMs are seeing a “pulled plug” event.
First check if the service exists and is enabled:
systemctl status libvirt-guests.service
If it’s disabled or not running, enable it:
systemctl enable --now libvirt-guests.service
Then configure its behavior in /etc/sysconfig/libvirt-guests. The key settings:
# What to do to each guest on host shutdown
# Options: suspend / shutdown / none
ON_SHUTDOWN=shutdown
# How long to wait for each guest to shut down before giving up (seconds)
SHUTDOWN_TIMEOUT=300
# What to do to guests on host boot
ON_BOOT=start
If you want behavior similar to Hyper-V’s save/resume, use ON_SHUTDOWN=suspend. This saves the VM’s memory state to disk and restores it on next boot, so the guest sees no interruption. The tradeoff is disk space and time during host shutdown.
ON_SHUTDOWN=shutdown sends a clean ACPI shutdown signal and waits up to SHUTDOWN_TIMEOUT seconds for the guest to power off gracefully. This is what Windows Server and most Linux guests handle well since they receive a proper shutdown command rather than a hard kill.
After editing /etc/sysconfig/libvirt-guests, restart the service and test with a host reboot:
systemctl restart libvirt-guests.service
Your Windows VM should receive a normal ACPI shutdown signal next time the host reboots.