Linux KVM if guest is rebooted it will not start, must be manually started

Have an Ubuntu server running KVM:

Linux hyperv 4.4.0-109-generic #132-Ubuntu SMP Tue Jan 9 19:52:39 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

It is running a few VMs which are linux, and one windows vm. After installing a new VM of Windows 2016 server, a problem occurs. The vm (called winstore) may be started by performing the following:

virsh start winstore

And it comes up fine. If this particular VM is restarted from within the VM, it will cleanly shutdown, but not come back up. running

virsh list

confirms that it has not started. In order to start the VM, one must do a

virsh start winstore 

again. This is not the desired behavior, and NOT how the other windows VMs behave (they have the desired behavior, which is they reboot when restarted).

The VM was created a bit differently than normal. These were the steps used to create the VM initially:

create the disk image

qemu-img create -f qcow2 -o preallocation=metadata /mnt/vmstorage/images/winstore.qcow2 1300G

get an xml output of what we would do, so we can modify the cdrom attributes

virt-install --name winstore --ram 8192 --vcpus=2 --graphics=vnc --network=bridge=br731,model=virtio --disk path=/mnt/vmstorage/images/winstore.qcow2,format=qcow2,bus=virtio,cache=none --disk path=/mnt/backups/isos/virtio-win-0.1.126.iso,device=cdrom --cdrom /mnt/backups/isos/SW_DVD9_Win_Server_STD_CORE_2016_64Bit_English_-4_DC_STD_MLF_X21-70526.ISO --os-type=windows --noautoconsole --accelerate --noapic --print-xml > winstore.xml

change the order of the cdroms in the xml file:

<disk type="file" device="cdrom">
  <driver name="qemu" type="raw"/>
  <source file="/mnt/backups/isos/virtio-win-0.1.126.iso"/>
  <target dev="hda" bus="ide"/>
  <readonly/>
</disk>
<disk type="file" device="cdrom">
  <driver name="qemu" type="raw"/>
  <source file="/mnt/backups/isos/SW_DVD9_Win_Server_STD_CORE_2016_64Bit_English_-4_DC_STD_MLF_X21-70526.ISO"/>
  <target dev="hdb" bus="ide"/>
  <readonly/>

then it was installed and started by performing the following:

virsh create ./winstore.xml 
virsh start winstore

after installation, the xml was edited, and the two drives were swapped (hda/hdb) so it will boot from the disk and not cdrom. Then the VM was defined with the following in virsh:

virsh define ./winstore.xml

Again, the VM seems to work fine now, but it only starts with

virsh start winstore

Again, IF the VM is rebooted from within the guest, it will not restart, it will just shutdown. Looking through the logs in /var/log/libvirt/qemu/winstore.log there does not seem to be anything out of the ordinary.

Note that the VM appears in a

virsh list --all

Yes, I am absolutely, positively sure that I am not clicking on "shutdown" in the windows VM. :)


As per Michael Hampton comments above, the xml had "destroy" for the <on_reboot> node instead of "restart".


As @Michael Hampton and @number9 already suggested, the key is to virsh edit your_VM to the following:

  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>restart</on_crash>

As a side note, the VM needs to be rebooted for the changes to take effect.

When using virt-install, you can specifiy the events by adding --events=on_reboot=restart,on_poweroff=restart,on_crash=restart to your virt-install command. Keep in mind that on first start, on_reboot will still be destroy.

As a more general note, you can use libvirt-guest to configure your machines to boot and shutdown properly with your host. On CentOS you'd configure /etc/sysconfig/libvirt-guests like:

ON_BOOT=start # Start the machines with the host
ON_SHUTDOWN=shutdown # Properly shutdown machines with host
PARALLEL_SHUTDOWN=2 # Don't shutdown all machines at the same time, do it 2 by 2 (or else depending on your host and the number of VM)
SHUTDOWN_TIMEOUT=600 # Allow a 10 minutes grace period for machines to shutdown properly before destroying them
SYNC_TIME=1 # Sync time with host (useful for suspended machines)

Once this is configured, you may enable libvirt-guests with

systemctl enable --now libvirt-guests

SYNC_TIME=1 requires guest tools to be installed. You can check that the sync is working with virsh qemu-agent-command vm_name'{"execute":"guest-set-time"}' which should return {"return":{}}