Hotplug USB Devices into libvirt VMs

2020-05-01

At some point I wanted to attach a USB printer into a libvirt/qemu virtual machine. This works fine as long as you do not disconnect the USB device. libvirt does not monitor for newly appearing devices. So once the USB-Device is disconnected from the host it's until you manually re-add it.

I am quite sure that I want to do this again some time in the future. And I am quite sure that I won't remember how I did it - so I am writing it down...

Attach a USB Device

Attach your device to your VM using virtmanager. You will end up with a section like this in your machine definition:

<hostdev mode='subsystem' type='usb' managed='yes'>
  <source>
    <vendor id='0x04f9'/>
    <product id='0x2015'/>
  </source>
  <address type='usb' bus='0' port='4'/>
</hostdev>

Copy this snippet into a new file, for example in /etc/libvirt/snippets/. Afterwards you can load this snippet into your VM using virsh:

$ virsh attach-device VMNAME /etc/libvirt/snippets/SNIPPET.xml
Device attached successfully

udev

You can automate this pluging und unplugging using udev. Just add a /etc/udev/rules.d/90-libvirt-usb.rules:

ACTION=="add",    SUBSYSTEM=="usb", ENV{PRODUCT}=="4f9/2015/100", RUN+="/usr/bin/virsh attach-device VMNAME /etc/libvirt/snippets/SNIPPET.xml"
ACTION=="remove", SUBSYSTEM=="usb", ENV{PRODUCT}=="4f9/2015/100", RUN+="/usr/bin/virsh detach-device VMNAME /etc/libvirt/snippets/SNIPPET.xml"

You can find that ENV{PRODUCT} using udevadm monitor --environment.