staging.inyokaproject.org

udev

Dieser Artikel wurde für die folgenden Ubuntu-Versionen getestet:


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+= prinzipiel nicht!

Artikel für fortgeschrittene Anwender

Dieser Artikel erfordert mehr Erfahrung im Umgang mit Linux und ist daher nur für fortgeschrittene Benutzer gedacht.

./udev_logo.png 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' /{{,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:

  1. 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"
  2. 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 Punkt RUN kann immer nur ein einzelner Befehl (mit Parametern) übergeben werden. Allerdings lassen sich über mehrere RUN+="..."-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 reload udev 

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 1x 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_PRESENTATION_HIDE}="1"

intern

  • usbauth - USB-Firewall, die Angriffe über präparierte USB-Geräten unterbinden kann

extern

Diese Revision wurde am 6. März 2023 18:06 von kB erstellt.
Die folgenden Schlagworte wurden dem Artikel zugewiesen: Hardware, System