libvirt

Last modified by Sebastian Marsching on 2023/05/16 20:12

Graceful shutdown of virtual machines / domains when shutting down libvirtd

When libvirtd is stopped, all virtual machines are destroyed. There is a little script that does a shutdown of all virtual machines before stopping libvirtd:

#!/usr/bin/python

import libvirt
import time
import sys

conn = libvirt.open("qemu:///system")
if conn == None:
   print "Failed to open connection"
    sys.exit(1)

domainIDs = conn.listDomainsID()

for id in domainIDs:
    dom = conn.lookupByID(id)
   if (dom == None):
       continue
    dom.shutdown()

# Wait up to 4 minutes
shutdownTimeOut = 240

while conn.numOfDomains() > 0 and (time.time() - startTime) < shutdownTimeOut:
    time.sleep(2)

if conn.numOfDomains > 0:
  sys.exit(2)

This script has to be integrated into the stop and restart part of the /etc/init.d/libvirt-bin init script:

# …stop or restart section…
       if running ; then
               echo -n "Stopping libvirt virtual machines..."
                /usr/local/bin/libvirt-shutdown-domains || true
               echo " done"
       fi

Converting OVA images for use with libvirt

OVA images can be imported into libvirt using the virt-v2v utility (from the libguestfs-tools Ubuntu package).

They can be imported directly using the libvirt output method, but I prefer only generating the necessary files, using the local output method. This way, I can easily adjust the VM settings before importing them into libvirt.

virt-v2v -i ova /path/to/source.ova -o local -of qcow2 -os /path/to/destination/dir

This will create an XML file with the VM configuration and a QCOW2 file for each disk in  /path/to/destination/dir. The XML file can be adjusted and then imported using virsh define.

Recovering unused space from a virtual disk images

libvirt offers a utility called virt-sparsify, which helps with recovering unused space from virtual disk images, reducing their size on disk. This is particularly useful with images in the QCOW2 format.

The utility can either be used in-place or create a new image. In either case, the virtual machine has to be shutdown before starting the process. To use the in-place variant, use the following command:

virt-sparsify --in-place /path/to/image.qcow2

The advantage of this method is that you don’t need a lot of free space on the partition storing the image. The disadvantages are that it does not always recover as much space as the second method, and if something goes wrong, the image might be damaged.

The second variant creates a new image, copying data from the original one. This method has the disadvantage that it does not only require enough free space for the new image but also a lot of temporary space. As the default location for temporary files often does not offer enough free space, it can make sense to set TMPDIR to point to a path on a partition with a sufficient amount of free space.

When using this methods, options can be passed to the qemu-img command. For example, setting the preallocation option might be useful:

mkdir /path/to/partition/with/free/space/tmp
TMPDIR=/path/to/partition/with/free/space/tmp virt-sparsify /path/to/original/image.qcow2 -o preallocation=metadata /path/to/new/image.qcow2
rm -r /path/to/partition/with/free/space/tmp

This will create an entirely new image, not touching the original one. Typically, the only useful values for the prellocation option or none or metadata. Using falloc or full will defeat the purpose of virt-sparsify, because instead of creating a sparse image, the unused space in the image is still going to be allocated, thus not freeing up any space.

Please note that when using this method, internally stored snapshots are going to be lost, so make sure that the virtual machine does not have any snapshots before starting this process.