Проброс нескольких одинаковых устройств USB в виртуальную машину libvirt+QEMU

от автора


Конфигурация.

Сервер виртуальных машин на GNU/Linux. Виртуальные машины Windows. Гипервизор QEMU-KVM.
Виртуальные машины запускаются автоматически.

Описание проблемы.

Для двух программ есть два электронных (лицензионных) ключа Guardant одной модели (у них одинаковые Vendor ID и Product ID). Чтобы не возникал конфликт, в libvirt в описании виртуальной машины такие ключи добавляются с указанием аппаратного адреса (bus, device). После перезагрузки может оказаться так, что номера устройств будут другие. А если переключить их в другой порт, то и номер шины может стать другим.

Решение.

Разбираться с UDEV желания не было. (Не знаю, можно ли в нём изменить номер устройства на шине USB, а изменить номер шины наверняка невозможно.)
Поэтому было применено максимально универсальное решение: в процессе загрузки после запуска виртуальной машины выполняется скрипт, который выясняет номера шины и номер устройства для каждого из одинаковых электронных ключей, формирует файл-описание устройств для libvirt (формата XML) и добавляет проброс этих устройств в виртуальную машину. Если в скрипте возникнет ошибка, она заносится в syslog и на stderr.
Чтобы не придумывать обработку start/stop/status и проверку зависимостей, скрипт добавлен в rc.local — он заведомо выполняется последним из стартовых скриптов.

Вывод lsusb (для справки), нужные устройства — пятое и шестое на третьей шине:

Bus 003 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 003 Device 003: ID 1a40:0101 Terminus Technology Inc. Hub Bus 003 Device 008: ID 051d:0002 American Power Conversion Uninterruptible Power Supply Bus 003 Device 004: ID 064f:0bd8 WIBU-Systems AG BOX/RU Bus 003 Device 005: ID 0a89:0008 Bus 003 Device 006: ID 0a89:0008 Bus 004 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub Bus 004 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub

Текст скрипта:

#!/bin/sh # libvirt-win-attach-guardant-keys # attach all guardant keys into virtual machine "win"  VMachine="win" MYDIR="/tmp/libvirt-guardant/" SYSLOG="logger -s -p daemon.error "  if [ -d $MYDIR ]; then rm -f $MYDIR/*_*.xml ; else  mkdir $MYDIR || ( $SYSLOG "Can't create $MYDIR" ; exit 1 ) fi cd $MYDIR echo "Attach guardant keys into virtual machine \"$VMachine\":" lsusb | awk '/ID 0a89:0008/{gsub(":", "", $4);print "<hostdev mode=\"subsystem\" type=\"usb\" managed=\"yes\">\n <source>\n  <vendor id=\"0x0a89\" /><product id=\"0x8\" />\n  <address bus=\"" $2 "\" device=\"" $4 "\" />\n </source>\n</hostdev>" > ""$2"_"$4".xml"; }' ||  ( $SYSLOG "Error in lsusb|awk: $? $!" ; exit 1 ) for devxml in *_*.xml ; do echo "   USB_${devxml/.xml/} ..." ;  virsh attach-device $VMachine $devxml | grep -vE "^(Device attached successfully|$)" ; done cd /tmp rm -f $MYDIR/*.xml rmdir $MYDIR echo "Done." 

Пояснение к тексту.
Для простоты программа для AWK передаётся в командной строке. При этом, чтобы избежать сложностей с экранированием кавычек и "$", внутри awk-программы переменные шела не используются. Поэтому сделан переход в созданный временный каталог, а также параметры устройств заданы константами (Vendor ID 0x0a89 и Product ID 0x0008).

ссылка на оригинал статьи http://habrahabr.ru/post/259401/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *