Running Virtual Machines with VMM on OpenBSD

OpenBSD has this small, nice virtual machine monitor (VMM) you can use to run accelerated virtual machines (VM) on OpenBSD. This article describes how to set up vmm(4) and how to run various operating systems.

Initial Setup

I run *-current* on my personal machine and thus all of the following applies to the version as of September 2018.

Quick Boot of a CD-ROM ISO Image

Sometimes, it's not desired to create a disk image plus a VM configuration, e.g., if you only want to fire up an ISO image to see if it boots. Use `vmctl start` and the `-r` option to specify the path to the ISO. Additionally, set `-c` to see the serial console output. `vmctl` will ask you for a name so set a random one since the name doesn't matter here:

Create a Hard Disk

In most cases, you want to have a persistent storage for your VM. Use `vmctl` or `qemu-img` to create a new hard disk. It doesn't matter if you create the image with vmctl or qemu-img, however, the first one is include in base. Use `-f` to switch between *raw* and the more modern *qcow2* format. The following command creates a qcow2 format disk images with a maximum size of 10 GB:

Connect your VMs to the Network

There are several ways to connect guest VMs to the network. The simplest one and the one I use is called *local interfaces*. A local interface is added to a VM by using the `-L` option with `vmctl start`. You will get a vio(4) interface within the VM connected to a tap(4) interface on the host. All IP addresses come from the shared, globally non-routed 100.64.0.0/10 address pool and served from a buit-in DHCP server. For the logic on how the IP addresses in the VM and the host are choose read the excellent man page of vmctl.

In the following example I use the same command as above but this time with the `-L` option. Note how the vio0 interface gets an IP address via the built-in DHCP server:

On the host, a tap(4) interface is now visible:

This is sufficient if you just want to have a connection between the VM and the host, If you want to grant Internet access to the VM via NAT you have to set up some pf(4) rules on the host. Add the following lines to your `pf.conf` and set the variables accordingly. The second rule is only needed if you want to redirect the VM's DNS traffic to `$dns_server`. Usually, the DHCP sets the IP address of the host as DNS server.

On the host you also have to enable IP forwarding via `sysctl`. To persistently enable forwarding set the value in `/etc/sysctl.conf`. While the former is active immediately, the latters needs a reboot.

Install and run an OpenBSD VM

Installing OpenBSD on vmm is really simple. Create a hard disk as described above and use the last `vmctl` command from above and add the `-d` option with the path to the disk image to the *start* command. If you use a qcow2 disk image, you have to prefix the path with *qcow2:*. For raw disks no prefix is needed. By default, a VM gets 512M RAM assigned, if you need more, just use `-m size`.

Install and run a Linux VM

Install VMs via qemu

As of today, vmm(4) does not support enhanced graphics like VGA output so you need a guest operating system that supports a serial console. Since the serial console is not always active by default you can either try to activate it by modifying the ISO/boot image or you just install the guest operating system in qemu, activate the serial console and attach the disk to vmm(4) later. Be advised that vmm(4) currently does not support all Unix-like operating systems you might like. If in doubt, just give it a try or search the mailing list archive.

It doesn't matter on which system you choose to install via qemu, so I prefer to do this on Linux since qemu on OpenBSD is not accelerated. An non-accelerated Debian Linux installation could easily take an hour. Since qemu and vmm(4) both supports the *qcow2* disk format it is my preferred choice.

If you want to go with OpenBSD, install qemu via `pkg_add`:

Create a qcow2 disk image file as mentioned above and use the following command to boot the specified ISO image. This will give a graphical VGA console and you can easily install the operating system of your choice. In the following example I use Debian Linux.

`$Id: vmm.gmi,v 1.1 2020/12/24 12:41:43 cvs Exp $`