Tyler's Site

Abstract

When starting to use FreeBSD, one might become interested in the hypervisor that FreeBSD uses, Bhyve. There are many guides on how to get started with it such as this one one from Klara Systems. However, many of these guides, including this one, teaches using vm-bhyve. While vm-bhyve is a great tool, I want to have a better understanding of vanilla bhyve for another project I am currently working on; these are some notes I have from experimenting with bhyve out of the box.

Getting Started

A natural place to start working with bhyve is going to be the bhyve man page; however, the man pages are quite dense with information, and all of it serves a purpose, but I think it is a bit much to get started. Thankfully there is an entry for Bhyve in the FreeBSD handbook. It has a very good guide on getting started with Bhyve. This blog post is another more concise ‘getting started’ guide for bhyve, however, it is worth noting that this guide only goes over creating Linux based VMs in Bhyve.

Networking

Before setting up any VMs, it would probably be beneficial to get the networking set up so that the VM can access the rest of the network and/or the Internet. The following commands should be run as root, or prefixed by sudo/doas.

# Enable vmm kernel module.
# this isn't really networking related,
# but fits in this sections quite nicely
kldload vmm
# Stuff to make networking work
ifconfig tap0 create
sysctl net.link.tap.up_on_open=1
ifconfig bridge0 create
ifconfig bridge0 addm vtnet0 addm tap0
ifconfig bridge0 up
# Add to pf.conf, only if PF is enabled
pass in on $HOSTIP from $YOURVMIP to $DHCPSERVER port 53 keep state

This should be sufficient to get networking set up in most cases, however, wireless NICs may require a different process as most wireless NICs cannot do bridge networking. In that case, setting up NAT networking is generally the way to approach giving VMs Internet access. This wiki entry from VM-bhyve should be a good place to start when setting it up.

Starting VMs

We can now finally get a VM set up.

# download the FreeBSD 13.2 release boot ISO
wget https://download.freebsd.org/releases/amd64/amd64/ISO-IMAGES/13.2/FreeBSD-13.2-RELEASE-amd64-bootonly.iso
# Load the VM with the ISO for installation
bhyveload -d FreeBSD-13.2-RELEASE-amd64-bootonly.iso -m 1G vm1
# Command to run the VM for installation
bhyve -c 1 -m 1G -A -H -P \
-s 0,hostbridge \
-s 1,lpc \
-s 2,virtio-net,tap0 \
-s 3,ahci-cd,FreeBSD-13.2-RELEASE-amd64-bootonly.iso \
-s 4,virtio-blk,guest.img \
-l com1,stdio vm1

Install FreeBSD as usual, may have to configure a static IP address and DNS server for networking to work though.

# This is required to load the VM into Bhyve
bhyveload -d guest.img -m 1G vm1

# Command to actually run the VM
bhyve -c 1 -m 1G -A -H -P \
-s 0,hostbridge \
-s 1,lpc \
-s 2,virtio-net,tap0 \
-s 3,virtio-blk,guest.img \
-l com1,stdio vm

Stopping VMs

Once a VM is started and you have a console, you can power off the VM by doing a standard shutdown in the guest. However, sometimes that is not an option for one reason or another. So, how can we shut guests down from the host? bhyvectl has us covered on it.

# To forcefully reset VM
bhyvectl --vm=${VM-Name} --force-reset
# To forcefully shutdown VM
bhyvectl --vm=${VM-Name} --force-poweroff
# To delete the VM
bhyvectl --vm=${VM-Name} --destroy

Gathing Information About Bhyve VMs

Occasionally, the system administrator will need or want to look at guests on the system for one reason or another.

All of the VMs that Bhyve knows about of the system will be listed in /dev/vmm. Using the following command will show all the VMs on the system that Bhyve is managing:

ls -al /dev/vmm

However, this doesn’t tell you much about the VMs themselves. How do we show the VMs that are currently running? or how much memory they have allocated to them? Unfortunately the Bhyve’s built in tools are not very user friendly for things like this, but there are still ways of getting such information using bhyvectl and some other built in tools. For example, the ps utility does a great job of showing running VMs:

# I personally like using the '-u' flag as it shows most everything I am looking for
# however there are many other flags that might work better for the reader, the ps manpage is a great place to look
ps -u
USER   PID %CPU %MEM     VSZ   RSS TT  STAT STARTED    TIME COMMAND
root 77792  6.0  1.7 1097588 71120  0  IC+  13:27   6:51.49 bhyve: vm1 (bhyve)
root 61273  0.0  0.1   12840  2296 v0  Is+  12:25   0:00.01 /usr/libexec/getty Pc ttyv0
root 61384  0.0  0.1   12840  2296 v1  Is+  12:25   0:00.01 /usr/libexec/getty Pc ttyv1
root 61499  0.0  0.1   12840  2296 v2  Is+  12:25   0:00.01 /usr/libexec/getty Pc ttyv2
root 61617  0.0  0.1   12840  2292 v3  Is+  12:25   0:00.01 /usr/libexec/getty Pc ttyv3
root 61718  0.0  0.1   12840  2292 v4  Is+  12:25   0:00.01 /usr/libexec/getty Pc ttyv4
root 61724  0.0  0.1   12840  2296 v5  Is+  12:25   0:00.01 /usr/libexec/getty Pc ttyv5
root 61821  0.0  0.1   12840  2296 v6  Is+  12:25   0:00.01 /usr/libexec/getty Pc ttyv6
root 61838  0.0  0.1   12840  2312 v7  Is+  12:25   0:00.01 /usr/libexec/getty Pc ttyv7
root 62367  0.0  0.1   13660  3172  0  I    12:30   0:00.04 su
root 62406  0.0  0.1   13944  3840  0  I    12:30   0:00.10 _su (csh)
root  1084  0.0  0.1   13448  2884  1  R+   14:31   0:00.00 ps -u
root 80435  0.0  0.1   13660  3164  1  I    13:45   0:00.04 su
root 80436  0.0  0.1   13944  3880  1  S    13:45   0:00.27 _su (csh)

# We can grep for bhyve to just see information about our VMs (and the grep process).
ps -u | grep bhyve
root 77792  6.0  1.7 1097588 71120  0  IC+  13:27   6:53.65 bhyve: vm1 (bhyve)
root  1181  0.0  0.1   12816  2264  1  S+   14:32   0:00.00 grep bhyve

Another utility that we can use is bhyvectl. Bhyvectl is geared more towards development rather than for administration, however, it can still give admins useful information on running VMs. The bhyvectl man page is a bit light on information, but as noted in the man page, a full list of arguments can be obtained by running bhyvectl without and arguments. Most of the valid arguments appeared to be things related to CPU registers and hacking on the virtual processor which is not particularly useful for me at this time. However, there are a few arguments that are useful:

# This command will show the CPU topology for the VM
bhyvectl --vm=vm1 --get-cpu-tologoy

# This command give a lot of output, most of which looked like register values
# piping the output through head made it much more readable for me.
cpu_topology: sockets=1, cores=1, threads=1, maxcpus=4
bhyvectl --vm=vm1 --get-all | head -n 3
ID  Length      Name
0   1024MB      sysmem
1   16384KB     bootrom

Closing Thoughts

Hopefully this article was helpful to someone trying to learn more about bhyve. Thankfully there are great tools like vm-bhyve that exist to make things like administration of bhyve VMs much easier on admins than it is with the standard tools that bhyve has. It is, however, important to know how things work on the back-end, and this information will be helpful to me in a future project.