Proxmox: USB Passthrough an LXC Container (mit eindeutigem Gerätenamen)
Die meisten reichen einfach das USB-Gerät mit der BUS und DEVICE-ID durch. Wird der Stick mal in ein anderen USB-Port gesteckt, funktioniert das ganze nicht mehr. Doch es geht auch anders...
Ich nutzte in diesem Beispiel ein CC2531 Zigbee USB-Dongle, den ich an mein zigbee2mqtt Container durchreichen möchte.
USB-Device identifizieren und festen Gerätenamen zuweisen:
Um das verwendete Geräte immer eindeutig identifizieren zu können benötigen wir die Vendor-ID, die Produkt-ID und die Seriennummer des USB-Devices. Am einfachsten, bekommen wir die Informationen von unserem Linux-Kernel. Damit wir nicht lange suchen müssen, ziehen wir erst einmal das USB-Gerät ab. Anschließend löschen wir den Kernel ring buffer mit:
$ sudo dmesg -C
Jetzt stecken wir das Device wieder in einen beliebigen USB-Port, warten 5 Sekunden und lassen uns die aktuellen Nachrichten vom Kernel ausgeben:
$ sudo dmesg
[81559.078490] usb 1-1.2: new full-speed USB device number 8 using ehci-pci
[81559.191689] usb 1-1.2: New USB device found, idVendor=0451, idProduct=16a8, bcdDevice= 0.09
[81559.191694] usb 1-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[81559.191697] usb 1-1.2: Product: TI CC2531 USB CDC
[81559.191699] usb 1-1.2: Manufacturer: Texas Instruments
[81559.191701] usb 1-1.2: SerialNumber: __0X00137B0018ED2AE2
[81559.192470] cdc_acm 1-1.2:1.0: ttyACM0: USB ACM device
So z.B. sieht es bei meinem Zigbee-Stick aus. Die benötigten Informationen habe ich fett markiert.
Mit diesen Infos erstellen wir uns jetzt eine udev-Rule. Hierzu bearbeiten wir die Datei /etc/udev/rules.d/99-usb-serial.rules
und fügen folgenden Inhalt (natürlich mit euren Daten) ein:
SUBSYSTEM=="tty", ATTRS{idVendor}=="0451", ATTRS{idProduct}=="16a8", ATTRS{serial}=="__0X00137B0018ED2AE2" SYMLINK+="ttyZIGBEE0"
KERNEL=="ttyACM[0-9]*",MODE="0666"
Die erste Zeile geniert für unser USB-Device ein Symlink mit einen von uns vorgegebenen Namen. Die zweite Zeile sorgt dafür, das die originale Gerätedatei die Berechtigung 666 bekommt, damit der Container später auch das Device lesen und beschreiben darf.
Jetzt noch die Rule aktivieren:
$ udevadm trigger
Nun überprüfen wir mal, ob das funktioniert hat.
$ ls -l /dev/ttyZIGBEE0
lrwxrwxrwx 1 root root 7 Apr 16 11:28 /dev/ttyZIGBEE0 -> ttyACM0
$ ls -l /dev/ttyACM0
crw-rw-rw- 1 root root 166, 0 Apr 16 16:00 /dev/ttyACM0
Perfekt! Der neue Symlink verweißt auf die originale Geräte-Datei und diese hat für "other" die "rw"-Bits gesetzt.
Dem Container das USB-Device zuordnen:
Nun müssen wir die neu generierte Geräte-Datei an den Container durchreichen.
Dafür wechseln wir in das Verzeichnis, in dem die Konfigurationsdateien unserer LXC-Container liegen:
$ cd /etc/pve/nodes/$(hostname)/lxc
Dort bearbeiten wir die Konfigurationsdatei unseres Containers, an den das Gerät gehen soll. In diesem Beispiel hat mein Container die ID 100 also bearbeiten wir die Datei 100.conf
und fügen am Ende folgendes hinzu:
lxc.mount.entry: /dev/ttyZIGBEE0 dev/ttyACM0 none bind,optional,create=file
Somit wird das Device /dev/ttyZIGBEE0
von unserem Proxmox-Host an den Container durchgereicht und dort als ttyACM0
erstellt.
Zum Schluss noch den Container starten und der Stick steht unter /dev/ttyACM0
zur Verfügung.
Sollte euer Container schon laufen, muss er einmal gestoppt und wieder neu gestartet werden. Nur so wird die Konfigurationsdatei neu eingelesen. Denn bei einem Restart des Containers wird die Konfig nicht neu eingelesen.