diff --git a/usr.sbin/bhyve/bhyve.8 b/usr.sbin/bhyve/bhyve.8 index 8001b5276d51..6c725537f97a 100644 --- a/usr.sbin/bhyve/bhyve.8 +++ b/usr.sbin/bhyve/bhyve.8 @@ -1,1209 +1,1218 @@ .\" Copyright (c) 2013 Peter Grehan .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd April 26, 2024 +.Dd August 21, 2024 .Dt BHYVE 8 .Os .Sh NAME .Nm bhyve .Nd "run a guest operating system inside a virtual machine" .Sh SYNOPSIS .Nm .Op Fl aCDeHhPSuWwxY .Oo .Sm off .Fl c\~ .Oo .Op Cm cpus= .Ar numcpus .Oc .Op Cm ,sockets= Ar n .Op Cm ,cores= Ar n .Op Cm ,threads= Ar n .Oc .Sm on .Oo Fl f .Sm off .Ar name Cm \&, .Oo .Cm string No | Cm file .Oc .Cm \&= Ar data .Sm on .Oc .Oo .Sm off .Fl G\~ .Oo Ar w Oc .Oo Ar bind_address Cm \&: Oc .Ar port .Sm on .Oc .Op Fl k Ar config_file .Op Fl K Ar layout .Oo Fl l .Sm off .Ar lpcdev Op Cm \&, Ar conf .Sm on .Oc .Sm off .Oo Fl m\~ .Ar memsize .Oo .Cm K | Cm k | Cm M | Cm m | Cm G | Cm g | Cm T | Cm t .Oc .Sm on .Oc .Op Fl o Ar var Ns Cm = Ns Ar value .Op Fl p Ar vcpu Ns Cm \&: Ns Ar hostcpu .Op Fl r Ar file .Sm off .Oo Fl s\~ .Ar slot Cm \&, Ar emulation Op Cm \&, Ar conf .Sm on .Oc .Op Fl U Ar uuid .Ar vmname .Nm .Fl l Cm help .Nm .Fl s Cm help .Sh DESCRIPTION .Nm is a hypervisor that runs guest operating systems inside a virtual machine. It can run guests on amd64 and arm64 platforms with suitable hardware support. .Pp Parameters such as the number of virtual CPUs, amount of guest memory, and I/O connectivity can be specified with command-line parameters. .Pp .Nm is typically used with a boot ROM that can load the guest operating system. On arm64 platforms, this is currently required. If not using a boot ROM, the guest operating system must be loaded with .Xr bhyveload 8 or a similar boot loader before running .Nm , otherwise. On amd64, the .Pa edk2-bhyve package provides a UEFI firmware that can be used to boot the guest; on arm64 the .Pa u-boot-bhyve-arm64 package provides a U-Boot image that can be used to boot the guest. .Pp .Nm runs until the guest operating system reboots or an unhandled hypervisor exit is detected. .Sh OPTIONS .Bl -tag -width 10n .It Fl a The guest's local APIC is configured in xAPIC mode. This option only applies to the amd64 platform. xAPIC mode is the default setting so this option is redundant. It will be deprecated in a future version. .It Fl C Include guest memory in core files. .It Fl c Op Ar setting ... Number of guest virtual CPUs and/or the CPU topology. The default value for each of .Ar numcpus , .Ar sockets , .Ar cores , and .Ar threads is 1. If .Ar numcpus is not specified then it will be calculated from the other arguments. The topology must be consistent in that the .Ar numcpus must equal the product of .Ar sockets , .Ar cores , and .Ar threads . If a .Ar setting is specified more than once the last one has precedence. .Pp The maximum number of virtual CPUs defaults to the number of active physical CPUs in the system available via the .Va hw.vmm.maxcpu .Xr sysctl 8 variable. The limit can be adjusted via the .Va hw.vmm.maxcpu loader tunable. .It Fl D Destroy the VM on guest initiated power-off. .It Fl e Force .Nm to exit when a guest issues an access to an I/O port that is not emulated. This is intended for debug purposes and only applies to the amd64 platform. .It Fl f Ar name Ns Cm \&, Ns Oo Cm string Ns No | Ns Cm file Ns Oc Ns Cm \&= Ns Ar data Add a fw_cfg file .Ar name to the fw_cfg interface. If a .Cm string is specified, the fw_cfg file contains the string as data. If a .Cm file is specified, bhyve reads the file and adds the file content as fw_cfg data. .It Fl G Xo .Sm off .Oo Ar w Oc .Oo Ar bind_address Cm \&: Oc .Ar port .Sm on .Xc Start a debug server that uses the GDB protocol to export guest state to a debugger. An IPv4 TCP socket will be bound to the supplied .Ar bind_address and .Ar port to listen for debugger connections. Only a single debugger may be attached to the debug server at a time. If the option begins with .Sq w , .Nm will pause execution at the first instruction waiting for a debugger to attach. .It Fl H Yield the virtual CPU thread when a HLT instruction is detected. If this option is not specified, virtual CPUs will use 100% of a host CPU. This option applies only to the amd64 platform. .It Fl h Print help message and exit. .It Fl k Ar config_file Set configuration variables from a simple, key-value config file. Each line of the config file is expected to consist of a config variable name, an equals sign .Pq Sq = , and a value. No spaces are permitted between the variable name, equals sign, or value. Blank lines and lines starting with .Sq # are ignored. See .Xr bhyve_config 5 for more details. .It Fl K Ar layout Specify the keyboard layout. The value that can be specified sets the file name in .Ar /usr/share/bhyve/kbdlayout . This specification only works when loaded with UEFI mode for VNC. When using a VNC client that supports QEMU Extended Key Event Message (e.g. TigerVNC), this option isn't needed. When using a VNC client that doesn't support QEMU Extended Key Event Message (e.g. tightVNC), the layout defaults to the US keyboard unless specified otherwise. .It Fl l Cm help Print a list of supported LPC devices. .It Fl l Ar lpcdev Ns Op Cm \&, Ns Ar conf Allow devices behind the LPC PCI-ISA bridge to be configured. The only supported devices are the TTY-class devices .Cm com1 , com2 , com3 , and .Cm com4 , the TPM module .Cm tpm , the boot ROM device .Cm bootrom , the .Cm fwcfg type and the debug/test device .Cm pc-testdev . .Pp The possible values for the .Ar conf argument are listed in the .Fl s flag description. .Pp This option applies only to the amd64 platform. On arm64, the console and boot ROM devices are configured using the more generic .Fl o option. .It Xo .Fl m Ar memsize Ns Oo .Sm off .Cm K | k | M | m | G | g | T | t .Sm on .Oc .Xc Set the guest physical memory size. This must be the same size that was given to .Xr bhyveload 8 . .Pp The size argument may be suffixed with one of .Cm K , M , G or .Cm T (either upper or lower case) to indicate a multiple of kilobytes, megabytes, gigabytes, or terabytes. If no suffix is given, the value is assumed to be in megabytes. .Pp The default is 256M. .It Fl o Ar var Ns Cm = Ns Ar value Set the configuration variable .Ar var to .Ar value . See .Xr bhyve_config 5 for configuration options. .It Fl P Force the guest virtual CPU to exit when a PAUSE instruction is detected. This option applies only to the amd64 platform. .It Fl p Ar vcpu Ns Cm \& : Ns Ar hostcpu Pin guest's virtual CPU .Em vcpu to .Em hostcpu . Host CPUs and guest virtual CPUs are numbered starting from 0. A .Fl p option is required for every guest vCPU to be pinned. To map a 4 vCPU guest to host CPUs 12-15: .Bd -literal -p 0:12 -p 1:13 -p 2:14 -p 3:15 .Ed .It Fl r Ar file Resume a guest from a snapshot. The guest memory contents are restored from .Ar file , and the guest device and vCPU state are restored from the file .Dq Ar file Ns .kern . .Pp Note that the current snapshot file format requires that the configuration of devices in the new VM match the VM from which the snapshot was taken by specifying the same .Fl s and .Fl l options. The count of vCPUs and memory configuration are read from the snapshot. .It Fl S Wire guest memory. .It Fl s Cm help Print a list of supported PCI devices. .It Fl s Ar slot Ns Cm \&, Ns Ar emulation Ns Op Cm \&, Ns Ar conf Configure a virtual PCI slot and function. .Pp .Nm provides PCI bus emulation and virtual devices that can be attached to slots on the bus. There are 32 available slots, with the option of providing up to 8 functions per slot. .Pp The .Ar slot can be specified in one of the following formats: .Pp .Bl -bullet -compact .It .Ar pcislot .It .Sm off .Ar pcislot Cm \&: Ar function .Sm on .It .Sm off .Ar bus Cm \&: Ar pcislot Cm \&: Ar function .Sm on .El .Pp The .Ar pcislot value is 0 to 31. The optional .Ar function value is 0 to 7. The optional .Ar bus value is 0 to 255. If not specified, the .Ar function value defaults to 0. If not specified, the .Ar bus value defaults to 0. .Pp See .Sx "PCI EMULATION" for available options for the .Ar emulation argument. .It Fl U Ar uuid Set the universally unique identifier .Pq UUID in the guest's System Management BIOS System Information structure. By default a UUID is generated from the host's hostname and .Ar vmname . .It Fl u RTC keeps UTC time. .It Fl W Force virtio PCI device emulations to use MSI interrupts instead of MSI-X interrupts. .It Fl w Ignore accesses to unimplemented Model Specific Registers (MSRs). This is intended for debug purposes. .It Fl x The guest's local APIC is configured in x2APIC mode. This option applies only to the amd64 platform. .It Fl Y Disable MPtable generation. This option applies only to the amd64 platform. .It Ar vmname Alphanumeric name of the guest. This should be the same as that created by .Xr bhyveload 8 . .El .Sh PCI EMULATION .Nm provides emulation for various PCI devices. They are specified by the .Fl s .Ar slot,emulation,conf configuration's .Ar emulation argument, which can be one of the following: .Bl -tag -width "amd_hostbridge" .It Cm hostbridge A simple host bridge. This is usually configured at slot 0, and is required by most guest operating systems. .It Cm amd_hostbridge Emulation identical to .Cm hostbridge using a PCI vendor ID of AMD. .It Cm passthru PCI pass-through device. .It Cm virtio-net Virtio network interface. .It Cm virtio-blk Virtio block storage interface. .It Cm virtio-scsi Virtio SCSI interface. .It Cm virtio-9p Virtio 9p (VirtFS) interface. .It Cm virtio-rnd Virtio RNG interface. .It Cm virtio-console Virtio console interface, which exposes multiple ports to the guest in the form of simple char devices for simple IO between the guest and host userspaces. .It Cm virtio-input Virtio input interface. .It Cm ahci AHCI controller attached to arbitrary devices. .It Cm ahci-cd AHCI controller attached to an ATAPI CD/DVD. .It Cm ahci-hd AHCI controller attached to a SATA hard drive. .It Cm e1000 Intel e82545 network interface. .It Cm uart PCI 16550 serial device. .It Cm lpc LPC PCI-ISA bridge with COM1, COM2, COM3, and COM4 16550 serial ports, a boot ROM, and, optionally, a fwcfg type, and the debug/test device. The LPC bridge emulation can only be configured on bus 0. .It Cm fbuf Raw framebuffer device attached to VNC server. .It Cm xhci eXtensible Host Controller Interface (xHCI) USB controller. .It Cm nvme NVM Express (NVMe) controller. .It Cm hda High Definition Audio Controller. .El .Pp The optional parameter .Ar conf describes the backend for device emulations. If .Ar conf is not specified, the device emulation has no backend and can be considered unconnected. .Ss Network device backends .Sm off .Bl -bullet .It .Xo .Cm tap Ar N .Op Cm \&,mac= Ar xx:xx:xx:xx:xx:xx .Op Cm \&,mtu= Ar N .Xc .It .Xo .Cm vmnet Ar N .Op Cm \&,mac= Ar xx:xx:xx:xx:xx:xx .Op Cm \&,mtu= Ar N .Xc .It .Xo .Cm netgraph,path= Ar ADDRESS Cm \&,peerhook= Ar HOOK .Op Cm \&,socket= Ar NAME .Op Cm \&,hook= Ar HOOK .Op Cm \&,mac= Ar xx:xx:xx:xx:xx:xx .Op Cm \&,mtu= Ar N .Xc .It .Xo .Cm slirp,hostfwd= Ar proto : Ar hostaddr : Ar hostport - Ar guestaddr : Ar guestport .Xc .El .Sm on .Pp If .Cm mac is not specified, the MAC address is derived from a fixed OUI, and the remaining bytes from an MD5 hash of the slot and function numbers and the device name. .Pp The MAC address is an ASCII string in .Xr ethers 5 format. .Pp With .Cm virtio-net devices, the .Cm mtu parameter can be specified to inform the guest about the largest MTU that should be allowed, expressed in bytes. .Pp With .Cm netgraph backend, the .Cm path and .Cm peerhook parameters must be specified to set the destination node and corresponding hook. The optional parameters .Cm socket and .Cm hook may be used to set the .Xr ng_socket 4 node name and source hook. The .Ar ADDRESS , .Ar HOOK , and .Ar NAME must comply with .Xr netgraph 4 addressing rules. .Pp The slirp backend can be used to provide a NATed network to the guest. This backend has poor performance but does not require any network configuration on the host system. It depends on the .Pa net/libslirp port. The .Cm hostfwd option takes a 5-tuple describing how connections from the host are to be forwarded to the guest. Multiple rules can be specified, separated by semicolons. Note that semicolons must be escaped or quoted to prevent the shell from interpreting them. .Ss Block storage device backends: .Bl -bullet .Sm off .It .Ar /filename Op Cm \&, Ar block-device-options .It .Ar /dev/xxx Op Cm \&, Ar block-device-options .Sm on .El .Pp The .Ar block-device-options are: .Bl -tag -width 10n .It Cm nocache Open the file with .Dv O_DIRECT . .It Cm direct Open the file using .Dv O_SYNC . .It Cm ro Force the file to be opened read-only. .It Cm sectorsize= Ns Ar logical Ns Oo Cm \&/ Ns Ar physical Oc Specify the logical and physical sector sizes of the emulated disk. The physical sector size is optional and is equal to the logical sector size if not explicitly specified. .It Cm nodelete Disable emulation of guest trim requests via .Dv DIOCGDELETE requests. .It Li bootindex= Ns Ar index Add the device to the bootorder at .Ar index . A fwcfg file is used to specify the bootorder. The guest firmware may ignore or doesn't support this fwcfg file. In that case, this feature doesn't work as expected. .El .Ss SCSI device backends .Bl -bullet .Sm off .It .Pa /dev/cam/ctl Oo Ar pp Cm \&. Ar vp Oc Oo Cm \&, Ar scsi-device-options Oc .Sm on .El .Pp The .Ar scsi-device-options are: .Bl -tag -width 10n .It Cm iid= Ns Ar IID Initiator ID to use when sending requests to specified CTL port. The default value is 0. .It Li bootindex= Ns Ar index Add the device to the bootorder at .Ar index . A fwcfg file is used to specify the bootorder. The guest firmware may ignore or doesn't support this fwcfg file. In that case, this feature doesn't work as expected. .El .Ss 9P device backends .Bl -bullet .Sm off .It .Ar sharename Cm = Ar /path/to/share Op Cm \&, Ar 9p-device-options .Sm on .El .Pp The .Ar 9p-device-options are: .Bl -tag -width 10n .It Cm ro Expose the share in read-only mode. .El .Ss TTY device backends .Bl -tag -width 10n .It Cm stdio Connect the serial port to the standard input and output of the .Nm process. .It Ar /dev/xxx Use the host TTY device for serial port I/O. +.It Ar tcp=ip:port +Use the TCP server for serial port I/O. +Configuring this option will start a TCP server that waits for connections. +Only one connection is allowed at any time. Other connection try to connect +to TCP server will be disconnected immediately. Note that this feature +allows unprivileged users to access the guest console, so ensure that +access is appropriately restricted. .El .Ss TPM device backends .Bl -bullet .Sm off .It .Ar type Ns \&, Ns Ar path Ns Op Cm \&, Ns Ar tpm-device-options .Sm on .El .Pp Emulate a TPM device. The argument .Ar path needs to point to a valid TPM device path, i.e. .Pa /dev/tpm0 . .El .Pp Supported options for .Ar type : .Bl -tag -width 10n .It Cm passthru pass a physical TPM device through to the guest .El .Pp The .Ar tpm-device-options are: .Bl -tag -width 10n .It Cm version= Ns Ar version Version of the TPM device according to the TCG specification. Defaults to .Cm 2.0 .El .Ss Boot ROM device backends .Sm off .Bl -bullet .It .Ar romfile Ns Op Cm \&, Ns Ar varfile .El .Sm on .Pp Map .Ar romfile in the guest address space reserved for boot firmware. .Pp If .Ar varfile is provided, that file is also mapped in the boot firmware guest address space, and any modifications the guest makes will be saved to that file. .Pp Fwcfg types: .Bl -tag -width 10n .It Ar fwcfg The fwcfg interface is used to pass information such as the CPU count or ACPI tables to the guest firmware. Supported values are .Ql bhyve and .Ql qemu . Due to backward compatibility reasons, .Ql bhyve is the default option. When .Ql bhyve is used, bhyve's fwctl interface is used. It currently reports only the CPU count to the guest firmware. The .Ql qemu option uses QEMU's fwcfg interface. This interface is widely used and allows user-defined information to be passed to the guest. It is used for passing the CPU count, ACPI tables, a boot order and many other things to the guest. Some operating systems such as Fedora CoreOS can be configured by qemu's fwcfg interface as well. .El .Ss Pass-through device backends .Sm off .Bl -bullet .It .Cm ppt Ar N Oo , Ar passthru-device-options Oc .It .Ns Ar bus Cm \&/ Ar slot Cm \&/ Ar function .Op , Ar passthru-device-options .It .Cm pci Ar bus Cm : Ar slot Cm : Ns Ar function .Op , Ar passthru-device-options .El .Sm on .Pp Connect to a PCI device on the host either named ppt .Ns Ar N or at the selector described by .Ar slot , .Ar bus , and .Ar function numbers. .Pp The .Ar passthru-device-options are: .Bl -tag -width 10n .It Cm rom= Ns Ar romfile Add .Ar romfile as option ROM to the PCI device. The ROM will be loaded by firmware and should be capable of initializing the device. .It Li bootindex= Ns Ar index Add the device to the bootorder at .Ar index . A fwcfg file is used to specify the bootorder. The guest firmware may ignore or doesn't support this fwcfg file. In that case, this feature doesn't work as expected. .El .Pp Guest memory must be wired using the .Fl S option when a pass-through device is configured. .Pp The host device must have been reserved at boot-time using the .Va pptdevs loader variable as described in .Xr vmm 4 . .Ss Virtio console device backends .Bl -bullet .Sm off .It .Cm port1= Ns Ar /path/to/port1.sock Ns Op Cm ,port Ns Ar N Cm \&= Ns Ar /path/to/port2.sock No \~ Ar ... .Sm on .El .Pp A maximum of 16 ports per device can be created. Every port is named and corresponds to a Unix domain socket created by .Nm . .Nm accepts at most one connection per port at a time. .Pp Limitations: .Bl -bullet .It Due to the lack of destructors in .Nm , sockets on the filesystem must be cleaned up manually after .Nm exits. .It There is no way to use the .Dq console port feature, nor the console port resize at present. .It Emergency write is advertised, but no-op at present. .El .Ss Virtio input device backends: .Bl -bullet .Sm off .It .Ar /dev/input/eventX .Sm on .El .Pp Send input events of .Ar /dev/input/eventX to guest by VirtIO Input Interface. .Ss Framebuffer device backends .Bl -bullet .Sm off .It .Op Cm rfb= Ar ip-and-port .Op Cm ,w= Ar width .Op Cm ,h= Ar height .Op Cm ,vga= Ar vgaconf .Op Cm ,wait .Op Cm ,password= Ar password .Sm on .El .Pp Configuration options are defined as follows: .Bl -tag -width 10n .It Cm rfb= Ns Ar ip-and-port Pq or Cm tcp= Ns Ar ip-and-port An IP address and a port VNC should listen on. There are two formats: .Pp .Bl -bullet -compact .It .Sm off .Op Ar IPv4 Cm \&: .Ar port .Sm on .It .Sm off .Cm \&[ Ar IPv6%zone Cm \&] Cm \&: Ar port .Sm on .El .Pp The default is to listen on localhost IPv4 address and default VNC port 5900. An IPv6 address must be enclosed in square brackets and may contain an optional zone identifier. .It Cm w= Ns Ar width No and Cm h= Ns Ar height A display resolution, width and height, respectively. If not specified, a default resolution of 1024x768 pixels will be used. Minimal supported resolution is 640x480 pixels, and maximum is 3840x2160 pixels. .It Cm vga= Ns Ar vgaconf Possible values for this option are .Cm io (default), .Cm on , and .Cm off . PCI graphics cards have a dual personality in that they are standard PCI devices with BAR addressing, but may also implicitly decode legacy VGA I/O space .Pq Ad 0x3c0-3df and memory space .Pq 64KB at Ad 0xA0000 . The default .Cm io option should be used for guests that attempt to issue BIOS calls which result in I/O port queries, and fail to boot if I/O decode is disabled. .Pp The .Cm on option should be used along with the CSM BIOS capability in UEFI to boot traditional BIOS guests that require the legacy VGA I/O and memory regions to be available. .Pp The .Cm off option should be used for the UEFI guests that assume that VGA adapter is present if they detect the I/O ports. An example of such a guest is .Ox in UEFI mode. .Pp Please refer to the .Nm .Fx wiki page .Pq Lk https://wiki.freebsd.org/bhyve for configuration notes of particular guests. .It Cm wait Instruct .Nm to only boot upon the initiation of a VNC connection, simplifying the installation of operating systems that require immediate keyboard input. This can be removed for post-installation use. .It Cm password= Ns Ar password This type of authentication is known to be cryptographically weak and is not intended for use on untrusted networks. Many implementations will want to use stronger security, such as running the session over an encrypted channel provided by IPsec or SSH. .El .Ss xHCI USB device backends .Bl -bullet .Sm off .It .Ar tablet .Sm on .El .Pp A USB tablet device that provides precise cursor synchronization when using VNC. .Ss NVMe device backends .Bl -bullet .Sm off .It .Ar devpath .Op Cm ,maxq= Ar # .Op Cm ,qsz= Ar # .Op Cm ,ioslots= Ar # .Op Cm ,sectsz= Ar # .Op Cm ,ser= Ar # .Op Cm ,eui64= Ar # .Op Cm ,dsm= Ar opt .Sm on .El .Pp Configuration options are defined as follows: .Bl -tag -width 10n .It Ar devpath Accepted device paths are: .Ar /dev/blockdev or .Ar /path/to/image or .Cm ram= Ns Ar size_in_MiB . .It Cm maxq Max number of queues. .It Cm qsz Max elements in each queue. .It Cm ioslots Max number of concurrent I/O requests. .It Cm sectsz Sector size (defaults to blockif sector size). .It Cm ser Serial number with maximum 20 characters. .It Cm eui64 IEEE Extended Unique Identifier (8 byte value). .It Cm dsm DataSet Management support. Supported values are: .Cm auto , enable , and .Cm disable . .El .Ss AHCI device backends .Bl -bullet .It .Sm off .Op Oo Cm hd\&: | cd\&: Oc Ar path .Op Cm ,nmrr= Ar nmrr .Op Cm ,ser= Ar # .Op Cm ,rev= Ar # .Op Cm ,model= Ar # .Sm on .El .Pp Configuration options are defined as follows: .Bl -tag -width 10n .It Cm nmrr Nominal Media Rotation Rate, known as RPM. Value 1 will indicate device as Solid State Disk. Default value is 0, not report. .It Cm ser Serial Number with maximum 20 characters. .It Cm rev Revision Number with maximum 8 characters. .It Cm model Model Number with maximum 40 characters. .El .Ss HD Audio device backends .Bl -bullet .It .Sm off .Op Cm play= Ar playback .Op Cm ,rec= Ar recording .Sm on .El .Pp Configuration options are defined as follows: .Bl -tag -width 10n .It Cm play Playback device, typically .Ar /dev/dsp0 . .It Cm rec Recording device, typically .Ar /dev/dsp0 . .El .Sh CONFIGURATION VARIABLES .Nm uses an internal tree of configuration variables to describe global and per-device settings. When .Nm starts, it parses command line options (including config files) in the order given on the command line. Each command line option sets one or more configuration variables. For example, the .Fl s option creates a new tree node for a PCI device and sets one or more variables under that node including the device model and device model-specific variables. Variables may be set multiple times during this parsing stage with the final value overriding previous values. .Pp Once all of the command line options have been processed, the configuration values are frozen. .Nm then uses the value of configuration values to initialize device models and global settings. .Pp More details on configuration variables can be found in .Xr bhyve_config 5 . .Sh CONFIGURATION FILE CREATION The .Fl k flag allows one to provide a path to a configuration file holding all settings, which otherwise would need to be defined by providing a long list of program arguments to .Nm . .Pp There is a very simple way to translate a complex set of program arguments to an equivalent configuration file in .Xr bhyve_config 5 format. .Pp Use .Fl o .Ar config.dump=1 to make .Nm dump a configuration file representing the used flags and arguments to stdout. You can pipe the output into a file to persist the generated settings. .Pp Make sure to remove the .Ar config.dump line from the resulting configuration file before using it to start .Nm . .Sh DEBUG SERVER The current debug server provides limited support for debuggers. .Ss Registers Each virtual CPU is exposed to the debugger as a thread. .Pp General purpose registers can be queried for each virtual CPU, but other registers such as floating-point and system registers cannot be queried. .Ss Memory Memory (including memory mapped I/O regions) can be read and written by the debugger. Memory operations use virtual addresses that are resolved to physical addresses via the current virtual CPU's active address translation. .Ss Control The running guest can be interrupted by the debugger at any time .Pq for example, by pressing Ctrl-C in the debugger . .Pp Single stepping is only supported on Intel CPUs supporting the MTRAP VM exit. .Pp Breakpoints are supported on Intel CPUs that support single stepping. Note that continuing from a breakpoint while interrupts are enabled in the guest may not work as expected due to timer interrupts firing while single stepping over the breakpoint. .Sh SIGNAL HANDLING .Nm deals with the following signals: .Pp .Bl -tag -width SIGTERM -compact .It SIGTERM Trigger ACPI poweroff for a VM .El .Sh EXIT STATUS Exit status indicates how the VM was terminated: .Pp .Bl -tag -width indent -compact .It 0 rebooted .It 1 powered off .It 2 halted .It 3 triple fault .It 4 exited due to an error .El .Sh EXAMPLES If not using a boot ROM, the guest operating system must have been loaded with .Xr bhyveload 8 or a similar boot loader before .Xr bhyve 4 can be run. Otherwise, the boot loader is not needed. .Pp To run a virtual machine with 1GB of memory, two virtual CPUs, a virtio block device backed by the .Pa /my/image filesystem image, and a serial port for the console: .Bd -literal -offset indent bhyve -c 2 -s 0,hostbridge -s 1,lpc -s 2,virtio-blk,/my/image \\ -l com1,stdio -H -P -m 1G vm1 .Ed .Pp To do the same on arm64: .Bd -literal -offset indent .Ed bhyve -c 2 -s 0,hostbridge -s 1,virtio-blk,/my/image -o console=stdio \\ -o bootrom=/usr/local/share/u-boot/u-boot-bhyve-arm64/u-boot.bin -m 1G vm1 .Pp Run a 24GB single-CPU virtual machine with three network ports, one of which has a MAC address specified: .Bd -literal -offset indent bhyve -s 0,hostbridge -s 1,lpc -s 2:0,virtio-net,tap0 \\ -s 2:1,virtio-net,tap1 \\ -s 2:2,virtio-net,tap2,mac=00:be:fa:76:45:00 \\ -s 3,virtio-blk,/my/image -l com1,stdio \\ -H -P -m 24G bigvm .Ed .Pp Run an 8GB quad-CPU virtual machine with 8 AHCI SATA disks, an AHCI ATAPI CD-ROM, a single virtio network port, an AMD hostbridge, and the console port connected to an .Xr nmdm 4 null-modem device. .Bd -literal -offset indent bhyve -c 4 \\ -s 0,amd_hostbridge -s 1,lpc \\ -s 1:0,ahci,hd:/images/disk.1,hd:/images/disk.2,\\ hd:/images/disk.3,hd:/images/disk.4,\\ hd:/images/disk.5,hd:/images/disk.6,\\ hd:/images/disk.7,hd:/images/disk.8,\\ cd:/images/install.iso \\ -s 3,virtio-net,tap0 \\ -l com1,/dev/nmdm0A \\ -H -P -m 8G .Ed .Pp Run a UEFI virtual machine with a display resolution of 800 by 600 pixels -that can be accessed via VNC at: 0.0.0.0:5900. +that can be accessed via VNC at: 0.0.0.0:5900 or via serial console over +TCP at: 127.0.0.1:1234 (unsafe if you expose serial console without protection). .Bd -literal -offset indent bhyve -c 2 -m 4G -w -H \\ -s 0,hostbridge \\ -s 3,ahci-cd,/path/to/uefi-OS-install.iso \\ -s 4,ahci-hd,disk.img \\ -s 5,virtio-net,tap0 \\ -s 29,fbuf,tcp=0.0.0.0:5900,w=800,h=600,wait \\ -s 30,xhci,tablet \\ - -s 31,lpc -l com1,stdio \\ + -s 31,lpc -l com1,tcp=127.0.0.1:1234 \\ -l bootrom,/usr/local/share/uefi-firmware/BHYVE_UEFI.fd \\ uefivm .Ed .Pp Run a UEFI virtual machine with a VNC display that is bound to all IPv6 -addresses on port 5900. +addresses on port 5900 and a serial I/O port bound to TCP port 1234 of +loopback address (unsafe if you expose serial console without protection). .Bd -literal -offset indent bhyve -c 2 -m 4G -w -H \\ -s 0,hostbridge \\ -s 4,ahci-hd,disk.img \\ -s 5,virtio-net,tap0 \\ -s 29,fbuf,tcp=[::]:5900,w=800,h=600 \\ -s 30,xhci,tablet \\ - -s 31,lpc -l com1,stdio \\ + -s 31,lpc -l com1,tcp=[::1]:1234 \\ -l bootrom,/usr/local/share/uefi-firmware/BHYVE_UEFI.fd \\ uefivm .Ed .Pp Run a UEFI virtual machine with a VARS file to save EFI variables. Note that .Nm will write guest modifications to the given VARS file. Be sure to create a per-guest copy of the template VARS file from .Pa /usr . .Bd -literal -offset indent bhyve -c 2 -m 4g -w -H \\ -s 0,hostbridge \\ -s 31,lpc -l com1,stdio \\ -l bootrom,/usr/local/share/uefi-firmware/BHYVE_UEFI_CODE.fd,BHYVE_UEFI_VARS.fd uefivm .Ed .Pp To create a configuration file .Pa configfile for a virtual machine, use .Fl o .Ar config.dump=1 : .Bd -literal -offset indent /usr/sbin/bhyve -c 2 -m 256 -H -P \\ -s 0:0,hostbridge -s 1:0,virtio-net,tap0 \\ -s 2:0,ahci-hd,./vm0.img \\ -s 31,lpc -l com1,stdio \\ -o config.dump=1 vm0 > configfile .Ed .Pp Then use an editor of your choice to remove the line "config.dump=1" from the newly generated .Pa configfile . .Pp To start .Nm using this configuration file, use flag .Fl k : .Bd -literal -offset indent /usr/sbin/bhyve -k configfile vm0 .Ed .Sh SEE ALSO .Xr bhyve 4 , .Xr netgraph 4 , .Xr ng_socket 4 , .Xr nmdm 4 , .Xr vmm 4 , .Xr bhyve_config 5 , .Xr ethers 5 , .Xr bhyvectl 8 , .Xr bhyveload 8 .Pp .Rs .%A Intel .%B 64 and IA-32 Architectures Software Developer’s Manual .%V Volume 3 .Re .Sh HISTORY .Nm first appeared in .Fx 10.0 . .Sh AUTHORS .An Neel Natu Aq Mt neel@freebsd.org .An Peter Grehan Aq Mt grehan@freebsd.org diff --git a/usr.sbin/bhyve/bhyve_config.5 b/usr.sbin/bhyve/bhyve_config.5 index 25185e2ef1b4..7b99737c3baa 100644 --- a/usr.sbin/bhyve/bhyve_config.5 +++ b/usr.sbin/bhyve/bhyve_config.5 @@ -1,740 +1,746 @@ .\" SPDX-License-Identifier: BSD-2-Clause .\" .\" Copyright (c) 2021 John H. Baldwin .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd August 13, 2024 +.Dd August 21, 2024 .Dt BHYVE_CONFIG 5 .Os .Sh NAME .Nm bhyve_config .Nd "bhyve configuration variables" .Sh DESCRIPTION .Xr bhyve 8 uses a hierarchical tree of configuration variables to describe global and per-device settings. Internal nodes in this tree do not have a value, only leaf nodes have values. This manual describes the configuration variables understood by .Xr bhyve 8 . If additional variables are defined, .Xr bhyve 8 will ignore them and will not emit errors for unknown variables. However, these additional variables can be referenced by other variables as described below. .Sh VARIABLE VALUES Configuration variable values are stored as strings. A configuration variable value may refer to one or more other configuration values by name. Instances of the pattern .Sq % Ns Pq Ar var are replaced by the value of the configuration variable .Va var . To avoid unwanted expansion, .Sq % characters can be escaped by a leading .Sq % . For example, if a configuration variable .Va disk uses the value .Pa /dev/zvol/bhyve/%(name) , then the final value of the .Va disk variable will be set to the path of a ZFS volume whose name matches the name of the virtual machine on the pool .Pa bhyve . .Pp Some configuration variables may be interpreted as a boolean value. For those variables the following case-insensitive values may be used to indicate true: .Pp .Bl -bullet -offset indent -compact .It true .It on .It yes .It 1 .El .Pp The following values may be used to indicate false: .Pp .Bl -bullet -offset indent -compact .It false .It off .It no .It 0 .El .Pp Some configuration variables may be interperted as an integer. For those variables, any syntax supported by .Xr strtol 3 may be used. .Sh GLOBAL SETTINGS .Ss Architecture Neutral Settings .Bl -column "memory.guest_in_core" "integer" "Default" .It Sy Name Ta Sy Format Ta Sy Default Ta Sy Description .It Va name Ta string Ta Ta The name of the VM. .It Va cpus Ta integer Ta 1 Ta The total number of virtual CPUs. .It Va cores Ta integer Ta 1 Ta The number of virtual cores in each virtual socket. .It Va threads Ta integer Ta 1 Ta The number of virtual CPUs in each virtual core. .It Va sockets Ta integer Ta 1 Ta The number of virtual sockets. .It Va memory.guest_in_core Ta bool Ta false Ta Include guest memory in core file. .It Va memory.size Ta string Ta 256M Ta Guest physical memory size in bytes. The value must be formatted as described in .Xr expand_number 3 . .It Va memory.wired Ta bool Ta false Ta Wire guest memory. .It Va bootrom Ta path Ta Ta Path to a boot ROM. During initialization of the guest, the contents of this file are copied into the guest's memory. If a boot ROM is present, a firmware interface device is also enabled for use by the boot ROM. .It Va bootvars Ta path Ta Ta Path to boot VARS. The contents of this file are copied beneath the boot ROM. Firmware can write to it to save variables. All variables will be persistent even on reboots of the guest. .It Va acpi_tables Ta bool Ta true Ta Generate ACPI tables. .It Va acpi_tables_in_memory Ta bool Ta true Ta .Xr bhyve 8 always exposes ACPI tables by FwCfg. For backward compatibility bhyve copies them into the guest memory as well. This can cause problems if the guest uses the in-memory version, since certain advanced features, such as TPM emulation, are exposed only via FwCfg. Therefore, it is recommended to set this flag to false when running Windows guests. .It Va destroy_on_poweroff Ta bool Ta false Ta Destroy the VM on guest-initiated power-off. .It Va gdb.address Ta string Ta localhost Ta Hostname, IP address, or IPv6 address for the debug server. .It Va gdb.port Ta integer Ta 0 Ta TCP port number for the debug server. If this is set to a non-zero value, a debug server will listen for connections on this port. .It Va gdb.wait Ta bool Ta false Ta If the debug server is enabled, wait for a debugger to connect before starting the guest. .It Va keyboard.layout Ta string Ta Ta Specify the keyboard layout name with the file name in .Ar /usr/share/bhyve/kbdlayout . This value only works when loaded with UEFI mode for VNC, and used a VNC client that don't support QEMU Extended Key Event Message (e.g. TightVNC). .It Va pci.enable_bars Ta bool Ta Ta Enable and map PCI BARs before executing any guest code. This setting is false by default when using a boot ROM and true otherwise. .It Va tpm.path Ta string Ta Ta Path to the host TPM device. This is typically /dev/tpm0. .It Va tpm.type Ta string Ta Ta Type of the TPM device passed to the guest. Currently, only "passthru" is supported. .It Va tpm.version Ta string Ta 2.0 Ta Version of the TPM device according to the TCG specification. Currently, only version 2.0 is supported. .It Va rtc.use_localtime Ta bool Ta true Ta The real time clock uses the local time of the host. If this is set to false, the real time clock uses UTC. .It Va uuid Ta string Ta Ta The universally unique identifier (UUID) to use in the guest's System Management BIOS System Information structure. If an explicit value is not set, a valid UUID is generated from the host's hostname and the VM name. .It Va virtio_msix Ta bool Ta true Ta Use MSI-X interrupts for PCI VirtIO devices. If set to false, MSI interrupts are used instead. .It Va config.dump Ta bool Ta false Ta If this value is set to true after .Xr bhyve 8 has finished parsing command line options, then .Xr bhyve 8 will write all of its configuration variables to stdout and exit. No VM will be started. .It Va bios.vendor Ta string Ta BHYVE Ta This value is used for the guest's System Management BIOS System Information structure. .It Va bios.version Ta string Ta 14.0 Ta This value is used for the guest's System Management BIOS System Information structure. .It Va bios.release_date Ta string Ta 10/17/2021 Ta This value is used for the guest's System Management BIOS System Information structure. .It Va system.family_name Ta string Ta Virtual Machine Ta Family the computer belongs to. This value is used for the guest's System Management BIOS System Information structure. .It Va system.manufacturer Ta string Ta FreeBSD Ta This value is used for the guest's System Management BIOS System Information structure. .It Va system.product_name Ta string Ta BHYVE Ta This value is used for the guest's System Management BIOS System Information structure. .It Va system.serial_number Ta string Ta None Ta This value is used for the guest's System Management BIOS System Information structure. .It Va system.sku Ta string Ta None Ta Stock keeping unit of the computer. It's also called product ID or purchase order number. This value is used for the guest's System Management BIOS System Information structure. .It Va system.version Ta string Ta 1.0 Ta This value is used for the guest's System Management BIOS System Information structure. .It Va board.manufacturer Ta string Ta FreeBSD Ta This value is used for the guest's System Management BIOS System Information structure. .It Va board.product_name Ta string Ta BHYVE Ta This value is used for the guest's System Management BIOS System Information structure. .It Va board.version Ta string Ta 1.0 Ta This value is used for the guest's System Management BIOS System Information structure. .It Va board.serial_number Ta string Ta None Ta This value is used for the guest's System Management BIOS System Information structure. .It Va board.asset_tag Ta string Ta None Ta This value is used for the guest's System Management BIOS System Information structure. .It Va board.location Ta string Ta None Ta Describes the board's location within the chassis. This value is used for the guest's System Management BIOS System Information structure. .It Va chassis.manufacturer Ta string Ta FreeBSD Ta This value is used for the guest's System Management BIOS System Information structure. .It Va chassis.version Ta string Ta 1.0 Ta This value is used for the guest's System Management BIOS System Information structure. .It Va chassis.serial_number Ta string Ta None Ta This value is used for the guest's System Management BIOS System Information structure. .It Va chassis.asset_tag Ta string Ta None Ta This value is used for the guest's System Management BIOS System Information structure. .It Va chassis.sku Ta string Ta None Ta Stock keeping unit of the chassis. It's also called product ID or purchase order number. This value is used for the guest's System Management BIOS System Information structure. .El .Ss x86-Specific Settings .Bl -column "x86.vmexit_on_pause" "integer" "Default" .It Sy Name Ta Sy Format Ta Sy Default Ta Sy Description .It Va x86.mptable Ta bool Ta true Ta Generate an MPTable. .It Va x86.x2apic Ta bool Ta false Ta Configure guest's local APICs in x2APIC mode. .It Va x86.strictio Ta bool Ta false Ta Exit if a guest accesses an I/O port that is not emulated. By default, writes are ignored and reads return all bits set. .It Va x86.strictmsr Ta bool Ta true Ta Inject a general protection fault if a guest accesses a Model Specific Register (MSR) that is not emulated. If this is false, writes are ignored and reads return zero. .It Va x86.vmexit_on_hlt Ta bool Ta false Ta Force a VM exit when a guest CPU executes the .Dv HLT instruction. This allows idle guest CPUs to yield the host CPU. .It Va x86.vmexit_on_pause Ta bool Ta false Ta Force a VM exit when a guest CPU executes the .Dv PAUSE instruction. .El .Sh DEVICE SETTINGS Device settings are stored under a device node. The device node's name is set by the parent bus of the device. .Ss PCI Device Settings PCI devices are described by a device node named .Dq pci . Ns Ar bus . Ns Ar slot . Ns Ar function where each of .Ar bus , .Ar slot , and .Ar function are formatted as decimal values with no padding. All PCI device nodes must contain a configuration variable named .Dq device which specifies the device model to use. The following PCI device models are supported: .Bl -tag -indent .It Li hostbridge Provide a simple PCI-Host bridge device. This is usually configured at pci0:0:0 and is required by most guest operating systems. .It Li ahci AHCI storage controller. .It Li e1000 Intel e82545 network interface. .It Li fbuf VGA framebuffer device attached to VNC server. .It Li lpc LPC PCI-ISA bridge with COM1-COM4 16550 serial ports, a boot ROM, an optional fwcfg type, and an optional debug/test device. This device must be configured on bus 0. .It Li hda High Definition audio controller. .It Li nvme NVM Express (NVMe) controller. .It Li passthru PCI pass-through device. .It Li uart PCI 16550 serial device. .It Li virtio-9p VirtIO 9p (VirtFS) interface. .It Li virtio-blk VirtIO block storage interface. .It Li virtio-console VirtIO console interface. .It Li virtio-input VirtIO input interface. .It Li virtio-net VirtIO network interface. .It Li virtio-rnd VirtIO RNG interface. .It Li virtio-scsi VirtIO SCSI interface. .It Li xhci Extensible Host Controller Interface (XHCI) USB controller. .El .Ss USB Device Settings USB controller devices contain zero or more child USB devices attached to slots. Each USB device stores its settings in a node named .Dq slot. Ns Va N under the controller's device node. .Va N is the number of the slot to which the USB device is attached. Note that USB slot numbers begin at 1. All USB device nodes must contain a configuration variable named .Dq device which specifies the device model to use. The following USB device models are supported: .Bl -tag -indent .It Li tablet A USB tablet device which provides precise cursor synchronization when using VNC. .El .Ss Block Device Settings Block devices use the following settings to configure their backing store. These settings are stored in the configuration node of the respective device. .Bl -column "sectorsize" "logical[/physical]" "Default" .It Sy Name Ta Sy Format Ta Sy Default Ta Sy Description .It path Ta string Ta Ta The path of the file or disk device to use as the backing store. .It nocache Ta bool Ta false Ta Disable caching on the backing file by opening the backing file with .Dv O_DIRECT . .It nodelete Ta bool Ta false Ta Disable emulation of guest trim requests via .Dv DIOCGDELETE requests. .It sync Ta bool Ta false Ta Write changes to the backing file with synchronous writes. .It direct Ta bool Ta false Ta An alias for .Va sync . .It ro Ta bool Ta false Ta Disable writes to the backing file. .It sectorsize Ta Va logical Ns Op / Ns Va physical Ta Ta Specify the logical and physical sector size of the emulated disk. If the physical size is not specified, it is equal to the logical size. .El .Ss Network Backend Settings Network devices use the following settings to configure their backend. The backend is responsible for passing packets between the device model and a desired destination. Configuring a backend requires setting the .Va backend variable. The type of a backend can either be set explicitly via the .Va type variable or it can be inferred from the value of .Va backend . .Pp The following types of backends are supported: .Bl -tag -width "netgraph" .It tap Use the .Xr tap 4 interface named in .Va backend as the backend. .It netgraph Use a .Xr netgraph 4 socket hook as the backend. This backend uses the following additional variables: .Bl -column "peerhook" "Format" "Default" .It Sy Name Ta Sy Format Ta Sy Default Ta Sy Description .It Va path Ta string Ta Ta The name of the .Xr netgraph 4 destination node. .It Va peerhook Ta string Ta Ta The name of the destination hook. .It Va socket Ta string Ta Ta The name of the created .Xr ng_socket 4 node. .It Va hook Ta string Ta vmlink Ta The name of the source hook on the created .Xr ng_socket 4 node. .El .It netmap Use .Xr netmap 4 either on a network interface or a port on a .Xr vale 4 bridge as the backend. The value of .Va backend is passed to .Xr nm_open to connect to a netmap port. .It slirp Use the slirp backend to provide a userspace network stack. The .Va hostfwd variable is used to configure how packets from the host are translated before being sent to the guest. .Bl -column "peerhook" "Format" "Default" .It Sy Name Ta Sy Format Ta Sy Default Ta Sy Description .It Va hostfwd Ta string Ta Ta A semicolon-separated list of host forwarding rules, each of the form .Ar proto:haddr:hport-gaddr:gport , where .Ar proto is either .Ql tcp or .Ql udp . If the guest address is equal to the empty string, packets will be forwarded to the first DHCP-assigned address in the guest. .El .El .Pp If .Va type is not specified explicitly, then it is inferred from .Va backend based on the following patterns: .Bl -column -offset indent "valuebridge:port" .It Sy Pattern Ta Sy Type .It tap Ns Va N Ta tap .It vmnet Ns Va N Ta tap .It netgraph Ta netgraph .It netmap: Ns Va interface Ta netmap .It vale Ns Va bridge : Ns Va port Ta netmap .El .Ss UART Device Settings .Bl -column "Name" "Format" "Default" .It Sy Name Ta Sy Format Ta Sy Default Ta Sy Description .It Va path Ta path Ta Ta Backend device for the serial port. Either the pathname of a character device or .Dq stdio to use standard input and output of the .Xr bhyve 8 process. +.It Va tcp Ta Oo Ar IP Ns : Oc Ns Ar port Ta Ta +TCP address to listen on for remote connections. +The IP address must be given as a numeric address. +IPv6 addresses must be enclosed in square brackets and +supports scoped identifiers as described in +.Xr getaddrinfo 3 . .El .Ss Host Bridge Settings .Bl -column "pcireg.*" "integer" "Default" .It Sy Name Ta Sy Format Ta Sy Default Ta Sy Description .It Va pcireg.* Ta integer Ta Ta Values of PCI register. .Bl -column "device" "Default" .It Sy Name Ta Sy Default .It Va vendor Ta integer Ta 0x1275 Ta .It Va device Ta integer Ta 0x1275 Ta .El .El .Ss AHCI Controller Settings AHCI controller devices contain zero or more ports each of which provides a storage device. Each port stores its settings in a node named .Dq port. Ns Va N under the controller's device node. The .Va N values are formatted as successive decimal values starting with 0. In addition to the block device settings described above, each port supports the following settings: .Bl -column "model" "integer" "generated" .It Sy Name Ta Sy Format Ta Sy Default Ta Sy Description .It Va type Ta string Ta Ta The type of storage device to emulate. Must be set to either .Dq cd or .Dq hd . .It Va nmrr Ta integer Ta 0 Ta Nominal Media Rotation Rate, also known as RPM. A value 1 of indicates a device with no rate such as a Solid State Disk. .It Va ser Ta string Ta generated Ta Serial number of up to twenty characters. A default serial number is generated using a hash of the backing store's pathname. .It Va rev Ta string Ta 001 Ta Revision number of up to eight characters. .It Va model Ta string Ta Ta Model number of up to forty characters. Separate default model strings are used for .Dq cd and .Dq hd device types. .El .Ss e1000 Settings In addition to the network backend settings, Intel e82545 network interfaces support the following variables: .Bl -column "Name" "MAC address" "generated" .It Sy Name Ta Sy Format Ta Sy Default Ta Sy Description .It Va mac Ta MAC address Ta generated Ta MAC address. If an explicit address is not provided, a MAC address is generated from a hash of the device's PCI address. .El .Ss Frame Buffer Settings .Bl -column "password" "[IP:]port" "127.0.0.1:5900" .It Sy Name Ta Sy Format Ta Sy Default Ta Sy Description .It Va wait Ta bool Ta false Ta Wait for a remote connection before starting the VM. .It Va rfb Ta Oo Ar IP Ns : Oc Ns Ar port Ta 127.0.0.1:5900 Ta TCP address to listen on for remote connections. The IP address must be given as a numeric address. IPv6 addresses must be enclosed in square brackets and support scoped identifiers as described in .Xr getaddrinfo 3 . A bare port number may be given in which case the IPv4 localhost address is used. .It Va vga Ta string Ta io Ta VGA configuration. More details are provided in .Xr bhyve 8 . .It Va w Ta integer Ta 1024 Ta Frame buffer width in pixels. .It Va h Ta integer Ta 768 Ta Frame buffer height in pixels. .It Va password Ta string Ta Ta Password to use for VNC authentication. This type of authentication is known to be cryptographically weak and is not intended for use on untrusted networks. .El .Ss High Definition Audio Settings .Bl -column "Name" "Format" "Default" .It Sy Name Ta Sy Format Ta Sy Default Ta Sy Description .It Va play Ta path Ta Ta Host playback device, typically .Pa /dev/dsp0 . .It Va rec Ta path Ta Ta Host recording device, typically .Pa /dev/dsp0 . .El .Ss LPC Device Settings The LPC bridge stores its configuration under a top-level .Va lpc node rather than under the PCI LPC device's node. The following nodes are available under .Va lpc : .Bl -column "pc-testdev" "Format" "Default" .It Sy Name Ta Sy Format Ta Sy Default Ta Sy Description .It Va com1 Ta node Ta Ta Settings for the COM1 serial port device. .It Va com2 Ta node Ta Ta Settings for the COM2 serial port device. .It Va com3 Ta node Ta Ta Settings for the COM3 serial port device. .It Va com4 Ta node Ta Ta Settings for the COM4 serial port device. .It Va fwcfg Ta string Ta bhyve Ta The fwcfg type to be used. Supported values are .Dq bhyve for fwctl and .Dq qemu for fwcfg. .It Va pc-testdev Ta bool Ta false Ta Enable the PC debug/test device. .It Va pcireg.* Ta integer Ta Ta Values of PCI register. It also accepts the value .Ar host to use the pci id of the host system. This value is required for the Intel GOP driver to work properly. .Bl -column "subvendor" "Default" .It Sy Name Ta Sy Default .It Va vendor Ta 0x8086 .It Va device Ta 0x7000 .It Va revid Ta 0 .It Va subvendor Ta 0 .It Va subdevice Ta 0 .El .El .Ss NVMe Controller Settings Each NVMe controller supports a single storage device. The device can be backed either by a memory disk described by the .Va ram variable, or a block device using the block device settings described above. In addition, each controller supports the following settings: .Bl -column "ioslots" "Format" "Default" .It Sy Name Ta Sy Format Ta Sy Default Ta Sy Description .It Va maxq Ta integer Ta 16 Ta Maximum number of I/O submission and completion queue pairs. .It Va qsz Ta integer Ta 2058 Ta Number of elements in each I/O queue. .It Va ioslots Ta integer Ta 8 Ta Maximum number of concurrent I/O requests. .It Va sectsz Ta integer Ta Ta Sector size. Can be one of 512, 4096, or 8192. Devices backed by a memory disk use 4096 as the default. Devices backed by a block device use the block device's sector size as the default. .It Va ser Ta string Ta Ta Serial number of up to twenty characters. A default serial number is generated using a hash of the device's PCI address. .It Va eui64 Ta integer Ta Ta IEEE Extended Unique Identifier. If an EUI is not provided, a default is generated using a checksum of the device's PCI address. .It Va dsm Ta string Ta auto Ta Whether or not to advertise DataSet Management support. One of .Dq auto , .Dq enable , or .Dq disable . The .Dq auto setting only advertises support if the backing store supports resource freeing, for example via TRIM. .It Va ram Ta integer Ta Ta If set, allocate a memory disk as the backing store. The value of this variable is the size of the memory disk in megabytes. .El .Ss PCI Passthrough Settings The .Xr ppt 4 device driver must be attached to the PCI device being passed through. The device to pass through can be identified either by name or its host PCI bus location. .Bl -column "Name" "integer" "Default" .It Sy Name Ta Sy Format Ta Sy Default Ta Sy Description .It Va bus Ta integer Ta Ta Host PCI bus address of device to pass through. .It Va slot Ta integer Ta Ta Host PCI slot address of device to pass through. .It Va func Ta integer Ta Ta Host PCI function address of device to pass through. .It Va pptdev Ta string Ta Ta Name of a .Xr ppt 4 device to pass through. .It Va rom Ta path Ta Ta ROM file of the device which will be executed by OVMF to init the device. .El .Ss VirtIO 9p Settings Each VirtIO 9p device exposes a single filesystem from a host path. .Bl -column "sharename" "Format" "Default" .It Sy Name Ta Sy Format Ta Sy Default Ta Sy Description .It Va sharename Ta string Ta Ta The share name exposed to the guest. .It Va path Ta path Ta Ta The path of a directory on the host to export to the guest. .It Va ro Ta bool Ta false Ta If true, the guest filesystem is read-only. .El .Ss VirtIO Block Device Settings In addition to the block device settings described above, each VirtIO block device supports the following settings: .Bl -column "model" "integer" "generated" .It Sy Name Ta Sy Format Ta Sy Default Ta Sy Description .It Va ser Ta string Ta generated Ta Serial number of up to twenty characters. A default serial number is generated using a hash of the backing store's pathname. .El .Ss VirtIO Console Device Settings Each VirtIO Console device contains one or more console ports. Each port stores its settings in a node named .Dq port. Ns Va N under the controller's device node. The .Va N values are formatted as successive decimal values starting with 0. Each port supports the following settings: .Bl -column "Name" "Format" "Default" .It Sy Name Ta Sy Format Ta Sy Default Ta Sy Description .It Va name Ta string Ta Ta The name of the port exposed to the guest. .It Va path Ta path Ta Ta The path of a UNIX domain socket providing the host connection for the port. .El .Ss VirtIO Input Interface Settings Each VirtIO Input device contains one input event device. All input events of the input event device are send to the guest by VirtIO Input interface. VirtIO Input Interfaces support the following variables: .Bl -column "Name" "Format" "Default" .It Sy Name Ta Sy Format Ta Sy Default Ta Sy Description .It Va path Ta path Ta Ta The path of the input event device exposed to the guest .El .Ss VirtIO Network Interface Settings In addition to the network backend settings, VirtIO network interfaces support the following variables: .Bl -column "Name" "MAC address" "generated" .It Sy Name Ta Sy Format Ta Sy Default Ta Sy Description .It Va mac Ta MAC address Ta generated Ta MAC address. If an explicit address is not provided, a MAC address is generated from a hash of the device's PCI address. .It Va mtu Ta integer Ta 1500 Ta The largest supported MTU advertised to the guest. .El .Ss VirtIO SCSI Settings .Bl -column "Name" "integer" "Default" .It Sy Name Ta Sy Format Ta Sy Default Ta Sy Description .It Va dev Ta path Ta Ta The path of a CAM target layer (CTL) device to export: .Pa /dev/cam/ctl Ns Oo Ar pp . Ns Ar vp Oc . .It Va iid Ta integer Ta 0 Ta Initiator ID to use when sending requests to the CTL port. .El .Sh SEE ALSO .Xr expand_number 3 , .Xr getaddrinfo 3 , .Xr strtol 3 , .Xr netgraph 4 , .Xr netmap 4 , .Xr ng_socket 4 , .Xr tap 4 , .Xr vale 4 , .Xr vmnet 4 , .Xr bhyve 8 diff --git a/usr.sbin/bhyve/uart_backend.c b/usr.sbin/bhyve/uart_backend.c index 51844cbf1170..a09764190137 100644 --- a/usr.sbin/bhyve/uart_backend.c +++ b/usr.sbin/bhyve/uart_backend.c @@ -1,368 +1,561 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2012 NetApp, Inc. * Copyright (c) 2013 Neel Natu * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include +#include #include #include +#include + +#include #include #include #include +#include #include #include #include #include #include #include #include #include "debug.h" #include "mevent.h" #include "uart_backend.h" struct ttyfd { bool opened; + bool is_socket; int rfd; /* fd for reading */ int wfd; /* fd for writing, may be == rfd */ }; #define FIFOSZ 16 struct fifo { uint8_t buf[FIFOSZ]; int rindex; /* index to read from */ int windex; /* index to write to */ int num; /* number of characters in the fifo */ int size; /* size of the fifo */ }; struct uart_softc { struct ttyfd tty; struct fifo rxfifo; struct mevent *mev; pthread_mutex_t mtx; }; +struct uart_socket_softc { + struct uart_softc *softc; + void (*drain)(int, enum ev_type, void *); + void *arg; +}; + static bool uart_stdio; /* stdio in use for i/o */ static struct termios tio_stdio_orig; +static void uart_tcp_disconnect(struct uart_softc *); + static void ttyclose(void) { tcsetattr(STDIN_FILENO, TCSANOW, &tio_stdio_orig); } static void ttyopen(struct ttyfd *tf) { struct termios orig, new; tcgetattr(tf->rfd, &orig); new = orig; cfmakeraw(&new); new.c_cflag |= CLOCAL; tcsetattr(tf->rfd, TCSANOW, &new); if (uart_stdio) { tio_stdio_orig = orig; atexit(ttyclose); } raw_stdio = 1; } static int -ttyread(struct ttyfd *tf) +ttyread(struct ttyfd *tf, uint8_t *ret) { - unsigned char rb; + uint8_t rb; + int len; - if (read(tf->rfd, &rb, 1) == 1) - return (rb); - else - return (-1); + len = read(tf->rfd, &rb, 1); + if (ret && len == 1) + *ret = rb; + + return (len); } -static void +static int ttywrite(struct ttyfd *tf, unsigned char wb) { - (void)write(tf->wfd, &wb, 1); + return (write(tf->wfd, &wb, 1)); } static bool rxfifo_available(struct uart_softc *sc) { return (sc->rxfifo.num < sc->rxfifo.size); } int uart_rxfifo_getchar(struct uart_softc *sc) { struct fifo *fifo; int c, error, wasfull; wasfull = 0; fifo = &sc->rxfifo; if (fifo->num > 0) { if (!rxfifo_available(sc)) wasfull = 1; c = fifo->buf[fifo->rindex]; fifo->rindex = (fifo->rindex + 1) % fifo->size; fifo->num--; if (wasfull) { if (sc->tty.opened) { error = mevent_enable(sc->mev); assert(error == 0); } } return (c); } else return (-1); } int uart_rxfifo_numchars(struct uart_softc *sc) { return (sc->rxfifo.num); } static int rxfifo_putchar(struct uart_softc *sc, uint8_t ch) { struct fifo *fifo; int error; fifo = &sc->rxfifo; if (fifo->num < fifo->size) { fifo->buf[fifo->windex] = ch; fifo->windex = (fifo->windex + 1) % fifo->size; fifo->num++; if (!rxfifo_available(sc)) { if (sc->tty.opened) { /* * Disable mevent callback if the FIFO is full. */ error = mevent_disable(sc->mev); assert(error == 0); } } return (0); } else return (-1); } void uart_rxfifo_drain(struct uart_softc *sc, bool loopback) { - int ch; + uint8_t ch; + int len; if (loopback) { - (void)ttyread(&sc->tty); + if (ttyread(&sc->tty, &ch) == 0 && sc->tty.is_socket) + uart_tcp_disconnect(sc); } else { - while (rxfifo_available(sc) && - ((ch = ttyread(&sc->tty)) != -1)) + while (rxfifo_available(sc)) { + len = ttyread(&sc->tty, &ch); + if (len <= 0) { + /* read returning 0 means disconnected. */ + if (len == 0 && sc->tty.is_socket) + uart_tcp_disconnect(sc); + break; + } + rxfifo_putchar(sc, ch); + } } } int uart_rxfifo_putchar(struct uart_softc *sc, uint8_t ch, bool loopback) { if (loopback) { return (rxfifo_putchar(sc, ch)); } else if (sc->tty.opened) { - ttywrite(&sc->tty, ch); + /* write returning -1 means disconnected. */ + if (ttywrite(&sc->tty, ch) == -1 && sc->tty.is_socket) + uart_tcp_disconnect(sc); return (0); } else { /* Drop on the floor. */ return (0); } } void uart_rxfifo_reset(struct uart_softc *sc, int size) { char flushbuf[32]; struct fifo *fifo; ssize_t nread; int error; fifo = &sc->rxfifo; bzero(fifo, sizeof(struct fifo)); fifo->size = size; if (sc->tty.opened) { /* * Flush any unread input from the tty buffer. */ while (1) { nread = read(sc->tty.rfd, flushbuf, sizeof(flushbuf)); if (nread != sizeof(flushbuf)) break; } /* * Enable mevent to trigger when new characters are available * on the tty fd. */ error = mevent_enable(sc->mev); assert(error == 0); } } int uart_rxfifo_size(struct uart_softc *sc __unused) { return (FIFOSZ); } #ifdef BHYVE_SNAPSHOT int uart_rxfifo_snapshot(struct uart_softc *sc, struct vm_snapshot_meta *meta) { int ret; SNAPSHOT_VAR_OR_LEAVE(sc->rxfifo.rindex, meta, ret, done); SNAPSHOT_VAR_OR_LEAVE(sc->rxfifo.windex, meta, ret, done); SNAPSHOT_VAR_OR_LEAVE(sc->rxfifo.num, meta, ret, done); SNAPSHOT_VAR_OR_LEAVE(sc->rxfifo.size, meta, ret, done); SNAPSHOT_BUF_OR_LEAVE(sc->rxfifo.buf, sizeof(sc->rxfifo.buf), meta, ret, done); done: return (ret); } #endif +/* + * Listen on the TCP port, wait for a connection, then accept it. + */ +static void +uart_tcp_listener(int fd, enum ev_type type __unused, void *arg) +{ + const static char tcp_error_msg[] = "Socket already connected\n"; + struct uart_socket_softc *socket_softc = (struct uart_socket_softc *) + arg; + struct uart_softc *sc = socket_softc->softc; + int conn_fd; + + conn_fd = accept(fd, NULL, NULL); + if (conn_fd == -1) + goto clean; + + if (fcntl(conn_fd, F_SETFL, O_NONBLOCK) != 0) + goto clean; + + pthread_mutex_lock(&sc->mtx); + + if (sc->tty.opened) { + (void)send(conn_fd, tcp_error_msg, sizeof(tcp_error_msg), 0); + pthread_mutex_unlock(&sc->mtx); + goto clean; + } else { + sc->tty.rfd = sc->tty.wfd = conn_fd; + sc->tty.opened = true; + sc->mev = mevent_add(sc->tty.rfd, EVF_READ, socket_softc->drain, + socket_softc->arg); + } + + pthread_mutex_unlock(&sc->mtx); + return; + +clean: + if (conn_fd != -1) + close(conn_fd); +} + +/* + * When a connection-oriented protocol disconnects, this handler is used to + * clean it up. + * + * Note that this function is a helper, so the caller is responsible for + * locking the softc. + */ +static void +uart_tcp_disconnect(struct uart_softc *sc) +{ + mevent_delete_close(sc->mev); + sc->mev = NULL; + sc->tty.opened = false; + sc->tty.rfd = sc->tty.wfd = -1; +} + static int uart_stdio_backend(struct uart_softc *sc) { #ifndef WITHOUT_CAPSICUM cap_rights_t rights; cap_ioctl_t cmds[] = { TIOCGETA, TIOCSETA, TIOCGWINSZ }; #endif if (uart_stdio) return (-1); sc->tty.rfd = STDIN_FILENO; sc->tty.wfd = STDOUT_FILENO; sc->tty.opened = true; if (fcntl(sc->tty.rfd, F_SETFL, O_NONBLOCK) != 0) return (-1); if (fcntl(sc->tty.wfd, F_SETFL, O_NONBLOCK) != 0) return (-1); #ifndef WITHOUT_CAPSICUM cap_rights_init(&rights, CAP_EVENT, CAP_IOCTL, CAP_READ); if (caph_rights_limit(sc->tty.rfd, &rights) == -1) errx(EX_OSERR, "Unable to apply rights for sandbox"); if (caph_ioctls_limit(sc->tty.rfd, cmds, nitems(cmds)) == -1) errx(EX_OSERR, "Unable to apply rights for sandbox"); #endif uart_stdio = true; return (0); } static int uart_tty_backend(struct uart_softc *sc, const char *path) { #ifndef WITHOUT_CAPSICUM cap_rights_t rights; cap_ioctl_t cmds[] = { TIOCGETA, TIOCSETA, TIOCGWINSZ }; #endif int fd; fd = open(path, O_RDWR | O_NONBLOCK); if (fd < 0) return (-1); if (!isatty(fd)) { close(fd); return (-1); } sc->tty.rfd = sc->tty.wfd = fd; sc->tty.opened = true; #ifndef WITHOUT_CAPSICUM cap_rights_init(&rights, CAP_EVENT, CAP_IOCTL, CAP_READ, CAP_WRITE); if (caph_rights_limit(fd, &rights) == -1) errx(EX_OSERR, "Unable to apply rights for sandbox"); if (caph_ioctls_limit(fd, cmds, nitems(cmds)) == -1) errx(EX_OSERR, "Unable to apply rights for sandbox"); #endif return (0); } +/* + * Listen on the address and add it to the kqueue. + * + * If a connection is established (e.g., the TCP handler is triggered), + * replace the handler with the connected handler. + */ +static int +uart_tcp_backend(struct uart_softc *sc, const char *path, + void (*drain)(int, enum ev_type, void *), void *arg) +{ +#ifndef WITHOUT_CAPSICUM + cap_rights_t rights; + cap_ioctl_t cmds[] = { TIOCGETA, TIOCSETA, TIOCGWINSZ }; +#endif + int bind_fd = -1; + char addr[256], port[6]; + int domain; + struct addrinfo hints, *src_addr = NULL; + struct uart_socket_softc *socket_softc = NULL; + + if (sscanf(path, "tcp=[%255[^]]]:%5s", addr, port) == 2) { + domain = AF_INET6; + } else if (sscanf(path, "tcp=%255[^:]:%5s", addr, port) == 2) { + domain = AF_INET; + } else { + warnx("Invalid number of parameter"); + goto clean; + } + + bind_fd = socket(domain, SOCK_STREAM, 0); + if (bind_fd < 0) + goto clean; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = domain; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV | AI_PASSIVE; + + if (getaddrinfo(addr, port, &hints, &src_addr) != 0) { + warnx("Invalid address %s:%s", addr, port); + goto clean; + } + + if (bind(bind_fd, src_addr->ai_addr, src_addr->ai_addrlen) == -1) { + warn( + "bind(%s:%s)", + addr, port); + goto clean; + } + + freeaddrinfo(src_addr); + src_addr = NULL; + + if (fcntl(bind_fd, F_SETFL, O_NONBLOCK) == -1) + goto clean; + + if (listen(bind_fd, 1) == -1) { + warnx("listen(%s:%s)", addr, port); + goto clean; + } + + /* + * Set the connection softc structure, which includes both the softc + * and the drain function provided by the frontend. + */ + if ((socket_softc = calloc(sizeof(struct uart_socket_softc), 1)) == + NULL) + goto clean; + + sc->tty.is_socket = true; + + socket_softc->softc = sc; + socket_softc->drain = drain; + socket_softc->arg = arg; + +#ifndef WITHOUT_CAPSICUM + cap_rights_init(&rights, CAP_EVENT, CAP_ACCEPT, CAP_RECV, CAP_SEND, + CAP_FCNTL, CAP_IOCTL); + if (caph_rights_limit(bind_fd, &rights) == -1) + errx(EX_OSERR, "Unable to apply rights for sandbox"); + if (caph_ioctls_limit(bind_fd, cmds, nitems(cmds)) == -1) + errx(EX_OSERR, "Unable to apply ioctls for sandbox"); + if (caph_fcntls_limit(bind_fd, CAP_FCNTL_SETFL) == -1) + errx(EX_OSERR, "Unable to apply fcntls for sandbox"); +#endif + + if ((sc->mev = mevent_add(bind_fd, EVF_READ, uart_tcp_listener, + socket_softc)) == NULL) + goto clean; + + return (0); + +clean: + if (bind_fd != -1) + close(bind_fd); + if (socket_softc != NULL) + free(socket_softc); + if (src_addr) + freeaddrinfo(src_addr); + return (-1); +} + struct uart_softc * uart_init(void) { struct uart_softc *sc = calloc(1, sizeof(struct uart_softc)); if (sc == NULL) return (NULL); pthread_mutex_init(&sc->mtx, NULL); return (sc); } int uart_tty_open(struct uart_softc *sc, const char *path, void (*drain)(int, enum ev_type, void *), void *arg) { int retval; if (strcmp("stdio", path) == 0) retval = uart_stdio_backend(sc); + else if (strncmp("tcp", path, 3) == 0) + retval = uart_tcp_backend(sc, path, drain, arg); else retval = uart_tty_backend(sc, path); - if (retval == 0) { + + /* + * A connection-oriented protocol should wait for a connection, + * so it may not listen to anything during initialization. + */ + if (retval == 0 && !sc->tty.is_socket) { ttyopen(&sc->tty); sc->mev = mevent_add(sc->tty.rfd, EVF_READ, drain, arg); assert(sc->mev != NULL); } return (retval); } void uart_softc_lock(struct uart_softc *sc) { pthread_mutex_lock(&sc->mtx); } void uart_softc_unlock(struct uart_softc *sc) { pthread_mutex_unlock(&sc->mtx); }