Libvirt automatic USB passthrough scripts

09 Aug 2020

Short guide to setup automatic USB passthrough for a virtual machine. With these scripts it is possible to dedicate USB port(s) for one virtual machine. Anything plugged in to the USB port will automaticly attach to a predefined virtual machine.

Lets install the scripts, found them on github made by olavmrk

mkdir -p /kvm/usb-hotplug
cd /kvm/usb-hotplug
git clone https://github.com/olavmrk/usb-libvirt-hotplug.git

Then run the udevadm monitor to see the actions when an usb device is attached

udevadm monitor --property --udev --subsystem-match=usb/usb_device

and then plug in a USB device, this will output loads of text

monitor will print the received events for:
UDEV - the event which udev sends out after rule processing

UDEV  [1300765.854711] add      /devices/pci0000:00/0000:00:08.1/0000:28:00.3/usb5/5-4/5-4.4 (usb)
ACTION=add
DEVPATH=/devices/pci0000:00/0000:00:08.1/0000:28:00.3/usb5/5-4/5-4.4
SUBSYSTEM=usb
DEVNAME=/dev/bus/usb/005/009
DEVTYPE=usb_device
PRODUCT=1b1c/b29/200
TYPE=0/0/0
BUSNUM=005
DEVNUM=009
SEQNUM=5304
USEC_INITIALIZED=1300765850734
ID_VENDOR=Corsair
ID_VENDOR_ENC=Corsair
ID_VENDOR_ID=1b1c
ID_MODEL=Voyager_Mini
ID_MODEL_ENC=Voyager\x20Mini
ID_MODEL_ID=0b29
ID_REVISION=0200
ID_SERIAL=Corsair_Voyager_Mini_899801162008011514251488
ID_SERIAL_SHORT=899801162008011514251488
ID_BUS=usb
ID_USB_INTERFACES=:080650:
ID_VENDOR_FROM_DATABASE=Corsair
ID_PATH=pci-0000:28:00.3-usb-0:4.4
ID_PATH_TAG=pci-0000_28_00_3-usb-0_4_4
MAJOR=189
MINOR=520

UDEV  [1300766.058848] bind     /devices/pci0000:00/0000:00:08.1/0000:28:00.3/usb5/5-4/5-4.4 (usb)
ACTION=bind
DEVPATH=/devices/pci0000:00/0000:00:08.1/0000:28:00.3/usb5/5-4/5-4.4
SUBSYSTEM=usb
DEVNAME=/dev/bus/usb/005/009
DEVTYPE=usb_device
DRIVER=usb
PRODUCT=1b1c/b29/200
TYPE=0/0/0
BUSNUM=005
DEVNUM=009
SEQNUM=5309
USEC_INITIALIZED=1300765850734
ID_VENDOR=Corsair
ID_VENDOR_ENC=Corsair
ID_VENDOR_ID=1b1c
ID_MODEL=Voyager_Mini
ID_MODEL_ENC=Voyager\x20Mini
ID_MODEL_ID=0b29
ID_REVISION=0200
ID_SERIAL=Corsair_Voyager_Mini_899801162008011514251488
ID_SERIAL_SHORT=899801162008011514251488
ID_BUS=usb
ID_USB_INTERFACES=:080650:
ID_VENDOR_FROM_DATABASE=Corsair
ID_PATH=pci-0000:28:00.3-usb-0:4.4
ID_PATH_TAG=pci-0000_28_00_3-usb-0_4_4
MAJOR=189
MINOR=520

Extract the DEVPATH= string

/devices/pci0000:00/0000:00:08.1/0000:28:00.3/usb5/5-4/5-4.4

This device path the actual USB port, lets make a script for udev to monitor the port. The script should be placed in /etc/udev/rules.d and named something like 90-usb-libvirt-hotplug.rules

SUBSYSTEM=="usb",DEVPATH=="/devices/pci0000:00/0000:00:08.1/0000:28:00.3/usb5/5-4/5-4.4"

This will instruct udev to monitor this device, the usb port of our choice, and it will monitor it. But it will not do anything so lets add a run command to run a script

SUBSYSTEM=="usb",DEVPATH=="/devices/pci0000:00/0000:00:08.1/0000:28:00.3/usb5/5-4/5-4.4",RUN+="/kvm/usb-hotplug/usb-libvirt-hotplug/usb-libvirt-hotplug.sh debian"

Now this script will instruct udev to run /kvm/usb-hotplug/usb-libvirt-hotplug/usb-libvirt-hotplug.sh debian command (change debian to the virtual machine name you use) . The script olavmrk wrote will now attach the device plugged into the usb port to the debian virtual machine. The script will also detach the USB device from the virtual machine when the USB device is disconnected.

Reload udev so it will now about the new rules

sudo service udev reload

Anything that is pluged into the USB port will automaticaly attach to the virtual machine, to add a second USB port to the virtual machine just add another row to the udev script like this

SUBSYSTEM=="usb",DEVPATH=="/devices/pci0000:00/0000:00:08.1/0000:28:00.3/usb5/5-4/5-4.1",RUN+="/kvm/usb-hotplug/usb-libvirt-hotplug.sh debian"
SUBSYSTEM=="usb",DEVPATH=="/devices/pci0000:00/0000:00:08.1/0000:28:00.3/usb5/5-4/5-4.4",RUN+="/kvm/usb-hotplug/usb-libvirt-hotplug.sh debian"

and reload udev rules

sudo service udev reload

Update - 13 Aug 2020

Yesterday I connected my PS4 controller to on of my USB ports I have dedicated for my virtual machine for charging during the night. But this hanged my virtual machine, both keyboard and mouse stopped working everything froze.

I have no idea why this happened, it’s not an issue for me because I don’t use my PS4 controller on my PC. But it could be useful to know there can be an issue doing so in a virtual machine.