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


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

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


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

Неудачное решение


Первое, что пришло в голову после изучения документации — указать в конфигурации виртуальной машины все возможные bus и device для этих одинаковых USB-ключей. Но это породило неудобство при просмотре и редактировании виртуальной машины в Virt-Manager.

Окончательное решение.


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

Использование этого метода исключает переключение USB-ключей во время работы виртуальной машины — если вытащить ключ и вставить его в другой порт, он не будет подключен повторно. Для сервера это ограничение приемлимо.

Вывод 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).

Комментарии (6)


  1. 3om6ak
    09.06.2015 09:30

    Добрый день!
    При пробросе ключей Guardant Stealth II в KVQ/QEMU (Proxmox) программа (в виртуалке естественно) время от времени (раз в сутки примерно) теряет их… Не сталкиваливались вы с подобными проблемами?


    1. grumbler66rus Автор
      09.06.2015 12:53

      Насчёт proxmox ничего сказать не могу.
      В QEMU-KVM я сталкивался с потерей устройства USB (внешняя «корзина» с диском SATA 3«5). Оказалось, что виноват контроллер в корзине.
      Ранее сталкивался с тем, что виртуальная сетевая карта перестаёт работать, „лечится“ такое отсоединением и повторным присоединением интерфейса. Однажды, после очередного обновления ядра сеть стала работать нормально.

      1) Последовательность detach-device и attach-device исправляет ситуацию?
      2) Проверьте dmesg на хост-машине, там может быть интересное про этот USB-ключ.


      1. 3om6ak
        09.06.2015 14:55

        Помогает простой перезапуск приложения, использующего USB-ключ. Складывается ощущение, что возник быстрый реконнект устройства. Т.е. как будто оно было выключено и включено на guest-машине.
        dmesg ничего необычного не говорит… мистика


        1. grumbler66rus Автор
          14.06.2015 09:52

          По идее, реконнект устройства должен быть отражён в Event log гостевой машины.


          1. 3om6ak
            16.06.2015 15:17

            Ничего такого нет(( Я прям не знаю куда копать уже.
            Уже даже поменял схему энергопотребления (запретить отключение USB), поменял настройки usbcore в proxmox (autosuspend отключил) — всё равно не работает.
            При этом на реальной машине работает без проблем


            1. 3om6ak
              22.06.2015 08:50

              Всё оказалось до безобразия просто… это проблема драйверов Guardant. Оказывается косячит последняя версия с сайта (7.0.148). После установки версии 5.40.80 (была в комплекте с ПО) — проблема исчезла.