bhyve Start a virtual machine in background

Hello everyone!

I'm creating an rc.d script to start a virtual machine at reboot, which is accessible by remote-connection.
The problem is, I'm not able to let the machine start in background, so that I can still continue working with the shell of the FreeBSD PC (which is, to be precise, a TwinCat/BSD-IPC).
The virtual machine (OS: Windows 10) that should be started, has already been created previously and is also reachable via the remote-connection.
Has anybody an idea what the problem could be?
By the way, the script is saved in /usr/local/bin and is linked to the /usr/local/etc/rc.d directory, just in case this is relevant.

This is the script I created:
Code:
#!/bin/sh
# SPDX-License-Identifier: 0BSD
# Copyright (C) 2019 - 2022 Beckhoff Automation GmbH & Co. KG

# PROVIDE: ${name}
# REQUIRE: DAEMON NETWORKING dmesg
# BEFORE: LOGIN TcSystemService
# KEYWORD: nojail shutdown

. /etc/rc.subr

name="samplevm"
rcvar="${name}_enable"

command="/usr/local/bin/${name}"

export PATH="${PATH}:/usr/local/bin:/usr/local/sbin"

start_cmd="${command} start > /dev/null 2>&1 &"
stop_cmd="${command} stop > /dev/null 2>&1 &"
status_cmd="${command} status"

set -e
set -u

usage() {
    cat >&2 << EOF
USAGE: ${0##*/} [COMMAND]
Control the virtual machine environment named '${name}'
COMMANDS:
    start       Start the VM
    stop        Shutdown the running VM
    help        Print this help message
EXAMPLES
# run the virual machine
${0##*/} start
# shutdown the virtual machine
${0##*/} stop
EOF
}

# Cleanup any resources used by the VM after shutdown
cleanup() {
    # do not trap during cleanup procedure
    trap '' EXIT
    set +e
    set +u
    pfctl -a "bhf/bhyve/${name}" -f /dev/null > /dev/null 2>&1
    if test -e "${temp_firewall_rules}"; then
        rm "${temp_firewall_rules}"
    fi
}

prepare_host() {
    # Ensure that kernel modul vmm.ko is loaded
    kldload -n vmm.ko

    # accept incoming VNC and remote connections
        service pf stop
    temp_firewall_rules="/etc/pf.conf.d/${name}"
    printf "pass in quick proto tcp to port %s\n" "${samplevm_vncport}" > "${temp_firewall_rules}"
    pfctl -a bhf/bhyve/"${name}" -f "${temp_firewall_rules}"

}

run_vm() {
    trap 'cleanup' EXIT

    prepare_host

    while true; do
# destroy former VM instance to ensure we start
# with a clean VM configuration
    if test -e /dev/vmm/${name}; then
        bhyvectl --vm="${name}" --destroy
        echo "current VM was beeing destroyed in order to restart"
    else 
        echo "VM starting..."
    fi

#check if mountpoint exists
    if !(zfs list -H -o mountpoint | grep -q ${samplevm_path}); then
        zfs create -p -o mountpoint=${samplevm_path} zroot${samplevm_path}
    fi

#create a disk for the virtual machine, size of 40GB is necessarily needed for Windows 10 installation
    if (zfs list | grep -F -q "zroot${samplevm_path}/disk0"); then
        echo "existing disk is used"
        #check if size is ok
        if zfs get volsize zroot${samplevm_path}/disk0 | grep -q "50G"; then
            #size is ok
        else
            zfs set volsize=50G zroot${samplevm_path}/disk0
        fi
    else
        zfs create -V 50G zroot${samplevm_path}/disk0
    fi

# create an interface for the virtual machine 
    if ifconfig | grep -q tap0; then
        # use existing
    else 
        ifconfig tap create
        sysrc cloned_interfaces+="tap0"
    fi

# create a bridge if not already existing
    if ifconfig | grep -q bridge0; then
        #use existing
        if -q "ifconfig_bridge0" /etc/rc.conf; then
            #persistant configuration finished
        else 
            sysrc ifconfig_bridge0="addm igb1 addm tap0"
        fi
    else
        ifconfig bridge create
        sysrc cloned_interfaces+="bridge0"
        sysrc ifconfig_bridge0="addm igb1 addm tap0"
    fi

# set ppt driver (PCI PassThrough) 
    if (pciconf -l | grep -F -q "igb2@pci0:3:0:0:"); then 
        devctl set driver -f pci0:3:0:0 ppt
    elif (pciconf -l | grep -q "ppt0@pci0:3:0:0:"); then
        echo "pass through driver is set to igb2"
        # ppt was already set to igb2 
    else 
        echo "an error occured, please check the pass-through configuration with pciconf -l and change the settings"
    fi 

    if grep -F -q "3/0/0" /boot/loader.conf; then
        #already persistantly safed
    else
        echo "pptdevs="3/0/0"" >> /boot/loader.conf
    fi

    if test -e ${samplevm_path}/BHYVE_BHF_UEFI_VARS.fd; then
        # VARS-File already copied in the vm-path 
    elif !(test -e ${samplevm_path}/BHYVE_BHF_UEFI_VARS.fd); then
    if test -e ${samplevm_path}/; then
        cp /usr/local/share/uefi-firmware/BHYVE_BHF_UEFI_VARS.fd ${samplevm_path}/;
    else
        mkdir -m a+rwx ${samplevm_path}
        cp /usr/local/share/uefi-firmware/BHYVE_BHF_UEFI_VARS.fd ${samplevm_path}/;
    fi 
fi


    _bhyve_rc=0
   bhyve \
        -c sockets=1,cores=1,threads=1 \
        -m 2G \
        -s 0,hostbridge \
        -s 10,nvme,/dev/zvol/zroot/vms/samplevm/disk0 \
        -s 20,virtio-net,tap0 \
        -s 21,passthru,3/0/0 \
        -s 30,xhci,tablet \
        -s 31,lpc \
        -l com1,stdio \
        -l bootrom,/usr/local/share/uefi-firmware/BHYVE_BHF_UEFI.fd,${samplevm_path}/BHYVE_BHF_UEFI_VARS.fd \
        -H -P -A -S -w \
        "${name}" || _bhyve_rc=$?

    if test "${_bhyve_rc}" -ne 0; then
        break
    fi
done
}
shutdown_vm() {
    # do not trap on exit during shutdown command
    trap '' EXIT
    set +e
    set +u

    kill "${_pid}"
}

get_bhyve_pid() {
    printf "%s" "$(pgrep -f "bhyve: ${name}")"
}

# Execution of virtual machines requires root previleges
if test "$(id -u)" -ne 0; then
    printf "%s must be run as root\n" "${0##*/}"
    exit 1
fi

# Default values for VM configuration
: ${samplevm_enable:="NO"}
: ${samplevm_vncport:="5900"}
: ${samplevm_path:="/vms/samplevm"}
readonly _cmd="${1?Error: No COMMAND specified$(usage)}"

_pid="$(get_bhyve_pid)"

case "${_cmd}" in
    start)
        if test -z "${_pid:+x}"; then
            run_vm
        else
            printf "%s is already running with pid: %s\n" "${name}" "${_pid}"
            exit 1
        fi
        ;;

    stop)
        if ! test -z "${_pid:+x}"; then
            shutdown_vm
        fi
        ;;

    status)
        if ! test -z "${_pid:+x}"; then
            printf "'%s' is running with pid: %s\n" "${name}" "${_pid}"
        else
            printf "'%s' is not running.\n" "${name}"
        fi
        ;;
Would be great if anyone out there could help me further.
Thanks in advance!
 
I have installed TwinCAT BSD, I don't know how to make the bhyve virtual machine start with the operating system? did you manage to solve it?
 
Mimi and Mimo
If I were a guessing person I bet they are related.

Anyway here is how I have started bhyve in the past.
rc.local script
tmux it
daemon it.

Some of this depends on EFI or Legacy VM's.
 
Or use sysutils/vm-bhyve to create and manage your VMs.

Code:
root@hosaka:~ # vm list
NAME            DATASTORE  LOADER     CPU  MEMORY  VNC           AUTO      STATE
case            default    bhyveload  4    4096M   -             Yes [4]   Running (38464)
jenkins         default    bhyveload  4    4096M   -             Yes [6]   Running (55368)
kdc             default    uefi       2    2048M   0.0.0.0:5901  Yes [2]   Running (1949)
lady3jane       default    bhyveload  4    8192M   -             Yes [3]   Running (40702)
debian          stor10k    uefi       4    4096M   -             No        Stopped
errol           stor10k    bhyveload  2    4096M   -             Yes [9]   Running (62211)
fbsd-test       stor10k    bhyveload  2    4096M   -             Yes [13]  Running (11366)
foreman         stor10k    uefi       4    8192M   -             No        Stopped
gl-runner-1     stor10k    bhyveload  4    4096M   -             Yes [12]  Running (61774)
gl-runner-2     stor10k    bhyveload  4    4096M   -             No        Stopped
k8s             stor10k    grub       4    8192M   -             Yes [14]  Running (5564)
kibana          stor10k    bhyveload  4    8192M   -             Yes [1]   Running (43029)
phabricator     stor10k    bhyveload  1    4096M   -             No        Stopped
plex            stor10k    bhyveload  4    4096M   -             Yes [7]   Running (61990)
riviera         stor10k    bhyveload  2    4096M   -             Yes [11]  Running (23309)
sdgame01        stor10k    bhyveload  4    4096M   -             No        Stopped
tessierashpool  stor10k    bhyveload  2    4096M   -             Yes [5]   Running (40818)
ubuntu          stor10k    uefi       2    4096M   -             No        Stopped
wintermute      stor10k    bhyveload  4    4096M   -             Yes [10]  Running (12031)
 
Back
Top