udev
Dieser Artikel wurde für die folgenden Ubuntu-Versionen getestet:
Ubuntu 22.04 Jammy Jellyfish
Ubuntu 20.04 Focal Fossa
Du möchtest den Artikel für eine weitere Ubuntu-Version testen? Mitarbeit im Wiki ist immer willkommen! Dazu sind die Hinweise zum Testen von Artikeln zu beachten.
Fehlerhafte Anleitung
Diese Anleitung ist fehlerhaft. Wenn du weißt, wie du sie ausbessern kannst, nimm dir bitte die Zeit und bessere sie aus.
Anmerkung: Automatischer Start eines lang laufenden Skripts (z.B. Backup) funktioniert über RUN+=
prinzipiell nicht!
Artikel für fortgeschrittene Anwender
Dieser Artikel erfordert mehr Erfahrung im Umgang mit Linux und ist daher nur für fortgeschrittene Benutzer gedacht.
Zum Verständnis dieses Artikels sind folgende Seiten hilfreich:
udev ist ein Dienst (Hintergrundprogramm), der die Gerätedateien im Verzeichnis /dev dynamisch verwaltet. udev übernimmt außerdem die Rechteverwaltung von Geräten und legt bei Bedarf Symlinks auf Gerätedateien an. Dies geschieht sowohl beim Bootvorgang als auch durch nachträgliches An- oder Abstecken eines Gerätes im laufenden Betrieb (Hotplug). Bekommt udev vom Kernel Informationen über ein Gerät (sog. "device uevents"), wertet es diese anhand fester, aber frei konfigurierbarer Regeln aus.
Es werden auch Eingabegeräte über udev konfiguriert. Weitere Hinweise hierzu findet man im Artikel xorg.conf.d.
Installation¶
udev ist als Bestandteil des Pakets
udev
unter Ubuntu bereits vorinstalliert.
udev-Regeln¶
udev-Regeln legen fest, was passiert, wenn ein Gerät erkannt wird. Eine udev-Regel enthält dazu mindestens eine Bedingung und mindestens eine Zuweisung (Regelsyntax). Treffen alle Bedingungen einer Regel auf ein Gerät zu, werden die Zuweisungen dieser Regel ausgeführt. Auf diese Weise werden auch Gerätenamen erzeugt, unter denen das Gerät anschließend im Dateisystem zur Verfügung steht. Es können mehrere Regeln auf das gleiche Gerät angewendet werden. Damit ist es möglich, zusätzlich zu den Standardregeln eigene Regeln auf dasselbe Gerät anzuwenden. Die einzelnen Regeldateien beginnen mit einer zweistelligen Zahl und werden in alphanumerischer Reihenfolge abgearbeitet. So ist sichergestellt, dass wichtige Regeln zuerst behandelt werden. Werden mehrere Regeln in eine Regeldatei geschrieben, werden diese zeilenweise voneinander getrennt.
Standardregeln¶
Die Standardregeln liegen in /lib/udev/rules.d/. Einige Systemregeln sind auch unter /etc/udev/rules.d/ zu finden.
Beispiele für Standardregeln¶
Das folgende Beispiel zeigt eine Standardregel aus der Datei /lib/udev/rules.d/50-udev-default.rules. Sie besagt: Gehört ein erkanntes Gerät zum Subsystem "block
", wird ihm die Gruppe "disk
"[6] zugewiesen.
# Block SUBSYSTEM=="block", GROUP="disk"
Die nächste Regel ist etwas länger: Wird ein Gerät im Subsystem "net
" mit der MAC-Adresse 57:04:b6:c2:6c:z3
erkannt, erhält es den Namen "eth0
", eine Gerätedatei wird unter Linux für Netzwerkschnittstellen nicht angelegt.
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="57:04:b6:c2:6c:z3", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"
udev-Konfigurations-Verzeichnisse¶
Die Konfiguration von udev wird aus diesen Verzeichnissen gelesen:
/lib/udev/rules.d/ (Regeln,, die mit dem Paket installiert werden)
/usr/local/lib/udev/rules.d/ (sofern existent – bei Ubuntu nicht)
/run/udev/rules.d/ (temporär bis zum Neustart)
/etc/udev/rules.d/ (eigene Regeln)
Beim Einlesen der Konfiguration maskieren gleichnamige Dateien einander. Ist also in einem späteren Verzeichnis eine Datei gleichen Namens vorhanden wie in einen vorherigen, so überschreibt die spätere Datei die vorherige.
Die Dateien werden in lexikographischer Reihenfolge abgearbeitet, allerdings nicht nach der deutschen. Deshalb sollte man auf deutsche Sonderzeichen in Dateinamen verzichten und die Dateien mit einer zweistelligen Zahlen 00 … 99 beginnen.
Möchte man die Regeln nach einem SUCHBEGRIFF durchsuchen, so kann man dieses folgendermaßen tun:
grep -r 'SUCHBEGRIFF' /{{,usr/local/}lib,run,etc}/udev/rules.d/
Eigene udev-Regeln¶
Sinn eigener Regeln¶
Standardmäßig werden Gerätenamen unter Linux "hochgezählt". So heißt z.B. der erste USB-Stick /dev/sdb, der zweite /dev/sdc. Das System kennt zunächst keinen Unterschied zwischen beiden Sticks. Das bringt einige Nachteile mit sich, wie folgende Beispiele zeigen:
Auf einer USB-Festplatte liegen .mp3-Dateien. Da die Platte immer anders eingebunden wird, wird die Sammlung vom Mediaplayer immer neu eingelesen.
Ein Gerät verschwindet plötzlich aus dem System, Gerätedateien wie z.B. /dev/cdrom funktionieren nicht mehr. Der Grund: SCSI-Geräte werden bei Fehlern einfach "hochgezählt" und fehlerhafte Gerätedateien verworfen. Ein zunächst als sr0 eingebundenes Gerät heißt nach einem Trennen der Verbindung ("disconnect") etwa sr1, und der zugehörige Verweis von /dev/cdrom auf /dev/sr0 ist dann nicht mehr verwendbar.
Ein Skript soll von oder zu einem Laufwerk kopieren (z.B. bei der Datensicherung oder beim Kopieren von SD-Karten), ohne von der Gerätebezeichnung abhängig zu sein.
Durch die Verwendung eigener Regeln ist es möglich, Geräte mit eindeutig zugeordneten Gerätenamen im Dateisystem einzubinden (siehe Erstellen eigener Regeln). Durch die umfangreichen Möglichkeiten von udev lässt sich auch erreichen, dass beim Anstecken eines Gerätes ein Skript ausgeführt wird. Das kann z.B. sehr hilfreich für die Datensicherung sein (siehe Automatischer Start eines Skripts).
Hinweis:
Man unterscheidet das Einbinden von Geräten vom Einhängen eines Dateisystems. Dateisysteme auf externen (USB-)Geräten werden standardmäßig mit dem Partitionsnamen (Label) oder der UUID in das Verzeichnis /media eingehängt - unabhängig vom Gerätenamen. Dadurch wird zwar eine gewisse Eindeutigkeit in der Verzeichnisstruktur gewährleistet, die aber bei einer Neuformatierung des Datenträgers wieder verlorengeht.
Im Gegensatz dazu kümmern sich udev-Regeln zuerst um das Einbinden des Geräts mit einem eindeutigen Namen in das Verzeichnis /dev/. Sie können sich dazu an Kriterien orientieren, die fester und eindeutiger an das Gerät gebunden sind.
Beispiele für eigene Regeln¶
Es wird für eine USB-Festplatte mit der Seriennummer
ABCDEF012345
die Gerätedatei /dev/musik als Symlink erzeugt:# Beispiel 1: USB HDD Musik KERNEL=="sd?1", SUBSYSTEMS=="usb", ATTRS{serial}=="ABCDEF012345", SYMLINK+="musik"
Für ein externes USB-DVD-Laufwerk mit der Modellbezeichnung "
DVD-ROM GDR8163B
" wird der Gerätenamen /dev/dvd-rom-lg als Symlink erzeugt:# Beispiel 2: externes LG DVD-ROM KERNEL=="sr?", SUBSYSTEMS=="usb", ATTRS{model}=="DVD-ROM GDR8163B", SYMLINK+="dvd-rom-lg"
Ein USB-Stick, der die Herstellernummer "
0204
" und die Produktnummer "0275
" übermittelt, wird als /dev/usbstick erzeugt und ein Skript /usr/local/bin/usbstick-backup gestartet:# Beispiel 3: USB-Stick für Backups KERNEL=="sd?1", SUBSYSTEMS=="usb", ATTRS{idVendor}=="0204", ATTRS{idProduct}=="0275", SYMLINK+="usbstick", ACTION=="add", RUN+="/usr/local/bin/usbstick-backup"
Ein Mobilgerät am USB-Port wird für den Zugriff als normaler Benutzer freigeschaltet. Das erleichtert eine Synchronisierung:
# Beispiel 4: Handy SUBSYSTEMS=="usb", ATTRS{serial}=="123456789123456789", OWNER="benutzername"
Eine Tastatur, mit der Herstellernummer "
046d
" und die Produktnummer "c519
" aktiviert/deaktiviert Numlock, beim ein/ausstecken [1] :# Beispiel 5: Numlock # <BENUTZERNAME> muss angepasst werden und das Packet numlockx installiert sein ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c519", ACTION=="add", RUN+="/bin/su <BENUTZERNAME> -c 'DISPLAY=:0 /usr/bin/numlockx on'" ENV{ID_VENDOR_ID}=="046d", ENV{ID_MODEL_ID}=="c519", ACTION=="remove", RUN+="/bin/su <BENUZTERNAME> -c 'DISPLAY=:0 /usr/bin/numlockx off'"
Eine Webcam, mit der Herstellernummer "
046d
" und die Produktnummer "082d
" konfigurieren [2] :# Beispiel 6: Webcam konfiguration SUBSYSTEM=="video4linux", SUBSYSTEMS=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="082d", PROGRAM="/usr/bin/v4l2-ctl --set-ctrl brightness=128 --device /dev/%k"
Erstellen eigener udev-Regeln¶
Hier wird die Erstellung eigener udev-Regeln am Beispiel einer USB-Festplatte und eines externen USB-DVD-Laufwerks erklärt. Die Aufgabe ist, die USB-Festplatte beim Einschalten oder Anstecken automatisch einzubinden und ein Backup-Skript zu starten, um bequem eine Datensicherung durchzuführen. Die Aufgabe für das DVD-Laufwerk ist simpler. Letztlich geht es darum, dass das Gerät immer unter einem spezifischen Gerätenamen verfügbar ist.
Auslesen von Informationen¶
Zunächst müssen möglichst eindeutige Informationen über das jeweilige Gerät ausgelesen werden.
Als Kriterien für eine udev-Regel empfiehlt sich insbesondere:
Die Laufwerksverwaltung (falls vorhanden und nicht
NULL
) kann mit dem Programm Laufwerksverwaltung ermittelt werden.Die Kombination aus Herstellerkennung und Produktkennung.
Die Kombination aus Hersteller und Modellbezeichnung.
Informationen kann man auf mehrerlei Weise sammeln. Je nachdem, um was für ein Gerät es sich handelt (und wie es angeschlossen wurde), eignen sich hierfür unterschiedliche Werkzeuge. Als Universalwerkzeug kann udevadm eingesetzt werden.
Daten über ein USB-Gerät herausfinden mit lsusb¶
Zunächst die USB-Festplatte: Zuerst sollte man das Gerät anstecken oder einschalten. Standardmäßig wird das Dateisystem dabei automatisch eingehängt, was sich mit mount
[4] überprüfen lässt.
mount
Gekürzte Ausgabe:
/dev/sdb1 on /media/EE80-57H2
Die Partition wurde als /dev/sdb1 eingebunden, das Dateisystem ist unter /media/EE80-57H2 eingehängt.
Jetzt führt man folgenden Befehl aus:
lsusb
Die Ausgabe sieht dann in etwa wie folgt aus:
Bus 005 Device 036: ID 04b4:6830 Cypress Semiconductor Corp. USB-2.0 IDE Adapter Bus 005 Device 033: ID 144d:c019 Bus 005 Device 001: ID 0000:0000 Bus 001 Device 001: ID 0000:0000 Bus 003 Device 001: ID 0000:0000 Bus 004 Device 001: ID 0000:0000 Bus 002 Device 001: ID 0000:0000
Anhand der Bus-Nummer und der Device-Nummer fragt man jetzt mit der Option -v
detailliertere Informationen über das Gerät ab:
sudo lsusb -vs 005:036
Bus 005 Device 013: ID 04b4:6830 Cypress Semiconductor Corp. USB-2.0 IDE Adapter Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 0 (Defined at Interface level) bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 idVendor 0x0ab4 Cypress Semiconductor Corp. idProduct 0x685a USB-2.0 IDE Adapter bcdDevice 0.01 iManufacturer 56 Cypress Semiconductor iProduct 78 USB2.0 Storage Device iSerial 100 ABCDEF012345 bNumConfigurations 1
Interessant sind vor allem die Zeilen idVendor
, idProduct
und iSerial
, da sich ihre Werte wegen ihrer Eindeutigkeit relativ gut für eine udev-Regel verwenden lassen. Mit diesen Angaben lassen sich bereits funktionierende Bedingungen für eine eigene udev-Regel bauen. Weiter mit udev-Regel schreiben und speichern.
Daten über beliebige Geräte auslesen mit udevadm¶
SCSI- oder andere Geräte können eine andere Vorgehensweise nötig machen. Dazu verwendet man Angaben aus der Logdatei /var/log/syslog. Dort werden am Ende die Protokoll-Einträge des Kernels angezeigt. Mit dem Befehl:
tail -f /var/log/syslog
lassen sich die letzten zehn Zeilen aus der Logdatei beobachten. Wie oben sollte man jetzt das Gerät - einen Scanner, ein SCSI-Laufwerk, ein Mobiltelefon oder eine Kamera - anstecken oder einschalten. Wenn die Erkennung des Gerätes nach ein paar Sekunden abgeschlossen ist, kann man die Ausgabe mit Strg + C abbrechen.
Eine Beispielausgabe für ein externes USB-DVD-Gerät, welches als SCSI-Gerät erkannt wird, zeigt, was nach dem Einstecken passiert:
[51755.613225] usb 4-1: new high speed USB device using ehci_hcd and address 16 [51755.754296] usb 4-1: configuration #1 chosen from 1 choice [51755.766872] scsi13 : SCSI emulation for USB Mass Storage devices [51755.767872] usb-storage: device found at 16 [51755.767880] usb-storage: waiting for device to settle before scanning [51760.764575] usb-storage: device scan complete [51760.769702] scsi 13:0:0:0: CD-ROM HL-DT-ST DVD-ROM GDR8163B 0L23 PQ: 0 ANSI: 0 [51760.790142] sr1: scsi3-mmc drive: 52x/52x cd/rw xa/form2 cdda tray [51760.790274] sr 13:0:0:0: Attached scsi CD-ROM sr1 [51760.790372] sr 13:0:0:0: Attached scsi generic sg1 type 5
Wie man sieht, wurde ein externes CD-ROM-USB-Laufwerk eingesteckt, das jedoch als SCSI-Gerät erkannt und geführt wird: sr1. Eine Kontrolle im /dev/-Verzeichnis zeigt die Existenz des neuen Gerätes /dev/sr1:
ls -l /dev/sr1
Nun kann man mit dem Gerätenamen /dev/sr1 genaue Informationen darüber finden, mit welchen Attributen das Gerät im System geführt wird. Diese Attribute können später 1:1 für eine udev-Regel verwendet werden. Die Eingabe des Befehls:
udevadm info --query=all --attribute-walk --name=/dev/sr1
führt meist zu einer sehr langen Ausgabe. Es ist jedoch mit ein wenig Fantasie möglich, die Spreu vom Weizen zu trennen. Die Ausgabe beginnt beim angegebenen Block-Device (in diesem Fall beim Dateisystem /dev/sr1). Anschließend folgen alle beteiligten "Elternsysteme" in aufsteigender Reihenfolge. Dies können z.B. sein
einzelne Partitionen des Gerätes
einzelne Chipsätze, Controller
Adapter (z.B. USB auf SATA) oder Lesegeräte
Subsysteme, wie verschiedene USB Systeme (1.0, 1.1, 2.0, 3.0)
Linux-Treiber (z.B.
ehci_hcd
)
Für jedes dieser Geräte werden alle Attribute ausgegeben, die in udev-Regeln verwendet werden können. Die Ausgabe der beteiligten Elternsysteme erfolgt blockweise. Jeder Block beginnt mit:
looking at ...
Der erste Ausgabeblock für das obige Gerät lautet z.B.:
looking at device '/block/sr1': KERNEL=="sr1" SUBSYSTEM=="block" [...]
Jetzt sucht man sich ein Elternsystem, das möglichst eindeutige Attribute für das Gerät enthält. In diesem Fall ist das bereits der nächste Ausgabeblock:
looking at parent device '/devices/pci0000:00/[...gekürzt]': [...] SUBSYSTEMS=="scsi" [...] ATTRS{model}=="DVD-ROM GDR8163B" ATTRS{vendor}=="HL-DT-ST" [...]
Hier nimmt man die Modellnummer (ATTRS{model}
), um das DVD-Laufwerk als solches eindeutig zu erkennen. Der Unterschied zur Methode mit lsusb
ist, dass man dies für beliebige Geräte anwenden kann und direkt die Attributnamen (ATTRS{...
) für die Erstellung der udev-Regeln verwenden kann. Beliebt ist auch die Seriennummer des Gerätes, meist ATTRS{serial}
.
Hinweis:
Eine Kombination von Attributen aus mehreren Elternsystemen in einer udev-Regel ist nicht möglich. Es können aber problemlos Attribute aus einem Elternsystem mit Attributen des eigentlichen Geräts zu einer Bedingung kombiniert werden, was im Beispiel auch gemacht wird.
Alternativen¶
Als Alternative zu o.g. Methoden gibt es noch
udevadm monitor --property
Da die Ausgabe aber nicht zwischen Gerät und Elternsystem unterscheidet, empfiehlt sich die Verwendung nur für routinierte Autoren von udev-Regeln.
udev-Regel schreiben und speichern¶
Eigene udev-Regeln erstellt man in einem Editor mit Root-Rechten[3] und legt sie im Verzeichnis /etc/udev/rules.d/ ab. Um sicher zu gehen, dass die eigenen Regeln nicht anschließend von Systemstandards überschrieben werden, sollte man den Dateinamen mit einer hohen Zahl oder ohne Zahl beginnen. Wichtig ist, dass die Dateien, die die Regeln enthalten, mit .rules enden, da sie sonst nicht ausgeführt werden. Es ist vorteilhaft für spätere Änderungen, nicht mit Kommentaren zu sparen. Beispiel:
# USB-Festplatte für Backups
Nun geht es an das eigentliche Erstellen der udev-Regel aus den oben ermittelten Werten. Zuerst nimmt man die KERNEL
-Information des Geräts selbst (also sdb1
oder sr1
). Da man ja will, dass die Regel auch bei anderer Nummerierung durch den Kernel zutrifft (z.B. sdc1
oder sr2
), sieht der erste Eintrag so aus:
KERNEL=="sd?1"
bzw.
KERNEL=="sr?"
Jetzt kombiniert man diesen Eintrag mit den ermittelten Werten aus einem Elternsystem (Wurde die Abfrage mit lsusb
gemacht, nimmt man einfach die ermittelten Werte und fügt sie wie folgt ein):
KERNEL=="sd?1", SUBSYSTEMS=="usb", ATTRS{serial}=="Hier Serialnummer einfügen"
Ist die iSerial
nicht gesetzt, kann man die Erkennung auch alternativ über idProduct
machen:
KERNEL=="sd?1", SUBSYSTEMS=="usb", ATTRS{idProduct}=="685a"
Oder über idVendor
:
KERNEL=="sd?1", SUBSYSTEMS=="usb", ATTRS{idVendor}=="0ab4"
Oder über eine Kombination aus beiden:
KERNEL=="sd?1", SUBSYSTEMS=="usb", ATTRS{idVendor}=="0ab4", ATTRS{idProduct}=="685a"
Damit hat man bereits eindeutige Bedingungen für das Gerät definiert. Nun folgt die Zuweisung, hier der zusätzliche Gerätename in /dev:
KERNEL=="sd?1", SUBSYSTEMS=="usb", ATTRS{serial}=="ABCDEF012345", SYMLINK+="backup"
Das Gerät steht dann künftig unter /dev/backup zur Verfügung.
Hinweis:
In den Standardregeln wird die Zuweisung für eine Gerätedatei oft mit dem Schlüssel NAME
erzeugt. Dies verleitet möglicherweise dazu, in eigenen Regeln NAME="backup"
zu schreiben. udev sieht aber insgesamt nur eine Zuweisung für ein Gerät über NAME
vor. Im Zweifelsfall sollte deshalb der Schlüssel SYMLINK
verwendet werden, da hier mehrere Zuweisungen pro Gerät möglich sind (deshalb auch der Operator +=
). So wird ein Konflikt mit einer NAME
-Zuweisung in einer Standardregel vermieden.
Mit der gleichen Methode wird die Regel für das externe DVD-Laufwerk erstellt (zweites Beispiel der Einführung). Zur näheren Bestimmung werden lediglich das Subsystem "scsi
" und der Attributwert "model
" verwendet. Dies genügt zur eindeutigen Bestimmung.
# LG DVD-ROM KERNEL=="sr?", SUBSYSTEMS=="scsi", ATTRS{model}=="DVD-ROM GDR8163B", SYMLINK+="dvd-rom-lg"
Abschließend muss die Datei gespeichert werden, z.B. als /etc/udev/rules.d/70-usb-storage-custom.rules. Ein paar Richtlinien, nach denen man die Zahl am Anfang aussuchen sollte, finden sich in der Datei /etc/udev/rules.d/README.
Automatischer Start eines Skripts¶
Man kann über udev ein Skript automatisch starten lassen, wenn ein Gerät erkannt wird. Hierzu werden der udev-Regel zwei weitere Punkte hinzugefügt:
Der Punkt
ACTION=="add"
sorgt dafür, dass die Regel nur zutrifft, wenn das Gerät neu angeschlossen wird, und sollte nach Möglichkeit verwendet werden:KERNEL=="sd?1", SUBSYSTEMS=="usb", ATTRS{serial}=="ABCDEF012345", SYMLINK+="backup", ACTION=="add", RUN+="/usr/local/bin/backup"
Der Punkt
RUN+="/usr/local/bin/backup"
ruft das Skript /usr/local/bin/backup auf. Dabei muss darauf geachtet werden, dass das Skript mit vollständiger Pfadangabe aufgerufen wird. Dem PunktRUN
kann immer nur ein einzelner Befehl (mit Parametern) übergeben werden. Allerdings lassen sich über mehrereRUN+="..."
-Einträge mehrere Befehle hintereinander ausführen:KERNEL=="sd?1", SUBSYSTEMS=="usb", ATTRS{serial}=="ABCDEF012345", SYMLINK+="backup", ACTION=="add", RUN+="/usr/bin/logger Starte Backup.", RUN+="/usr/local/bin/backup"
In obigem Beispiel wird nach dem Anstecken der Festplatte zuerst die Zeile "Starte Backup." mit logger in das Systemprotokoll geschrieben und danach das Skript /usr/local/bin/backup gestartet. Voraussetzung ist eine gültige Shebang-Zeile. Dabei muss es sich selbst um das korrekte Einbinden kümmern:
1 2 3 4 | #!/bin/bash mkdir /media/backup mount /dev/backup /media/backup ... |
Achtung!
Mit RUN+=
kann man allerdings keine lang laufende Prozesse starten, weil solche automatisch gekillt werden. Das zuverlässige Einbinden von Dateisystemen und Durchführen von Backups kann man so nicht realisieren!
udev-Regel für das Entfernen eines Gerätes¶
Eine Regel, die beim Anschließen des Gerätes funktioniert, wird in der Regel beim Entfernen des Geräts nicht funktionieren, wenn man nur den Wert des Schlüssels ACTION
von "add" auf "remove" ändert. Das liegt daran, dass auf die Speicherbereiche des Gerätes, in denen die Signaturen gespeichert sind, nicht mehr zugegriffen werden kann, da das Gerät ja nicht mehr vorhanden ist. Daher muss hier ein anderer Ansatz gewählt werden, um das entfernte Gerät dennoch zu identifizieren. Udev speichert zu jedem Gerät Informationen in den Environment-Variablen. Diese kann man mit dem Befehl:
udevadm monitor --env
überwachen. Wenn man jetzt das Gerät entfernt, kann man die Ausgabe nach den bekannten Werten für die Identifikation untersuchen. In folgender Tabelle sind beispielhaft einander entsprechende Ausgaben von lsusb -sv xxxx:yyyy
und udevadm monitor --env
gegenübergestellt.
Ausgaben der beiden Befehle, die einander entsprechen | |
lsusb -sv | udevadm monitor --env |
idVendor 0x0ab4 Cypress Semiconductor Corp. | ID_VENDOR_ID=0ab4 |
idProduct 0x685a USB-2.0 IDE Adapter | ID_MODEL_ID=685a |
iSerial 100 ABCDEF012345 | ID_SERIAL_SHORT=ABCDEF012345 |
Die oben beschriebene Regel zum Ausführen eines Skripts beim Hinzufügen wäre dann für das Entfernen folgendermaßen anzupassen:
ACTION=="remove", ENV{ID_SERIAL_SHORT}=="ABCDEF012345", RUN+="/usr/local/bin/remove"
Die gesamte Ausgabe beim Entfernen des Gerätes kann mehrere hundert Zeilen umfassen, und bietet unter Umständen deutlich mehr Möglichkeiten zur eindeutigen Identifzierung. Falls das Gerät keine Seriennummer hat, gibt es z.B. Variablen für UUID, Dateisystem und Label. Auch können hier der Variablenname und der zugehörige Wert 1:1 übernommen werden, was bei der Abfrage mit lsusb
nicht immer der Fall ist. Die Environment-Variablen lassen sich natürlich auch beim Anstecken des Geräts nutzen.
Neustart des udev-Systems¶
Ein Neustart von udev ist eigentlich nicht erforderlich, da udev beim Anschließen eines neuen Gerätes automatisch die Regeln im Verzeichnis /etc/udev/rules.d/ durchgeht. Wurde die Regel für entfernbare Geräte erstellt, können diese einfach entfernt und wieder eingesteckt werden. Wurden dagegen Regeln für fest eingebaute Geräte (z.B. PCI-Karten) festgelegt, muss udev aber dazu veranlasst werden, alle Geräte neu einzulesen. Dies geschieht mittels:
sudo udevadm trigger
Falls es dennoch notwendig sein sollte, udev neu zu starten, verwendet man den Befehl:
sudo systemctl restart systemd-udevd.service
Funktionstest¶
Ein Funktionstest ist recht einfach durchzuführen: Dazu muss man einfach die USB-Festplatte abziehen und neu anstecken. Ist dann eine Gerätedatei /dev/backup erstellt worden, hat alles geklappt. Wenn nicht, dann ist an der udev-Regel etwas falsch, und man sollte sie korrigieren. Dabei helfen verschiedene Werkzeuge.
Das System prüft eine udev-Regel in /etc/udev/rules.d/ sofort beim Speichern der Datei und protokolliert mögliche Fehler in /var/log/syslog. Es empfiehlt sich deshalb, die Log-Datei in einem Fenster mit tail -n 10 -f /var/log/syslog offen zu halten. Selbst auskommentierte Zeilen werden hier auf ihre Syntax geprüft, auch wenn sie nicht angewendet werden.
Hinweis:
Ein "beliebter" Fehler ist die Angabe des Operatorts *=
statt +=
, weil das +
als einziges Zeichen in der Kette ohne Umschalttaste eingegeben werden muss.
Als Universalwerkzeug kann man auch hier udevadm verwenden. Mit dem Befehl:
sudo udevadm test /sys/class/block/sdb1
lässt sich prüfen, welche Regeln und Attribute auf das Gerät sdb1 angewendet werden.
Hinweis:
Zu beachten ist hierbei aber, dass man als Parameter einen Eintrag im /sys/-Ordner angeben soll und nicht eine Gerätedatei aus dem /dev/-Ordner.
Möchte man nur wissen, welche Symlinks für ein Gerät existieren, kann man das z.B. mit dem Befehl:
sudo udevadm info --root --query=symlink --name=/dev/GERÄTEDATEI_ODER_SYMLINK
machen. Weitere Anwendungsmöglichkeiten findet man in der Manpage von udevadm.
Einhängen eines Dateisystems¶
Über den erstellten Symlink des Geräts kann ein Dateisystem wie gewohnt eingehängt[4] werden:
sudo mkdir EINHÄNGEPUNKT sudo mount SYMLINK EINHÄNGEPUNKT
Beispiel:
sudo mkdir /media/usb-backup sudo mount /dev/usb-backup /media/usb-backup
Für eine dauerhafte Lösung bietet sich das Einhängen per /etc/fstab[5] an.
Regelsyntax¶
Hier noch eine Übersicht möglicher Schlüssel. Eine vollständige Liste findet man in der Manpage von udev.
Vergleichsschlüssel, um Bedingungen zu definieren | ||
Schlüssel | Bedeutung | Beispiel |
ACTION | Gerät neu eingesteckt bzw. entfernt | ACTION=="add" , ACTION=="remove" |
KERNEL | Kernelname des Geräts | KERNEL=="block" |
KERNELS | Wert für den Kernelnamen des Elternsystems | KERNELS=="3:0:0:0" |
SUBSYSTEM | Subsystem des Geräts | SUBSYSTEM=="block" |
SUBSYSTEMS | Subsystem des Elternsystems | SUBSYSTEMS=="usb" |
ATTRS | SYSFS-Attribut des Elternsystems | ATTRS{model}=="WDC WD20EARS-07M" , ATTRS{vendor}=="WD" , ATTRS{serial}=="AEFHSSK768KJH" |
Zuweisungsschlüssel | |||
Schlüssel | Bedeutung | Verwendung | Hinweis |
NAME | definiert den NAMEN des Geräts in /dev | NAME="eth0" | Darf nur einmal pro Gerät vergeben werden. Die Vergabe von eigenen Namen mit NAME= ist nur für Netzwerkschnittstellen eth* sinnvoll. Bis Ubuntu 13.04 könnnen zwar auch andere Geräte noch umbenannt werden, dies führt aber zu Inkonsistenzen mit dem Kernel. Daher unterstützt Ubuntu ab 13.10 nur noch das das Umbenennen von eth*-Geräten. |
SYMLINK | definiert einen Symlink für das Gerät in /dev | SYMLINK+="usb-backup" | Kann mit dem Operator += mehrfach verwendet werden. |
OWNER , GROUP , MODE | definiert Rechte für das Gerät | OWNER="users" | Ein angegebener Wert überschreibt den bisher definierten. |
RUN | startet ein Skript oder ein Programm | RUN+="/usr/local/bin/backup" | Verlangt den absoluten Pfad des Skripts, sollte zusammen mit ACTION=="add" verwendet werden. Wenn das Skript auf das neu hinzugefügte Gerät zugreifen soll, muss dieses vorher eingehängt werden. |
Operatoren | |||
Operator | Typ | Bedeutung | Hinweis |
== | Vergleichsoperator | prüft, ob der angegebene Schlüssel dem Wert entspricht | alle Kriterien müssen erfüllt sein, damit eine Regel ausgeführt wird |
!= | Vergleichsoperator | prüft, ob der angegebene Schlüssel dem Wert nicht entspricht | alle Kriterien müssen erfüllt sein, damit eine Regel ausgeführt wird |
= | Zuweisungsoperator | weist einem Schlüssel einen Wert zu | alle Werte, die bisher für diesen Schlüssel definiert wurden, werden ignoriert |
+= | Zuweisungsoperator | weist einem Schlüssel einen Wert hinzu | mehrere Werte pro Schlüssel möglich |
:= | Zuweisungsoperator | weist einem Schlüssel einen Wert zu | lässt ab sofort keine Änderungen an diesem Schlüssel mehr zu |
Weitere Befehle rund um udev¶
Den udev-Dienst starten/stoppen oder den Status anzeigen:
sudo systemctl status udev sudo systemctl stop udev sudo systemctl start udev
Zeigt Kernel-Events:
udevadm monitor --kernel udevadm monitor --udev
Problembehebung¶
Probleme mit einigen Digitalkameras¶
Es kann sein, dass eine Kamera nicht als Massenspeichermedium erkannt wird, aber über Gphoto2 🇬🇧 zugänglich ist. In diesem Fall erfolgt der Zugriff durch normale ("Userspace") Programme anstatt über einen Kernel-Treiber. Das Problem daran ist vor allem, dass die erwähnten Kernel-Namen in diesem Fall nicht funktionieren, da die Kamera ja kein Block-Device ist. Siehe auch Kamera via PTP einbinden.
Tipps und Tricks¶
Die Ausgabe von lsusb -vs BUS_NAME:DEVICE_NAME ist leer¶
Wenn mit lsusb
das gewünschte Gerät angezeigt wird, die Ausgabe von lsusb -vs BUS_NAME:DEVICE_NAME
aber leer bleibt, liegt das wahrscheinlich daran, dass das Gerät nicht eingehängt ist. Möglicherweise wurde das Gerät zwar bereits eingehängt, hat sich aber in den Ruhezustand verabschiedet. In diesem Fall empfiehlt es sich, das Gerät ab- und wieder anzustecken. Dadurch ändert sich aber die Device-Nummer, sodass lsusb
erneut ausgeführt und die neue Nummer zur Abfrage durch lsusb -vs BUS_NAME:DEVICE_NAME
verwendet werden muss.
Partition mit Windows ausblenden¶
Manche Nutzer haben neben Ubuntu noch eine Partition (hier /dev/sda1) mit Windows. Diese Partition wird in Nautilus und unter "Orte" ständig angezeigt, obwohl man sie evtl. gar nicht braucht.
Mit Hilfe der folgenden Regel kann die Partition leicht ausgeblendet werden.
KERNEL=="sda1", ENV{UDISKS_IGNORE}="1"
Links¶
intern¶
usbauth - USB-Firewall, die Angriffe über präparierte USB-Geräten unterbinden kann
extern¶
Writing udev rules 🇬🇧 - gut erklärt und mit Beispielen
Create your own udev rules to control removable devices 🇬🇧 - Ubuntuforums.org, 04/2006
Geräteschuppen - udev & Co 🇩🇪 - LinuxUser, 12/2007 (teilweise veraltet)
udev-notify 🇬🇧 - grafische Benachrichtigungen beim Anschluss externer Geräte anzeigen
udev wird Bestandteil von Init-System Systemd 🇩🇪 - heise Open Source, 04/2012
Logitech Harmony Fernbedienung - Praxisbeispiel für die Hardware-Erkennung mittels udev