When I start a qemu (Windows Server 2003) virtual machine with
-qmp tcp:127.0.0.1:4444,server,nowait
I can make it shutdown with the following script
#!/bin/bash
telnet 127.0.0.1 4444 <<JSON
{ "execute": "qmp_capabilities" }
{ "execute": "system_powerdown" }
JSON
But there are two problems:
the script exits with $? = 1 and says "Connection closed by foreign host". Can I make it exit in a clean way?
The shutdown process happens asynchronously. So, the script returns at once, not waiting for the vm to finish the shutdown. How do I know when it's done (without grepping ps for qemu or something like this)?
The background is I want to host a Windows Server 2003 installation inside a VM on a linux host and I want to use an UPS. In case of a blackout, I want to shutdown the VM and then the host – and of course, the host should start the shutdown not until the VM is done.
It is possible using expect. An event called "SHUTDOWN" will be emitted when the vm is finished. So, the following script starts the shutdown and waits for it to complete:
As I got already downvotes for my question and especially considering the following statement
I have to say another thing. I really don't see why doing something like this is "probably a complete mess", especially the vm itself. When launching it via libvirt, the very same thing is done compared to a shell script doing the job. Why should it "barely work"?! Additionally, QMP has been designed and made available through something like telnet to make it possible to do "something like this" in this way, isn't it?
And isn't libvirt nothing but a wrapper to the interfaces of several virtualization solutions so one can handle multiple vm installations run by different hypervisors in the same manner? So why should I use it when I only run one vm in one hypervisor?
Probably I'm completely wrong here, but at least, this is how one can shutdown a qemu virtual machine using a (bash) script and know when it's done in a decent way without having to use libvirt.
Came across this looking to shut down a VM with out libvirtd. As to why, libvirtd would not start due to a failed swap device. I wanted to cleanly shut down the vm's and couldn't use libvirt to save to disk. With the above I came up with
in /var/lib/libvirt/qemu
for sock in $(find | grep monitor); do printf "{ 'execute': 'qmp_capabilities' }\n{ 'execute': 'system_powerdown' }\n" | socat - UNIX-CONNECT:$sock; done
This is for UBUNTU. So overall yes I usually would use libvirt, but I knew it was an interface to some other command to shut down. Knowing what libvirt was actually doing let me cleanly shut down the vm's.