Dynamically attach and detach USB devices to a libvirt guest
Go to file
David Thurstenson dd93ee98f7 Added README 2020-07-05 01:33:24 -05:00
PKGBUILD Initial Commit 2020-07-04 20:19:50 -05:00
README.md Added README 2020-07-05 01:33:24 -05:00
libvirt-usb-hotplug.bash Initial Commit 2020-07-04 20:19:50 -05:00
libvirt-usb-hotplug.conf Initial Commit 2020-07-04 20:19:50 -05:00
libvirt-usb-hotplug.rules Initial Commit 2020-07-04 20:19:50 -05:00
libvirt-usb-hotplug@.service Initial Commit 2020-07-04 20:19:50 -05:00


libvirt-usb-hotplug - Dynamically attach and detach USB devices to a libvirt guest


Udev rules: libvirt-usb-hotplug.rules

The add rule in this file is the first point of action. Any usb device that is connected will trigger this rule, and then Udev will run libvirt-usb-hotplug.bash as the logic that determines if the device in question should be attached to the guest domain.

Additionally, this rule creates a symlink that points to the dev path of the device, with a predictable name in the format of libvirt_<targetdomain>_<ID_VENDOR_ID>_<ID_MODEL_ID>. This string also gets passed to the systemd service and, subsequently, the Bash script for attaching/detaching the device.

Finally, the systemd service and instance name are added to the SYSTEMD_WANTS property of the device's udev database entry. This creates a Wants= dependency to the resulting systemd device unit, which will cause the systemd service to start as soon as this device unit is created.

The remove rule still needs some work.

Bash script: libvirt-usb-hotplug.bash

This script serves two purposes. One is to attach and detach the device in question, and the other is to do ID matching against the devlist array in libvirt-usb-hotplug.conf.

When udev triggers the add rule, it runs this script to determine if the device should be connected to the configured guest domain. See the Config File section for further discussion of this logic.

The second run of this script is from the systemd service. This run is fairly simple, and mainly formats the information into the correct places in the XML snippit, and hands the result to virsh to do the actual connection.

Systemd service: libvirt-usb-hotplug@.service

This service file handles the second run of the Bash script. It's started as a dependency of the systemd device unit that is spawned by the udev rule.

Config file: libvirt-usb-hotplug.bash

Matching can be configured in the following modes:

  • whitelist: Any device in devlist will return a good match. Any others will be ignored.
  • blacklist: Any device NOT in devlist will return a good match.
  • matchall: Bypasses matching logic, and always returns a good match.


  • Handle device disconnects in udev rule
  • Detach all devices on guest shutdown (or another appropriate teardown trigger)
  • Accept wildcard for one or both parts of the dev id (e.g.: "0b05:" or ":1872")
  • Check that the target domain is started before running anything
  • Find a way to gracefully enable and disable this setup, preferably with systemd