複数の同一のUSBデバイスをlibvirt + QEMU仮想マシンに転送する

構成。



GNU / Linux上の仮想マシンサーバー。 Windows仮想マシン。 ハイパーバイザーQEMU-KVM。

仮想マシンは自動的に起動します。



問題の説明。



2つのプログラムには、同じモデルの2つのGuardant電子(ライセンス)キーがあります(それらは同じベンダーIDと製品IDを持っています)。 競合を避けるため、libvirtでは、仮想マシンの説明にそのようなキーがハードウェアアドレス(バス、デバイス)で追加されます。 再起動後、デバイス番号が異なることが判明する場合があります。 また、それらを別のポートに切り替えると、バス番号が異なる場合があります。



悪い決断



ドキュメントを検討した後、最初に思いついたのは、これらの同一のUSBキーに使用可能なすべてのバスとデバイスを仮想マシン構成で指定することでした。 しかし、これにより、Virt-Managerで仮想マシンを表示および編集する際に不便が生じました。



最終決定。



UDEVに対処する意欲はありませんでした。 (USBバス上のデバイス番号を変更できるかどうかはわかりませんが、バス番号を変更することはおそらく不可能です。)

したがって、最も普遍的なソリューションが適用されました:ブートプロセス中に、仮想マシンを起動した後、同じ電子キーのそれぞれのバス番号とデバイス番号を検出し、libvirt(XML形式)のデバイス記述ファイルを生成し、これらのデバイスの転送を仮想マシンに追加するスクリプトが実行されます。 スクリプトでエラーが発生した場合、syslogおよびstderrに記録されます。

start / stop / status処理と依存性チェックを思い付かないように、スクリプトはrc.localに追加されます-明らかに最後の起動スクリプトによって実行されます。



この方法を使用すると、仮想マシンの実行中にUSBキーを切り替える必要がなくなります。キーを削除して別のポートに挿入した場合、再接続されません。 サーバーの場合、この制限は受け入れられます。



lsusbの出力(参照用)、必要なデバイスは3番目のバスの5番目と6番目です。

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プログラム内で使用されませんでした。 そのため、作成された一時ディレクトリへの移行が行われ、デバイスパラメーターは定数(ベンダーID 0x0a89および製品ID 0x0008)によって設定されます。




All Articles