How to auto-hotplug usb devices to libvirt VMs (Update 1)

2014-02-26:
I've updated this HowTo for current versions of udev and kvm.

libvirt/kvm allows you to expose any usb device attached to your physical maschine to the guests. Just edit the domain's XML definition and add the following <hostdev> to the <devices> area:

<domain type='kvm'>
   ...
  <devices>
    ....
  <!-- The XHCI driver includes support for USB 2 devices, which makes 
       it easier as with UHCI/EHCI to add an USB controller. Remove 
       existing USB controllers from definition. -->
  <controller type='usb' index='0' model='nec-xhci' /> 
  <hostdev mode='subsystem' type='usb' managed='yes'>
      <source startupPolicy='optional'>
        <vendor id='0x03f0'/>
        <product id='0x4217'/>
      </source>
    </hostdev>
  </devices>
</domain>

Vendor id and product id can be determined with 'lsusb':

$ lsusb
...
Bus 002 Device 018: ID 03f0:4217 Hewlett-Packard EWS CM1015
...

Sadly this only works if the device is attached and enabled when the VM is started. The connection will be lost whenever the device is disabled or removed. But you can re-attach it at runtime. Just put the hostdev-definition into it's own file:

hostdev-03f0:4217.xml

<hostdev mode='subsystem' type='usb'>
  <source>
    <vendor id='0x03f0'/>
    <product id='0x4217'/>
  </source>
</hostdev>

And execute the following command when the device is available again:

virsh attach-device GUESTNAME /path/to/hostdev-03f0:4217.xml

You can use udev to automatically run this command whenever the device is attached:

/etc/udev/rules.d/90-libvirt-usb.rules

ACTION=="add", \
    SUBSYSTEM=="usb", \
    ENV{ID_VENDOR_ID}=="03f0", \
    ENV{ID_MODEL_ID}=="4217", \
    RUN+="/usr/bin/virsh attach-device GUESTNAME /path/to/hostdev-03f0:4217.xml"
ACTION=="remove", \
    SUBSYSTEM=="usb", \
    ENV{ID_VENDOR_ID}=="03f0", \
    ENV{ID_MODEL_ID}=="4217", \
    RUN+="/usr/bin/virsh detach-device GUESTNAME /path/to/hostdev-03f0:4217.xml"

Previously, this example depended on sysFs{idVendor} and sysFs{idProduct} in order to match the correct USB device. These do not exist any longer, so I replaced them with environment variables containing the same information. To find out what attributes are available for matching, run udev monitor --property --udev while attaching and detaching the device.

Update: Fixed Typo

Comments

I have been trying your method of auto-hotplug, but I have problems initializing it. any tips?

Please ensure that the udev rules is executed. E.g. replace the RUN-Command by a shell script that writes something to /tmp.

You saved my 2-3 hours. Thank you!

It works!!!
A little inconvenience is hostdev alias becomes renumbered in the guest OS and sometimes driver re-intallation is required.
But yeah, it works without shutting virtual OS down/changing config/then starting :-)

Regards,
Arty

Very nice post.
A little shell for Debian Wheezy.
We need to replace "SYSFS" by "ATTR" for example : ATTR{idVendor}==....
To reload udev rules, we can use : udevadm control --reload-rules

Regards

There's a small typo in /etc/udev/rules.d/90-libvirt-usb.rules:

ENV{iID_VENDOR_ID}=="03f0", \

should be

ENV{ID_VENDOR_ID}=="03f0", \

thank you wary match for post!

in file /etc/udev/rules.d/90-libvirt-usb.rules
line 3
ENV{iID_VENDOR_ID}=="03f0", \
error "iID"

I'm running a modified version of this to get the vendor id's to the script that runs however, calling the ENV variables with %E in the run command only works on the remove action not the add action.

Thank you for the post, Useful for me for attaching and detaching.
suggestions :
virsh attach guestname --file path/to/file.xml
ATTRS{idVendor}=="xxxx" ATTRS{idProduct}=="xxxx" can be used to find specific device to be added or change any parameter to verify and add using the below command, you can find specific parameters using
udevadm info -a -n /dev/ttyUSBX

Thank you, thank you, thank you!

Works a treat with Ipad , the Libvirt/KVM i have with local host machine, local host always tries to access the storage device and blocks the autoredirect usb functionality of Spice.

Many, many thanks Roland, I'm really grateful you took the time to post this.

Thank you so much for this simple and to the point post ... it works so well. Had some issues with AppArmor to get USB working in VM. But as it was working this was a very nice addition!

Hello Roland,

We are using onapp version 5.X . we would like to attach usb disk to windows kvm VM.
Wer have already created xxx.xml file with vendor and product ID . The Device is attached successfully

[root@]# virsh attach-device vmID /tmp/usb.xml
Device attached successfully

However, USB disk not detecting within vm. Please advice, how to resolve this issue.

I found a script to add any device of bus PCI

https://github.com/olavmrk/usb-libvirt-hotplug