libvirt snapshots

If you have a VMWare-Background, handling libvirt-snapshots is very counter-intuitive. With VMWare, you take a snapshot and make changes to the actual disk. So when you’re done and haven’t encountered any problems, you just delete the snapshot and be happy.

With libvirt it’s the other way around: You work with the snapshot! This means you have to commit the changes to the base image after making changes! If you just delete the snapshot you’re back where you started! To make things worse, there are internal and external snapshots, and the latter aren’t fully supported by libvirt, meaning you can’t delete external snapshots with virsh.

So, to “emulate” VMWare-Behavior you have to:

  • Create an external snapshot while the VM is shut down:
# snapshot-create-as <domain> <snapshot-name> --disk-only --atomic
  • start the VM again:
#  start <domain>

Don’t let you fool by the output of snapshot-list: even though it says that the domain is shutoff, you’re actually working with the snapshot!

  • Make your changes
  • Once you’re done, commit the changes to the base image. Since libvirt cannot handle external snapshots properly you have to do it by foot. Shut down the VM and go to the directory with the disk images (/var/lib/libvirt/images or such). Then commit the changes to the base image with qemu-img:
# qemu-img commit <filename-of-external-snapshot>

Don’t worry about the destination. It’s in the metadata of the snapshot. Repeat for every disk of the VM and remove the (now very small) snapshot files.

  • Unfortunately libvirt still thinks that there is a snapshot. Delete it with
# snapshot-delete <domain> --metadata <name-of-snapshot>
  • More unfortunately, libvirt still references the snapshot files as base for the virtual disks. So remove them, re-add the real ones and start the VM.

Well, maybe it’s easier with internal snapshots (it should, because the procedure above is quite a dance…), but it works.

Kernel 4.4.1-2-ARCH and libvirtd

Well, well, well… What a fuckup! As of this writing [2016-03-03] the current versions of the Archlinux Kernel and libvirtd are not working at all. Took me almost a week to figure this out.

There are two issues:

  1. The Kernel package 4.4.1-2-ARCH (which is actually 4.4.3 with patches) crashes silently if you try to start a VM from libvirtd (if you even get so far, but that’s covered below). Honestly, I have no idea why, because it doesn’t sputter an OOPS. What I know: Downgrading to 4.3.3-3-ARCH fixes that issue.
  2. libvirt-1.3.2-1 is broken, or rather libvirtd.service is… It says that libvirtd is of type notify. That may be true, but it doesn’t work. Don’t even bother to fiddle around with polkit rules: It doesn’t work. IMHO polkit is over-engineered.

To fix (1.): Downgrade the Kernel to 4.3.3. If you don’t have a copy, download it here. Install it with:

# pacman -U linux-4.3.3-3-x86_64.pkg.tar.xz
# systemctl reboot

When the older kernel is running (confirm it with uname -a), we can fix (2.) by turning libvirtd.service from Type=notify to Type=simple. Be warned: It may have serious side effects! You’re on your own when you do this!

# cp /usr/lib/systemd/system/libvirtd.service /etc/systemd/system

Now edit /etc/systemd/system/libvirtd.service and comment out Type=notify. This turns libvirtd into a “simple” service, not forking, no authentication, nothing. Then reload everything and start libvirtd, virtlockd and virtlogd:

# systemctl daemon-reload
# systemctl start libvirtd virtlockd virtlogd

Finally (re-)start your virtual machines. Share and enjoy!