Configuration.
Virtual Machine Server on GNU / Linux. Windows virtual machines. Hypervisor QEMU-KVM.
Virtual machines start automatically.
Description of the problem.
For two programs there are two electronic (licensed) Guardant keys of the same model (they have the same Vendor ID and Product ID). To avoid a conflict, in libvirt in the description of the virtual machine such keys are added with the hardware address (bus, device). After a reboot, it may be that the device numbers are different. And if you switch them to another port, then the bus number may be different.
Bad decision
The first thing that came to mind after studying the
documentation was to specify in the virtual machine configuration all possible bus and device for these identical USB keys. But this caused inconvenience when viewing and editing a virtual machine in Virt-Manager.
The final decision.
There was no desire to deal with UDEV. (I don’t know if it is possible to change the device number on the USB bus, but it’s probably impossible to change the bus number.)
Therefore, the most versatile solution was applied: during the boot process, after starting the virtual machine, a script is executed that finds out the bus numbers and the device number for each of the same electronic keys, generates a device description file for libvirt (XML format) and adds forwarding of these devices to the virtual machine . If an error occurs in the script, it is recorded in the syslog and on stderr.
In order not to invent start / stop / status processing and dependency checking, the script has been added to rc.local - it is certainly executed by the last of the start scripts.
')
Using this method prevents switching of USB keys while the virtual machine is running - if you pull out the key and insert it into another port, it will not be reconnected. For a server, this restriction is acceptable.
The lsusb output (for reference), the devices you need are the fifth and sixth on the third bus:
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
Script text:
#!/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."
Explanation of the text.
For simplicity, the AWK program is passed on the command line. At the same time, to avoid difficulties with escaping quotes and "$", variables of the shell are not used inside the awk program. Therefore, a transition to the created temporary directory has been made, and the device parameters are given by constants (Vendor ID 0x0a89 and Product ID 0x0008).