~patmaddox

Changes On Branch bhyve
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Changes In Branch bhyve Excluding Merge-Ins

This is equivalent to a diff from 0b669eb036 to 8ce3666331

2023-11-08
17:54
merge bhyve

- use a makefile
- UEFI boot instead of bhyveload
- support rebooting
- support CURRENT check-in: cef3e91bc3 user: patmaddox tags: old-trunk

17:49
bhyve: UEFI boot instead of using bhyveload Closed-Leaf check-in: 8ce3666331 user: patmaddox tags: bhyve
17:48
bhyve: making the VM does not require an iface, only booting does check-in: 0561e4111d user: patmaddox tags: bhyve
2023-05-13
22:44
bhyve: start a script that just loads `vmm.ko` on demand check-in: cf96a69cb4 user: patmaddox tags: bhyve
22:16
sh: alias j=just in home dir; t=open new terminal tab check-in: 09269c0e06 user: patmaddox tags: old-trunk
2023-05-12
22:48
fossil: `just branch` to make / switch to a branch checkout check-in: 0b669eb036 user: patmaddox tags: old-trunk
20:49
fossil: ignore backup fossil files check-in: 7d74576efa user: patmaddox tags: old-trunk

Added experiments/bhyve/Makefile.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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.

























































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
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<<EOF
Usage:
  ./bhyve.sh boot <vm>
  ./bhyve.sh new <vm>
  ./bhyve.sh mount <vm>
  ./bhyve.sh unmount <vm>
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.



















































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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.











>
>
>
>
>
1
2
3
4
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.

































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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.



























>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
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.

















































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
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.























>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
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.















>
>
>
>
>
>
>
1
2
3
4
5
6
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.







>
>
>
1
2
3
hostname="example"
ifconfig_vtnet0="192.168.6.2/24"
defaultrouter="192.168.6.1"

Added experiments/bhyve/example.mk.









































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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