Udev verstehen und eigene Regeln erstellen

Aus LinuxUser 05/2019

Udev verstehen und eigene Regeln erstellen

© twinsterphoto, 123RF

Unsichtbarer Helfer

Udev verwaltet sowohl fest verbaute als auch ansteckbare Geräte – in der Regel ohne Ihr Zutun. Bei Bedarf tanzt der Daemon aber auch nach Ihrer Pfeife.

Geht es um das An- und Abstecken von Geräten im laufenden Betrieb, taucht unter Linux häufig der Begriff Udev auf. Er steht für Userspace /dev und bezeichnet einen Dienst, der im Hintergrund die Gerätedateien unter /dev dynamisch verwaltet.

Bis zum 2003 veröffentlichten Kernel 2.6 zeichnete das Devfs-Dateisystem [1] für diese Aufgaben zuständig, zu dessen Nachteilen unter anderem das inkonsistente Benennen der Geräte gehörte. Es entfiel nach der Ablösung durch Udev 2006 aus dem Kernel.

Einer der beiden Autoren von Udev war der bekannte Kernel-Entwickler Greg Kroah-Hartman, einer von Linus Torvalds’ Kernel-Lieutenants. Der andere, der Red-Hat-Angestellte Kai Sievers, zählt auch zu den Entwicklern von Systemd. Bei Fedora zeichnete er federführend für die Zusammenführung der Verzeichnisse /lib, /bin und /sbin unter /usr verantwortlich, den sogenannten Usrmerge.

Seit Systemd 183 aus dem Jahr 2012 gehört Udev zu den Komponenten dieses Init-Systems. Eine Alternative zu Udev, die auch ohne Systemd funktioniert, bietet das bei Gentoo entwickelte Eudev, das beispielsweise bei Devuan zum Einsatz kommt.

Hot Plugging

Udev verwaltet das Verzeichnis /dev, in dem sich die Gerätedateien befinden. Sie erlauben es Programmen, auf die entsprechende Hardware zuzugreifen, wie unter anderem Mäuse, Tastaturen, externe Festplatten, Joysticks, Gamepads, Digitalkameras oder Laufwerke für optische Medien.

Dabei spielt es keine Rolle, ob die Devices bereits zur Boot-Zeit im System vorliegen. Sie können sie ebenso gut zur Laufzeit an Schnittstellen wie USB, PCMCIA, Firewire oder Bluetooth anschließen. An dieser Hot Plugging genannten Technik ist neben Udev auch D-Bus beteiligt, das die bei Udev vorliegenden Informationen über angeschlossene Geräte ausliest und sie dann an das Betriebssystem und die Programme weiterleitet. Falls nötig, lädt Udev auch die von den Geräten benötigte Firmware.

Udev überwacht Hotplug-Ereignisse und erstellt beim Anschluss eines neuen Geräts im Verzeichnis /dev eine zugehörige Gerätedatei mit Regeln und Rechten. Diese sogenannten Rules legen fest, was geschieht, sobald Udev das Gerät erkennt. Wie der ausgeschriebene Name Userspace /dev bereits verrät, handelt es sich bei Udev anders als beim Vorgänger Devfs nicht um ein Kernelmodul, sondern um ein Programm, das im Userspace [2] startet. Dadurch lassen sich die Regeln auch vom Anwender erstellen und bearbeiten.

Uevents

Das heißt aber nicht, dass Udev nicht mit dem Kernel zusammenarbeitet, denn der informiert das Tool erst über Hotplug-Events. Wann immer Sie ein Gerät mit dem Rechner verbinden, erkennt und initialisiert der Kernel es. Dazu erstellt er zunächst unter /sys ein Verzeichnis mit dem Gerätenamen, das die Geräteattribute enthält. Das erfolgt sowohl beim Booten des Rechners als auch beim Anstecken entsprechender Geräte zur Laufzeit.

Meldet der Kernel über ein sogenanntes Uevent ein Ereignis wie das An- oder Abstecken eines Geräts oder eine Änderung im Gerätestatus, sammelt der Daemon Systemd-Udevd zunächst alle verfügbaren Informationen darüber, indem er die Einträge in den Unterverzeichnissen von /sys durchforstet.

Jedes empfangene Geräteereignis vergleicht der Daemon mit den in /lib/udev/rules.d/ und /etc/udev/rules.d/ hinterlegten Regeln. Der überwiegende Teil davon liegt im Udev-Verzeichnis unter /etc, während das Verzeichnis unter /lib die von Systemd erstellten Rules enthält. Udev befolgt dann die passende Regel und erstellt einen Symlink von der internen UUID auf den Gerätenamen, setzt Berechtigungen, legt einen Einhängepunkt fest oder benennt das Gerät um.

Die Namen von Udev-Regeln verwenden als Präfix in der Regel eine Zahl und als Postfix die Erweiterung .rules. Udev arbeitet die Rules in der Reihenfolge der vorangestellten Zahl ab, unabhängig davon, in welchem der beiden Verzeichnisse sie liegen. Dateien in /etc/udev/rules.d/ besitzen eine höhere Priorität als gleichnamige Regeln im Standardpfad des Systems.

Versteht man erst einmal die Logik dahinter, gestaltet sich die Syntax von Udev-Rules vergleichsweise einfach. Jede Regel besteht aus zwei Hauptabschnitten. Der erste davon enthält mindestens eine Bedingung samt einer Reihe von Schlüsseln. Der zweite Abschnitt definiert die auszuführende Aktion und greift, sobald die Bedingung erfüllt ist.

Fester Einhängepunkt

Das Verwenden eigener Regeln ermöglicht es unter anderem, Geräte mit individuell vergebenen Gerätenamen ins Dateisystem einzubinden und den Einhängepunkt festzulegen. So taucht dann beispielsweise ein bestimmter USB-Stick in /media statt als XYz123 mit einem Namen wie mein_usb_stick auf.

Das ginge auch ohne Udev, doch der Daemon bietet noch wesentlich mehr Funktionen. So ermöglicht er es beispielsweise, einer Regel ein Skript oder Programm mitzugeben, das beim Anstecken des Geräts startet. Das erweist sich etwa bei der Datensicherung als sehr hilfreich.

Bevor es aber an das Erstellen eigener Rules geht, sollten Sie die bereits in /lib/udev/rules.d/ vorhandenen Regeln durchforsten. Möglicherweise finden Sie dort für das entsprechende Gerät einen passenden Regelsatz, der – eventuell um weitere Operatoren ergänzt – das tut, was Sie beabsichtigen. Den kopieren Sie sicherheitshalber zum Bearbeiten nach /etc/udev/rules.d: Jede Distributionsaktualisierung überschreibt gnadenlos alle editierten Regeln in /lib.

Eindeutige Merkmale

Nehmen wir als Beispiel den Fall zweier gleicher USB-Sticks, die statt mit Nummer oder inhaltsabhängiger Bezeichnung unter einem festen Namen auf demselben Mountpoint erscheinen sollen.

Nehmen wir an, der Befehl mount zeigt einen frisch formatierten USB-Stick als /dev/sda1 on /media/aef715bf-4edg-o5de-fr93h-dg93s7gh. Zunächst ermitteln Sie, wo das System den Stick einhängt. Verwendet das System den MBR, verrät das der Befehl lsblk (Abbildung 1); nutzt es stattdessen GPT, führt blkid zum Ziel (Abbildung 2). Dann werten Sie mit dem Befehl journalctl -f oder dmesg | grep -i usb die Ereignisse nach dem Anstecken des Geräts aus (Abbildung 3).

Als nützlich erweisen sich hier unveränderliche Merkmale wie die Seriennummer, die Kombination aus Hersteller- und Produktkennung in der Form idVendor=, idProduct= oder die Kombination von Product und Manufacturer. Bei baugleichen Geräten desselben Herstellers lassen diese sich die einzelnen Exemplare meist durch eine eindeutige Seriennummer unterscheiden.

Abbildung 1: Lsblk listet verfügbare Blockgeräte in einer Baumdarstellung auf, die es zuvor aus dem Sysfs-Dateisystem ausgelesen hat.

Abbildung 1: Lsblk listet verfügbare Blockgeräte in einer Baumdarstellung auf, die es zuvor aus dem Sysfs-Dateisystem ausgelesen hat.


Abbildung 2: Im Gegensatz zu Lsblk führt Blkid nur Geräte mit einer gültigen Partitionstabelle auf, zeigt dafür aber mehr Informationen.

Abbildung 2: Im Gegensatz zu Lsblk führt Blkid nur Geräte mit einer gültigen Partitionstabelle auf, zeigt dafür aber mehr Informationen.


Abbildung 3: Dmesg dient zur Ausgabe der Meldungen des Kernel-Ringpuffers. Es gibt beim Anstecken eines Geräts die verfügbaren Informationen aus.

Abbildung 3: Dmesg dient zur Ausgabe der Meldungen des Kernel-Ringpuffers. Es gibt beim Anstecken eines Geräts die verfügbaren Informationen aus.

Gleich einsatzbereit

Eine andere Methode führt über den Befehl udevadm (Abbildung 4), mit dem sich die Angaben eins zu eins in die zu erstellende Regel einbauen lassen. In unserem Beispiel führt folgender Befehl zum Ziel:

$ udevadm info --attribute-walk --name=/dev/sda1

Die Ausgabe unterteilt sich zwar in recht lange Blöcke, doch meist genügt der erste oder zweite davon, um die benötigten Angaben zu erhalten. Fehlen Ihnen Informationen zum Gerät, tippen Sie vor dessen Anstecken udevadm monitor ein (Abbildung 5).

Finden Sie im ersten Block nicht genügend Informationen, verwenden Sie die aus einem der darunter gestaffelten Elternblöcke. Das Mischen von Informationen aus mehreren Elternblöcken in einer Regel unterstützt Udev nicht. Verwenden Sie Attribute aus Elternblöcken, wird ein S an die Operatoren angehängt. So wird aus KERNEL dann KERNELS, aus ATTR ein ATTRS.

Abbildung 4: Sobald Sie den Mountpoint kennen, gibt das Udevadm die für eine Udev-Regel benötigten Informationen preis.

Abbildung 4: Sobald Sie den Mountpoint kennen, gibt das Udevadm die für eine Udev-Regel benötigten Informationen preis.


Abbildung 5: Fehlen Informationen zu einem Device, hilft <code>udeavdm monitor</code> weiter. Das Kommando zeigt nach dem Einstecken des Devices in Echtzeit Informationen dazu an. Allerdings l&auml;sst sich die Ausgabe schwerer deuten als bei Udevadm.

Abbildung 5: Fehlen Informationen zu einem Device, hilft udeavdm monitor weiter. Das Kommando zeigt nach dem Einstecken des Devices in Echtzeit Informationen dazu an. Allerdings lässt sich die Ausgabe schwerer deuten als bei Udevadm.

Einfache Regeln

Nach dem Untersuchen beider Sticks kennen Sie jetzt (im besten Fall) die zwei Seriennummern, über die sie sich eindeutig identifizieren lassen. Nun geht es anhand der Ausgabe von udevadm info an das Erstellen einer einfachen Udev-Regel mit dem Ziel, jedem der USB-Sticks einen individuellen Namen zu geben und ihnen stets denselben Einhängepunkt zuzuweisen.

Dass die Einhängepunkte nicht konsistent sind, liegt übrigens an einer Eigenart von Udev selbst: Es lädt Kernel-Module asynchron und damit in willkürlicher Reihenfolge, weil das meist schneller geht als das serielle Laden der Module.

Fassen wir zusammen, was Sie vor dem Erstellen einer Regel für einen USB-Stick tun müssen: Der Befehl blkid verrät, dass das System den Stick als /dev/sda1 einhängt. Daraufhin zeigt udevadm info --name=/dev/sda1 die weiteren benötigten Informationen. In unserem Fall, bei einem USB-Stick von Sandisk, stehen alle benötigten Daten bereits im ersten Block.

Wenn das nicht ausreicht, erweitern Sie den Aufruf um den Parameter --attribute-walk. Er listet alle Eigenschaften des angegebenen Geräts aus Sysfs, die sich in Udev-Regeln für das Gerät verwenden lassen. Das reicht von den übergeordneten Geräten bis hinunter zur Wurzel von Sysfs, jeweils in separaten Blöcken, und schließt mitunter einzelne Partitionen, Chipsätze, Controller und USB-Subsysteme bis hinunter zum Linux-Treiber mit ein.

Um den Stick eindeutig zu identifizieren, verwenden Sie die Informationen zu KERNEL, SUBSYSTEM, Attr{ID_Vendor_ID} und Attr{ID_Serial_Short}. Daraus erstellen Sie die Regel aus Listing 1.

Listing 1

KERNEL=="sd?1", SUBSYSTEM=="block", ATTR{ID_VENDOR_ID}=="0781", ATTR{ID_SERIAL_SHORT}=="4C530001080716117381", OWNER="ft", SYMLINK+="music"

Sie sorgt dafür, dass Udev den Stick künftig unter /media als music mountet und dem User ft volle Zugriffsrechte einräumt. Wenn Sie nun den Stick anstecken, sehen Sie mit ls /dev/m* -la, wie Udev ihn eingehängt hat (Abbildung 6).

Abbildung 6: Mit dem Befehl <code>ls /dev/m* -la</code> &uuml;berpr&uuml;fen Sie, ob die erstellte Regel das Ger&auml;t richtig einh&auml;ngt.

Abbildung 6: Mit dem Befehl ls /dev/m* -la überprüfen Sie, ob die erstellte Regel das Gerät richtig einhängt.

In unserem Beispiel legen Sie die Regel in der Textdatei 10-my.rules unter /etc/udev/rules.d/ an. Das Kommando udevadm control --reload lädt sie anschließend neu. Die 10 im Namen sorgt dafür, dass Udev die Regel früh ausführt. Das wiederum verhindert, dass Standardregeln aus /etc/udev/rules.d/50-udev.rules sie übergehen. Sollte die Regel nicht funktionieren, machen Sie sicherheitshalber einen Neustart, bevor Sie weitere Untersuchungen anstellen.

Möchten Sie beim Anstecken eines USB-Sticks ein Programm oder ein Skript ausführen, fügen Sie bei den Bedingungen ACTION=="add" hinzu. Am Ende der Regel ergänzen Sie RUN="/Pfad/Skript" und geben so den absoluten Pfad zum gewünschten Programm oder Skript an. Die so ergänzte Regel sollte eine Bezeichnerzahl zwischen 80 und 90 erhalten.

Möchten Sie auf einem System ohne Systemd eine neue Netzwerkkarte oder ein WLAN-Modul mit einem persistenten Bezeichner ausstatten, sieht eine generische Regel dazu so aus wie in Listing 2 zu sehen. Die benötigte MAC-Adresse verrät der Befehl ip addr. Die Regel lässt sich in der Datei /etc/udev/rules.d/70-persistent-net.rules anpassen oder eintragen.

Listing 2

SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="hier MAC eingeben", ATTR{dev_id}=="0x0 eingeben", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"

Dokumentation

Dieser Artikel beleuchtet die grundlegenden Konzepte und die Logik zum Erstellen einer Udev-Regel, kratzt aber nur an der Oberfläche der vielen Optionen und möglichen Einstellungen auf allen möglichen Geräten. Eine Auflistung sämtlicher Operatoren finden Sie bei Freedesktop.org [3], im deutschen Wiki von Arch Linux [4] finden Sie weiterführende Informationen und Verweise. Weitere gute Quellen liefern die Manpages von Udev und Udevadm.

Fazit

Bei Udev handelt es sich um ein mächtiges Werkzeug. Für die Mühe, sich einzuarbeiten und selbst Regeln zu erstellen, winkt als Lohn mehr Kontrolle über das System. Allerdings sollten Sie dabei den Sicherheitsaspekt nicht aus den Augen verlieren. Das Ausführen eines Skripts, das automatisch ein Backup auf ein angestecktes USB-Gerät vornimmt, eignet sich beispielsweise nicht für ein Notebook, an das Dritte im Büro oder auf Konferenzen zugreifen könnten. 

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDF
LinuxUser 05/2019 KAUFEN
EINZELNE AUSGABE
ABONNEMENTS
TABLET & SMARTPHONE APPS
E-Mail Benachrichtigung
Benachrichtige mich zu:

Hinweis: Dieser Artikel ist älter als ein Jahr, enthaltene Informationen sind möglicherweise veraltet.

0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben