Подключение и отключение USB устройств к виртуальной машине KVM
Подключаем устрйоство к хосту с KVM и смотрим как оно определилось:
$ lsusb Bus 004 Device 024: ID 11a0:eb20 Chipcon AS
Тут нас интересуют номер шины и номер устройства: Bus 004 Device 024: На основании этих сведений создаем файлик *.xml:
<hostdev mode='subsystem' type='usb' managed='yes'> <source> <address bus='4' device='24'/> </source> </hostdev>
Также вместо положения на шине можно указывать VendorID и DeviceID:
<hostdev mode='subsystem' type='usb'> <source> <vendor id='0x03f0'/> <product id='0x4217'/> </source> </hostdev>
Нули из номера шины и номера девайса нужно убрать.
Теперь запускаем машину и узнаем ее мя:
$ virsh list Id Name State ---------------------------------------------------- 2 Windows_7_x64_Ent_RUS running
Теперь подключаем устройство:
virsh attach-device <VM name> <file>
То есть в моем случае:
$ virsh attach-device Windows_7_x64_Ent_RUS ./progr.xml Device attached successfully
Ну и самое интересное - оформление правил udev для автоматического подключения устройств.
/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"
И перечитать правила:
sudo udevadm control --reload-rules && sudo udevadm trigger
Ошибки
Если при попытке проброса устройства команда выполняется без ошибок с рузультатом:
Device attached successfully
в гостевой машине ничего не появляется, при этом в журнале хоста KVM есть ошибки типа:
apparmor="DENIED" operation="open"
Значит на хосте KVM в файлике /etc/apparmor.d/abstractions/libvirt-qemu нужно сделать некторые изменения:
Строку /dev/bus/usb/ r, привести к виду: /dev/bus/usb/ rw,
И еще добавить пару строк:
/dev/bus/usb/*/[0-9]* rw, /run/udev/** rw,
То есть выполнить:
cp /etc/apparmor.d/abstractions/libvirt-qemu ~/libvirt-qemu.backup sudo sed -i 's/\/dev\/bus\/usb\/\ r,/\/dev\/bus\/usb\/\ rw,/' /etc/apparmor.d/abstractions/libvirt-qemu sudo sed -i '\/dev\/bus\/usb\/\ rw,/ a\/dev\/bus\/usb\/\*\/\[0-9\]\* rw,' /etc/apparmor.d/abstractions/libvirt-qemu sudo sed -i '\/dev\/bus\/usb\/\ rw,/ a\/run\/udev\/\*\* rw,' /etc/apparmor.d/abstractions/libvirt-qemu
И перезапустить сервисы (или перезагрузить хост):
sudo service apparmor restart sudo service libvirtd restart
Подключение всего USB-хоста к виртуалке
Определяем на каком хосте работает USB-устройство:
lsusb ... Bus 001 Device 002: ID 0e8d:20ff MediaTek Inc. Android
Определяем номер устройства на шине PCI:
$ readlink /sys/bus/usb/devices/usb* ../../../devices/pci0000:00/0000:00:08.1/0000:03:00.3/usb1 ../../../devices/pci0000:00/0000:00:08.1/0000:03:00.3/usb2 ../../../devices/pci0000:00/0000:00:08.1/0000:03:00.4/usb3 ../../../devices/pci0000:00/0000:00:08.1/0000:03:00.4/usb4
Кажется в моем случае это Bus 001 → /devices/pci0000:00/0000:00:08.1/0000:03:00.3/usb1
Смотрим какой модуль ядра рулит этим девайсом:
$ls /sys/bus/pci/drivers/*_hcd/ ... /sys/bus/pci/drivers/xhci_hcd/: 0000:03:00.3 0000:03:00.4 bind module new_id remove_id uevent unbind
Отключаем и подключаем к vfio-pci https://01.org/linuxgraphics/gfx-docs/drm/driver-api/vfio.html
sudo su modprobe vfio-pci lspci -n -s 0000:03:00.3 ... 03:00.3 0c03: 1022:1639 ... echo 0000:03:00.3 > /sys/bus/pci/devices/0000:03:00.3/driver/unbind lspci -n -s 0000:03:00.3 ... 03:00.3 0c03: 1022:1639 ... echo 1022 1639 > /sys/bus/pci/drivers/vfio-pci/new_id echo -n "0000:03:00.3" > /sys/bus/pci/drivers/vfio-pci/bind
ls -l /sys/bus/pci/devices/0000:03:00.3/iommu_group/devices
Discussion