At the end of my bhyve and libvirt post is note that booting with grub isn’t automatic:

Needing to manually tell grub how to boot the VM is frustrating but being able to use virtio for the disk and network is good enough.

I solved this a while ago and forgot to include how. Eventually, I noticed the Debian cloud image I used as a base used extlinux to boot instead of what I expected, grub. Grub can’t boot if there’s no grub config so I installed grub2, set the configuration, and installed it on disk. The VM booted fine after that.

Later on I tried to boot a CentOS 7 cloud image. I knew it used grub already but it wouldn’t boot when using virsh start. After several times back and forth between my Linux laptop, where I could dissect the image, and the VM host running FreeBSD, where I only had access to the serial console, I noticed the problem. The key thing is the command may be grub-bhyve but the package name is grub2-bhyve. The problem is easier to see with the --help option:

grub-bhyve --help
Usage: grub-bhyve [OPTION...] vmname
...
  -d, --directory=DIR        use GRUB files in the directory DIR
                             [default=/boot/grub]

By default it checks for the grub configuration in /boot/grub. Debian uses /boot/grub so I didn’t notice. CentOS 7 however uses /boot/grub2 (and has /boot/grub1). I added a grub symlink to point to grub2, ran virsh start and it booted fine too.

Summary: make sure /boot/grub exists and has a usable grub.cfg. Grub does not have to be installed to the disk because that bootloader isn’t run.