2018-11-01

OpenBSD vmm Hypervisor Part 3: qcow2 and derived disk images

With OpenBSD 6.4, the VMM hypervisor got support for qcow2 disk images. This format is used by QEMU, but it has several features that make it a better choice than raw image files. The images are dynamically-allocated, so the disk image file grows as you use more space instead of taking up the entire filesystem size when the image is created. It won't ever shrink, though. "Derived images" are also supported. While VMM doesn't officially support snapshots yet, you can kind of get away with using derived images to do something similar. I'll cover that toward the end of this article.

You will probably want to have the networking set up on your OpenBSD VM host before you continue. That information is covered in Part 2 of my VMM series.

To create a qcow2 image, prefix the image file name with qcow2:

vmctl create qcow2:obsd64-base.qcow2 -s 10G

--OR--

You can also use the qemu-img utility (from qemu in the package repository) to convert an existing raw image to qcow2 format, if you've already been using VMM before OpenBSD 6.4 was released. This image file will not be dynamically sized, but it can serve as a base image for derivatives:

qemu-img convert obsd64.img obsd64-base.qcow2

Start the VM using your bsd.rd as the boot image, then follow the installer prompts. 

doas vmctl start obsd64-base -n local -m 512m -d obsd64-base.qcow2 -b /bsd.rd -c

When the install is done, rebooting will just bring the installer back. Exit to shell instead, type "halt -p" and use the ~. command sequence to exit the VM. Anything else you press will probably reboot the system (back into the installer). Now you have a pristine, freshly-installed OpenBSD image to start from.

To create a derived image, select your base image with the -b option to vmctl create:

vmctl create qcow2:obsd64-test1.qcow2 -b obsd64-base.qcow2

WARNING: If you make any changes to the base image, all derived image files it was based on will become corrupt and unusable. You can remove write access to the base image if you want. The VMs relying on derived images will run fine. 

chmod 400 obsd64-base.qcow2

Now, create a VM in /etc/vm.conf with the new obsd64-test1.qcow2 image file. All changes will be stored in this new image file. The original filesystem image will remain unchanged, and you can make as many derived images as you want from it.

# bridge0 for VMs, NAT and dhcpd (required for networking in this example)
switch "local" {
interface bridge0
}

# OpenBSD Stable
vm "test.vm" {
disable
owner axon
memory 512M
disk "/home/axon/vmm/obsd64-test1.qcow2"
interface {
switch "local"
lladdr fe:e1:ba:d0:eb:ab
}
}

Reload vmm's configuration:
doas vmctl reload

Then go ahead and boot it up with the console attached:
vmctl start test.vm -c

For snapshot-like functionality, you can make a copy of your derived image and save it with another file name in the same directory. You should shut down the VM before you do this, though. To restore, just copy it back over the derived image, or create a new vm clause in /etc/vm.conf pointing to your saved derived image file.

cp obsd64-test1.qcow2 snapshot-2018-11-01_obsd64-test1.qcow2

You can run multiple VMs at the same time, with different derived images from the base image as well. If I create a new derived image file and add a vm clause for it, both VMs can run at the same time.

vmctl create qcow2:obsd64-test2.qcow2 -b obsd64-base.qcow2

I added this to /etc/vm.conf:
# OpenBSD test2
vm "test2.vm" {
disable
owner axon
memory 512M
disk "/home/axon/vmm/obsd64-test2.qcow2"
interface {
switch "local"
lladdr fe:e1:ba:d0:eb:ac
}
}

Reload vmm, and start up your VMs!
doas vmctl reload
vmctl start test.vm
vmctl start test2.vm

You can attach to the consoles of each to see that they're running. Remember that you can use the [RETURN]~. key sequence to exit the console.

vmctl console test.vm
vmctl console test2.vm