Today I played around a bit with QEMU/KVM. At first I tried to use libvirt as the abstraction layer to hide QEMU, but a few weeks ago I had already read that some user had stability issues with libvirt compared to QEMU without libvirt. Additionally, during my tests for simple use cases I found the QEMU command line API much simpler than the libvirt XML definitions.

However, managing running QEMU Virtual Machines is more difficult without libvirt. libvirt keeps track of all VMs that have been started and provides a command line interface to list running VMs and stop them. QEMU only starts VMs and then basically forgets about them and there seems to be no interface that keeps track of all running VMs.

Then I found out that with QEMU you can set a process name with the -name parameter. This parameter accepts a window name and a process name and we can use the process name to find our VMs with standard linux tools. So let’s create a few VMs with a custom process name. For simplicity I will only start Live-CDs and not use pre-created images:

for i in $(seq 1 10); do
   qemu-system-x86_64 -cdrom archlinux-2020.05.01-x86_64.iso -cpu host \
      -enable-kvm -m 1024 -smp 1 \
      -name worker-$i,process=qemu-vm-worker-$i -daemonize
done

That was easy. To list all started VMs we now only have to search for the prefix qemu-vm-:

ps -eo comm | grep ^qemu-vm-

One difficulty with this approach is that the process name in ps is limited to 15 characters. This is due to a limit enforced by the kernel and can also be seen when showing the file /proc/<procnum>/comm.

This means that either we have to ensure that the process name always has less than or equal to 15 characters or we have to work with the full command line like this:

ps -eo cmd | grep -oP "qemu.+process=\\Kqemu-vm-[a-z0-9-]+"

Process names with at most 15 characters

Knowing the names of our processes we can then retrieve their process ID or kill them with pgrep and pkill:

# I shortened the VM name in the start script above
pgrep qemu-vm-wor-1$
pkill qemu-vm-wor-1$

Process names longer than 15 characters

If we work with process names longer than 15 characters we can still use pgrep but have to work with the full command name. Same goes for pkill.

pgrep -f process=qemu-vm-worker-1\\b
pkill -f process=qemu-vm-worker-1\\b

Exits

Of course, killing is no graceful shutdown, but at least we already know how to stop the processes. Shutting down the VMs gracefully without libvirt seems quite a bit more difficult.

A nice way to do this seems to be connecting to the QEMU monitor through a unix socket and then writing the command system_powerdown to the monitor. To test this you can open a socket connection with socat:

qemu-system-x86_64 -cdrom archlinux-2020.05.01-x86_64.iso \
   -cpu host -enable-kvm -m 1024 -smp 1 \
   -name worker-1,process=qemu-vm-worker-1 \
   -daemonize \
   -monitor unix:qemu-monitor.sock,server,nowait
socat -,echo=0,icanon=0 unix-connect:qemu-monitor.sock

Then boot the machine completely (it will not work if you’re still in the boot menu) and when it has booted type system_powerdown into the socket and press Enter.

I do not maintain a comments section. If you have any questions or comments regarding my posts, please do not hesitate to send me an e-mail to stefan@eliteinformatiker.de.