Anschließen eines USB-Dongles an eine KVM-VM

7

Ich habe Probleme, ein USB-Gerät, das vom Host korrekt erkannt wird, mit einem kvm vm zu verbinden.

Ich habe einen frisch installierten Ubuntu Server 14.10 als KVM / QEMU-Host. Ich habe eine Ubuntu vm mit diesem Befehl eingerichtet:

virt-install --connect qemu:///system \
            -n test01 \
            -r 1024 \
            --vcpus=2 \
            --disk path=/vmstorage/01/test01.img,size=5 \
            --vnc \
            --noautoconsole \
            --os-variant=ubuntuutopic \
            --hvm \
            --cdrom /path/to/ubuntu-14.10-server-i386.iso

Nach erfolgreicher Installation virsh dumpxml test01kehrt a zurück

<domain type='kvm' id='16'>
  <name>test01</name>
  <uuid>f58ca825-c999-4168-9f5a-616057d9955d</uuid>
  <memory unit='KiB'>1048576</memory>
  <currentMemory unit='KiB'>1048576</currentMemory>
  <vcpu placement='static'>2</vcpu>
  <resource>
    <partition>/machine</partition>
  </resource>
  <os>
    <type arch='x86_64' machine='pc-i440fx-utopic'>hvm</type>
    <boot dev='hd'/>
  </os>
  <features>
    <acpi/>
    <apic/>
    <pae/>
  </features>
  <cpu mode='custom' match='exact'>
    <model fallback='allow'>SandyBridge</model>
  </cpu>
  <clock offset='utc'>
    <timer name='rtc' tickpolicy='catchup'/>
    <timer name='pit' tickpolicy='delay'/>
    <timer name='hpet' present='no'/>
  </clock>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>restart</on_crash>
  <devices>
    <emulator>/usr/bin/kvm-spice</emulator>
    <disk type='file' device='disk'>
      <driver name='qemu' type='raw'/>
      <source file='/vmstorage/01/test01.img'/>
      <backingStore/>
      <target dev='vda' bus='virtio'/>
      <alias name='virtio-disk0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
    </disk>
    <disk type='block' device='cdrom'>
      <driver name='qemu' type='raw'/>
      <backingStore/>
      <target dev='hda' bus='ide'/>
      <readonly/>
      <alias name='ide0-0-0'/>
      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
    </disk>
    <controller type='usb' index='0' model='ich9-ehci1'>
      <alias name='usb0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x7'/>
    </controller>
    <controller type='usb' index='0' model='ich9-uhci1'>
      <alias name='usb0'/>
      <master startport='0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0' multifunction='on'/>
    </controller>
    <controller type='usb' index='0' model='ich9-uhci2'>
      <alias name='usb0'/>
      <master startport='2'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x1'/>
    </controller>
    <controller type='usb' index='0' model='ich9-uhci3'>
      <alias name='usb0'/>
      <master startport='4'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x2'/>
    </controller>
    <controller type='pci' index='0' model='pci-root'>
      <alias name='pci.0'/>
    </controller>
    <controller type='ide' index='0'>
      <alias name='ide0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
    </controller>
    <interface type='bridge'>
      <mac address='52:54:00:11:b2:c1'/>
      <source bridge='br0'/>
      <target dev='vnet0'/>
      <model type='virtio'/>
      <alias name='net0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>
    <serial type='pty'>
      <source path='/dev/pts/0'/>
      <target port='0'/>
      <alias name='serial0'/>
    </serial>
    <console type='pty' tty='/dev/pts/0'>
      <source path='/dev/pts/0'/>
      <target type='serial' port='0'/>
      <alias name='serial0'/>
    </console>
    <input type='mouse' bus='ps2'/>
    <input type='keyboard' bus='ps2'/>
    <graphics type='vnc' port='5900' autoport='yes' listen='0.0.0.0'>
      <listen type='address' address='0.0.0.0'/>
    </graphics>
    <video>
      <model type='cirrus' vram='9216' heads='1'/>
      <alias name='video0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
    </video>
    <memballoon model='virtio'>
      <alias name='balloon0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
    </memballoon>
  </devices>
  <seclabel type='dynamic' model='apparmor' relabel='yes'>
    <label>libvirt-f58ca825-c999-4168-9f5a-616057d9955d</label>
    <imagelabel>libvirt-f58ca825-c999-4168-9f5a-616057d9955d</imagelabel>
  </seclabel>
</domain>

Ich möchte jetzt einen USB-Stick anschließen. Nach einigen googleing ich fand einige Quellen , dass im Grunde alle folgenden Ansatz vorschlagen:

  1. Befestigen Sie den Stick am Host
  2. Hersteller- und Produkt-ID abrufen

    root@host01:~# lsusb
    Bus 002 Device 004: ID 13fe:5100 Kingston Technology Company Inc. Flash Drive
    Bus 002 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
    Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
    Bus 001 Device 004: ID 0624:0249 Avocent Corp.
    Bus 001 Device 003: ID 0624:0248 Avocent Corp.
    Bus 001 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
    Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
    
  3. füge ein neues config-snippet zu vm via hinzu virsh edit test01

    <devices>
      <!- ... ->
      <hostdev mode='subsystem' type='usb' managed='yes'>
        <source>
          <vendor id='0x13fe'/>
          <product id='0x5100'/>
        </source>
      </hostdev>
    </devices/>
    
  4. vm neu starten

Danach sollte der VM den Stick über sehen lsusb, aber nichts ändert sich. Wenn ich jedoch versuche, das Gerät an eine zweite VM anzuschließen, virsh start <othervm>schlägt dies fehl, error: Requested operation is not valid: USB device 002:003 is in use by driver QEMU, domain test01 ABER ich kann trotzdem den Stick auf dem Host mounten und darauf zugreifen. Ich habe verschiedene Sticks und verschiedene VM-Betriebssysteme (Ubuntu und Windows) ausprobiert, kein Erfolg.

Einige Anweisungen schlagen vor, Apparmor auszuschalten, aber a /etc/init.d/apparmor stophat nichts geändert.

Das macht mich verrückt, da ich keine Fehler- oder Protokollmeldungen erhalte und keine Ahnung habe, wie ich herausfinden kann, was falsch ist. Irgendwelche Ideen, wie man den USB mit dem VM verbindet oder zumindest wie man ihn weiter analysiert?

csch
quelle

Antworten:

4

Es ist wahrscheinlich ein Problem mit Zugriffsrechten. Ihr QEMU-Deamon darf nicht auf die USB-Geräte zugreifen. Versuchen:

chown libvirt-qemu /dev/bus/usb/ -R

oder welcher Benutzer auch immer Ihre KVM ausführt. Dies sollte den Trick tun.

Amöbe
quelle
Dies würde nur vorübergehend bis zum nächsten Neustart funktionieren. siehe meine Antwort für eine dauerhafte Lösung.
Ich hatte das gleiche Problem mit Ubuntu 16.04 und das hat bei mir nicht funktioniert. Ich habe festgestellt, dass ich die Apparmor-Konfiguration wie im Ubuntu KVM-Passthrough-Wiki beschrieben ändern muss: help.ubuntu.com/community/KVM/…
Max
7

Um dem Benutzer, unter dem der Hypervisor ausgeführt wird, permanenten Zugriff auf die unformatierten USB-Geräteknoten zu gewähren, müssen Sie eine udev-Regel erstellen. Die chown-basierte Antwort funktioniert nur bis zum nächsten Neustart.

In /lib/udev/rules.dErstellen Sie eine Datei wie 51-usb_passthrough.rules:

SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ATTRS{busnum}=="2" ATTRS{devpath}=="1" GROUP="kvm"

Hier habe ich physische Bus- und Portnummern verwendet, um auf das Gerät abzuzielen (da ich es vorziehe, den physischen Port zu passieren, unabhängig davon, welches Gerät angeschlossen ist, anstatt meine VM jedes Mal neu zu konfigurieren, wenn ich ein neues Gerät anschließe), aber natürlich können Sie beliebige Attribute verwenden Sie wollen; Das GROUPArgument bestimmt die Gruppe, der der Geräteknoten gehört. Dies sollte der Benutzer sein, der die virtuellen Maschinen ausführt.

Führen Sie diese aus udevadm control --reload-rules, um die neue Regel sofort wirksam zu machen (Sie müssen die USB-Geräte noch trennen / erneut verbinden) oder starten Sie den Host einfach neu.


quelle
Dies hat das Problem für mich nicht gelöst
Natus Drew
2

Einfache Lösung: verbinden mit

nc -U socket-file

zu Ihrem QEMU-Monitor, wobei Socket-Datei der zu überwachende Pfad ist. So finden Sie: ps -FA | grep qemu. Sie finden es dort in der Kommandozeile.

Führen Sie den Befehl auf dem Monitor aus:

device_add usb-host,id=<ANY string>,hostbus=<BUS>,hostport=<PORT>

Dies erfolgt über die Portnummer. Sie können jedes Gerät mit jeder VID / PID passieren. Sie können auch bestimmte Geräte mit passieren

device_add usb-host,id=<ANY string>,vendorid=0x0461,productid= 0x0010

und sie können an jeden Port Ihres Hosts angeschlossen werden.

Hilfreiche Befehle auch:

info usbhost
info usb
Vitaly Greck
quelle
Beachten Sie, dass Sie anstelle von Netcat wahrscheinlich libvirt und virsh direkt mit etwas wie verwenden können virsh -c qemu:///system qemu-monitor-command --hmp test01 "device_add usb-host,...".
Rabexc