machine: qemu: add usb host passthrough

QEMU usb-host driver which is the one for passthrough, supports two
options for selecting an USB devices in the host to provide it to the
VM:
 - Bus and Device number the device is plugged
 - Vendor and Product information of the USB devices

    https://qemu-project.gitlab.io/qemu/system/devices/usb.html

This commit allows a user to configure podman machine with either of
options, with new --usb command line option for podman machine init.

Examples
  podman machine init tosovm4 --usb vendor=13d3,product=5406
  podman machine init tosovm3 --usb bus=1,devnum=4 --usb bus=1,devnum=3

This commit also allows a user to change the USBs configured with
--usb command line option for podman machine set.

Note that this commit does not handle host device permissions nor
verify that the USB devices exists.

Signed-off-by: Victor Toso <victortoso@redhat.com>
This commit is contained in:
Victor Toso
2023-11-08 23:38:53 +01:00
parent 6bb2edd215
commit c23963d7a8
15 changed files with 260 additions and 0 deletions

View File

@ -4,6 +4,7 @@ import (
"fmt"
"strconv"
"github.com/containers/podman/v4/pkg/machine"
"github.com/containers/podman/v4/pkg/machine/define"
)
@ -46,6 +47,24 @@ func (q *QemuCmd) SetNetwork() {
*q = append(*q, "-netdev", "socket,id=vlan,fd=3", "-device", "virtio-net-pci,netdev=vlan,mac=5a:94:ef:e4:0c:ee")
}
// SetNetwork adds a network device to the machine
func (q *QemuCmd) SetUSBHostPassthrough(usbs []machine.USBConfig) {
if len(usbs) == 0 {
return
}
// Add xhci usb emulation first and then each usb device
*q = append(*q, "-device", "qemu-xhci")
for _, usb := range usbs {
var dev string
if usb.Bus != "" && usb.DevNumber != "" {
dev = fmt.Sprintf("usb-host,hostbus=%s,hostaddr=%s", usb.Bus, usb.DevNumber)
} else {
dev = fmt.Sprintf("usb-host,vendorid=%d,productid=%d", usb.Vendor, usb.Product)
}
*q = append(*q, "-device", dev)
}
}
// SetSerialPort adds a serial port to the machine for readiness
func (q *QemuCmd) SetSerialPort(readySocket, vmPidFile define.VMFile, name string) {
*q = append(*q,