ADDED experiments/bhyve/Makefile Index: experiments/bhyve/Makefile ================================================================== --- /dev/null +++ experiments/bhyve/Makefile @@ -0,0 +1,20 @@ +VM= newhost +VERS= 13.2-RELEASE +DOWNLOAD= https://download.freebsd.org/releases/amd64/${VERS} + +.if ${VERS} == CURRENT +DOWNLOAD= https://download.freebsd.org/snapshots/amd64/15.0-CURRENT +.endif + +.PHONY: new-vm dist + +dist: dist/${VERS}-base.txz dist/${VERS}-kernel.txz + +dist/${VERS}-base.txz: + fetch -o ${.TARGET} ${DOWNLOAD}/base.txz + +dist/${VERS}-kernel.txz: + fetch -o ${.TARGET} ${DOWNLOAD}/kernel.txz + +new-vm: dist + ./bhyve.sh new ${VM} ADDED experiments/bhyve/bhyve.sh Index: experiments/bhyve/bhyve.sh ================================================================== --- /dev/null +++ experiments/bhyve/bhyve.sh @@ -0,0 +1,156 @@ +#!/bin/sh +set -e + +# to mount and access the disk on the host: +# mdconfig -a -t vnode -f guest.img +# zpool import -f -R /mnt/myguest -N 16143602688976745622 -t zguest +# zfs mount -a +# zpool export zguest +# mdconfig -d -u 0 + +# configure a new disk +# truncate -s 10G new.img +# mdconfig -a -t vnode -f new.img +# gpart create -s gpt /dev/md0 +# gpart add -a 4k -t freebsd-zfs /dev/md0 +# zpool create -m none -o altroot=/mnt/myguest -o autoexpand=on -O atime=off -t zguest zroot /dev/md0p1 + + +# this relies on host networking and NAT +## /etc/rc.conf: +# ifconfig_bridge1_name="bhyves" +# ifconfig_bhyves="inet 192.168.3.1/24 up" +# +## /etc/pf.conf: +# bhyve_if = "bhyves" +# bhyve_net = $bhyve_if:network +# +# set skip on lo +# scrub in +# +# nat on $ext_if from $bhyve_net -> ($ext_if:0) +# +# pass out +# +# block in +# +# pass in proto tcp to port { 22 } +# pass in inet proto icmp icmp-type { echoreq } +# pass on $bhyve_if from $bhyve_net +## + +load_vmm() +{ + if ! kldstat | awk '{print $5}' | grep '^vmm.ko$'; then + kldload vmm + fi +} + +_ifconfig() +{ + iface=tap-${1} + if ! ifconfig $iface > /dev/null; then + ifconfig tap create name $iface + fi + (ifconfig bhyves | grep "member: $iface" > /dev/null) || ifconfig bhyves addm $iface +} + +usage() +{ +cat< + ./bhyve.sh new + ./bhyve.sh mount + ./bhyve.sh unmount +EOF +exit 1 +} + +boot() +{ + vm=$1 + img=vms/${vm}.img + if [ ! -f $img ]; then + echo "error: $img not found" + exit 1 + fi + load_vmm > /dev/null + _ifconfig $vm + bhyveload -c stdio -m 4096M -d $img $vm + bhyve -c 4 -m 4096M -s 0:0,hostbridge -s 1:0,lpc -s 2:0,virtio-net,${iface} -s 3:0,virtio-blk,${img} -H -A -P -l com1,stdio $vm +} + +new_vm() +{ + vm=$1 + img=vms/${vm}.img + root=/mnt/bhyve-${vm} + vers=${VERS:-13.2-RELEASE} + base=dist/${vers}-base.txz + kernel=dist/${vers}-kernel.txz + + if [ ! -f $base -o ! -f $kernel ]; then + echo "error: make sure $base and $kernel are present" + echo "suggestion: make dist" + exit 1 + fi + + mkdir -p vms + truncate -s 24G $img + mdconfig -a -t vnode -f $img + gpart create -s gpt /dev/md0 + gpart add -a 4k -t freebsd-zfs /dev/md0 + zpool create -m / -o altroot=${root} -o autoexpand=on -O atime=off -t bhyve-${vm} zroot /dev/md0p1 + tar -C $root -xzf $base + tar -C $root -xzf $kernel + touch ${root}/etc/fstab + sysrc -f ${root}/etc/rc.conf hostname="${vm}" + sysrc -f ${root}/etc/rc.conf zfs_enable="YES" + sysrc -f ${root}/boot/loader.conf zfs_load="YES" + unmount $vm +} + +unmount() +{ + vm=$1 + zpool export bhyve-${vm} + md=$(mdconfig -l -f vms/${vm}.img | sed -e 's/^md//') + mdconfig -d -u $md + rmdir /mnt/bhyve-${vm} +} + +_mount() +{ + vm=$1 + img=vms/${vm}.img + if [ ! -f $img ]; then + echo "error: $img not found" + exit 1 + fi + md=$(mdconfig -a -f $img) + zid=$(zpool import -d /dev/${md}p1 | grep '^[[:space:]]* id: [[:digit:]]*' | awk '{print $2}') + zpool import -f -R /mnt/bhyve-${vm} -t $zid bhyve-${vm} +} + +case $1 in + boot) + if [ -z "$2" ]; then usage; fi + boot $2 + ;; + new) + if [ -z "$2" ]; then usage; fi + new_vm $2 + ;; + mount) + if [ -z "$2" ]; then usage; fi + _mount $2 + ;; + unmount) + if [ -z "$2" ]; then usage; fi + unmount $2 + ;; + *) + usage + ;; +esac ADDED experiments/bhyve/bin/boot.sh Index: experiments/bhyve/bin/boot.sh ================================================================== --- /dev/null +++ experiments/bhyve/bin/boot.sh @@ -0,0 +1,25 @@ +#!/bin/sh + +vm=$1 +iface=tap-${vm} +img=vms/${vm}.img + +if [ ! -f $img ]; then + echo "error: $img not found" + exit 1 +fi + +bhyve_exit=0 + +while [ $bhyve_exit -eq 0 ]; do + bhyve -c 4 -m 4096M \ + -s 0:0,hostbridge \ + -s 1:0,lpc \ + -s 2:0,virtio-net,${iface} \ + -s 3:0,virtio-blk,${img} \ + -H -A -P \ + -l com1,stdio \ + -l bootrom,/usr/local/share/uefi-firmware/BHYVE_UEFI.fd \ + $vm + bhyve_exit=$? +done ADDED experiments/bhyve/bin/bridge.sh Index: experiments/bhyve/bin/bridge.sh ================================================================== --- /dev/null +++ experiments/bhyve/bin/bridge.sh @@ -0,0 +1,5 @@ +#!/bin/sh +set -e +if ! ifconfig $1 > /dev/null ; then + ifconfig bridge create inet $2 name $1 up +fi ADDED experiments/bhyve/bin/config.sh Index: experiments/bhyve/bin/config.sh ================================================================== --- /dev/null +++ experiments/bhyve/bin/config.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +rc=${1}-rc.conf +root=/mnt/bhyve-${1} +vm_rc=${root}/etc/rc.conf + +if [ ! -f $rc ]; then + echo "error: missing $rc" + exit 1 +fi + +sysrc -f ${root}/boot/loader.conf zfs_load="YES" + +sysrc -f ${vm_rc} zfs_enable="YES" +commands=$(sed -e "s|^|sysrc -f $vm_rc |" $rc) +eval "$commands" ADDED experiments/bhyve/bin/mount.sh Index: experiments/bhyve/bin/mount.sh ================================================================== --- /dev/null +++ experiments/bhyve/bin/mount.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +vm=$1 +img=vms/${vm}.img + +if [ ! -f $img ]; then + echo "error: $img not found" + exit 1 +fi + +md=$(mdconfig -a -f $img) +zid=$(zpool import -d /dev/${md}p1 | grep '^[[:space:]]* id: [[:digit:]]*' | awk '{print $2}') +zpool import -f -R /mnt/bhyve-${vm} -t $zid bhyve-${vm} ADDED experiments/bhyve/bin/new-vm.sh Index: experiments/bhyve/bin/new-vm.sh ================================================================== --- /dev/null +++ experiments/bhyve/bin/new-vm.sh @@ -0,0 +1,40 @@ +#!/bin/sh +set -e + +vm=$1 +img=vms/${vm}.img +root=/mnt/bhyve-${vm} +boot=${root}-boot +vers=${VERS:-13.2-RELEASE} +base=dist/${vers}-base.txz +kernel=dist/${vers}-kernel.txz + +if [ ! -f $base -o ! -f $kernel ]; then + echo "error: make sure $base and $kernel are present" + echo "suggestion: make dist" + exit 1 +fi + +mkdir -p vms +truncate -s 24G $img + +md=$(mdconfig -a -t vnode -f $img) +disk=/dev/${md} + +# boot partition +gpart create -s gpt $disk +gpart add -a 4k -s 40M -t efi $disk +newfs_msdos -F 32 -c 1 ${disk}p1 + +# root partition +gpart add -a 4k -t freebsd-zfs $disk +zpool create -m / -o altroot=${root} -o autoexpand=on -O atime=off -t bhyve-${vm} zroot ${disk}p2 +tar -C $root -xzf $base +tar -C $root -xzf $kernel +touch ${root}/etc/fstab + +# copy boot loader +mount -t msdosfs -o longnames ${disk}p1 $boot +mkdir -p ${boot}/EFI/BOOT +cp ${root}/boot/loader.efi ${boot}/EFI/BOOT/BOOTX64.efi +umount $boot ADDED experiments/bhyve/bin/tap.sh Index: experiments/bhyve/bin/tap.sh ================================================================== --- /dev/null +++ experiments/bhyve/bin/tap.sh @@ -0,0 +1,11 @@ +#!/bin/sh +set -e + +iface=tap-${1} +bridge=$2 + +if ! ifconfig $iface > /dev/null; then + ifconfig tap create name $iface +fi + +(ifconfig $bridge | grep "member: $iface" > /dev/null) || ifconfig $bridge addm $iface ADDED experiments/bhyve/bin/unmount.sh Index: experiments/bhyve/bin/unmount.sh ================================================================== --- /dev/null +++ experiments/bhyve/bin/unmount.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +vm=$1 +zpool export bhyve-${vm} +md=$(mdconfig -l -f vms/${vm}.img | sed -e 's/^md//') +mdconfig -d -u $md +rmdir /mnt/bhyve-${vm} ADDED experiments/bhyve/example-rc.conf Index: experiments/bhyve/example-rc.conf ================================================================== --- /dev/null +++ experiments/bhyve/example-rc.conf @@ -0,0 +1,3 @@ +hostname="example" +ifconfig_vtnet0="192.168.6.2/24" +defaultrouter="192.168.6.1" ADDED experiments/bhyve/example.mk Index: experiments/bhyve/example.mk ================================================================== --- /dev/null +++ experiments/bhyve/example.mk @@ -0,0 +1,20 @@ +.PHONY: vm bridge iface boot + +vm: vms/example.img + +bridge: + ./bin/bridge.sh bh2 192.168.5.1/24 + +iface: bridge + ./bin/tap.sh example bh2 + +vms/example.img: example-rc.conf + if [ -f ${.TARGET} ]; then ./bin/mount.sh example; else ./bin/new-vm.sh example; fi + ./bin/config.sh example + ./bin/unmount.sh example + +boot: vms/example.img iface + ./bin/boot.sh example + +destroy: + if [ -f /dev/vmm/example ]; then bhyvectl --destroy --vm=example; fi