udev

Aus Mikiwiki
Zur Navigation springen Zur Suche springen

Mit dem Programm udev verwaltet der Kernel von Linux über den Hotplug-Mechanismus Gerätedateien für die Datenein- und -ausgabe (input/output). Es ersetzte ab dem Kernel 2.6 das früher genutzte Dateisystem devfs. Genauso wie devfs verwaltet udev das Verzeichnis "/dev", das die speziellen Gerätedateien enthält, um von Programmen aus auf die vom System zur Verfügung gestellten Geräte zuzugreifen.

Beim Anschliessen oder Entfernen eines Geräts signalisiert der Controller des jeweiligen Busses (ISA, PCI, USB) dies durch einen Interrupt. Als Reaktion auf diese Unterbrechung ermittelt der Kernel Einzelheiten über das neu hinzugekommene Gerät, indem er entweder den Hardware-Controller befragt oder an fest vorgegebenen Adressen (z. B. im Konfigurationsbereich von PCI-Karten) nach dort abgelegten Informationen sucht, insbesondere nach der Vendor- und der Product-ID des Geräts. Anschliessend legt er für das neue Gerät ein sogenanntes Kobject an, das die Verwaltungsinformationen aufnimmt, wobei er die Informationen über den Gerätetyp (zeichen- oder blockorientiert) und die Major- und Minor-Nummer über den mit Kernel 2.6 eingeführten globalen Namensraum für Kernelkomponenten erhält. Diese Information macht der Kernel dann seinerseits über das Sys-FS, das in diesem Punkt das alte procfs ablöst, auch anderen zugänglich. sysfs wird normalerweise nach "/sys" eingehängt.

Bei älteren udev-Versionen ruft der Kernel danach das in "/proc/sys/kernel/hotplug" eingetragene Programm auf (meist "/sbin/hotplug"), um Usermode-Programme über den neuen Gerätestatus zu informieren. Dabei kann es beispielsweise nötige Treiber laden oder konfigurieren - welche das sein müssen, ermittelt es anhand der erwähnten IDs. Moderne udev-Versionen kommunizieren direkt mit dem Kernel und stossen dieselben Aktionen ohne Umweg an. Dann entfällt das Skript ersatzlos.

So verfährt udev sowohl beim Hinzufügen neuer Geräte im laufenden Betrieb (Hotplugging) wie bei ersten Initialisierung während des Bootvorgangs (Coldplugging). Dabei sucht der Kernel zunächst die Busse nach Geräten ab und erzeugt anhand des Ergebnisses Dateien mit dem Namen "uevent", die er (weil beim Bootvorgang anfänglich kein beschreibbares Root-Dateisystem vorhanden ist) im virtuellen Sys-FS ablegt. Später erzeugt udev anhand dieser Dateien für jedes während des Bootvorganges gefundene Gerät einen Event. Ab hier gleichen die Abläufe genau denen beim späteren Anschliessen der Geräte zur Laufzeit.

Folgende Auflistung zeigt ein mit dem Diagnosewerkzeug "udevmonitor" erzeugtes Protokoll, das die Ereignisse beim Einstecken eines USB-MP3-Players anzeigt.

# udevmonitor
udevmonitor will print the received events for:
UDEV the event which udev sends out after rule processing
UEVENT the kernel uevent

UEVENT[1213346079.943352] add      /devices/pci0000:00/0000:00:1d.2/usb3/3-2 (usb)
UEVENT[1213346079.943423] add      /devices/pci0000:00/0000:00:1d.2/usb3/3-2/usb_endpoint/usbdev3.2_ep00 (usb_endpoint)
UDEV  [1213346079.950449] add      /devices/pci0000:00/0000:00:1d.2/usb3/3-2 (usb)
UDEV  [1213346079.982302] add      /devices/pci0000:00/0000:00:1d.2/usb3/3-2/usb_endpoint/usbdev3.2_ep00 (usb_endpoint)
UEVENT[1213346079.983162] add      /class/scsi_host/host3 (scsi_host)
UEVENT[1213346079.987189] add      /devices/pci0000:00/0000:00:1d.2/usb3/3-2/3-2:1.0/usb_endpoint/usbdev3.2_ep01 (usb_endpoint)
UEVENT[1213346079.987235] add      /devices/pci0000:00/0000:00:1d.2/usb3/3-2/3-2:1.0/usb_endpoint/usbdev3.2_ep82 (usb_endpoint)
UDEV  [1213346080.054318] add      /devices/pci0000:00/0000:00:1d.2/usb3/3-2/3-2:1.0 (usb)
UDEV  [1213346080.056125] add      /class/scsi_host/host3 (scsi_host)
UDEV  [1213346080.086635] add      /devices/pci0000:00/0000:00:1d.2/usb3/3-2/3-2:1.0/usb_endpoint/usbdev3.2_ep01 (usb_endpoint)
UDEV  [1213346080.088971] add      /devices/pci0000:00/0000:00:1d.2/usb3/3-2/3-2:1.0/usb_endpoint/usbdev3.2_ep82 (usb_endpoint)
UEVENT[1213346084.991597] add      /devices/pci0000:00/0000:00:1d.2/usb3/3-2/3-2:1.0/host3/target3:0:0/3:0:0:0 (scsi)
UEVENT[1213346084.991648] add      /class/scsi_disk/3:0:0:0 (scsi_disk)
UEVENT[1213346085.053538] add      /block/sdd (block)
UEVENT[1213346085.053593] add      /class/scsi_device/3:0:0:0 (scsi_device)
UEVENT[1213346085.053607] add      /class/scsi_generic/sg4 (scsi_generic)
UDEV  [1213346085.082311] add      /devices/pci0000:00/0000:00:1d.2/usb3/3-2/3-2:1.0/host3/target3:0:0/3:0:0:0 (scsi)
UDEV  [1213346085.087225] add      /class/scsi_disk/3:0:0:0 (scsi_disk)
UDEV  [1213346085.142962] add      /class/scsi_device/3:0:0:0 (scsi_device)
UDEV  [1213346085.176744] add      /class/scsi_generic/sg4 (scsi_generic)
UDEV  [1213346085.354854] add      /block/sdd (block)
UEVENT[1213346085.957063] add      /module/fat (module)
UDEV  [1213346085.958808] add      /module/fat (module)
UEVENT[1213346085.962704] add      /slab/fat_cache (slab)
UEVENT[1213346085.962756] add      /slab/fat_inode_cache (slab)
UDEV  [1213346085.964219] add      /slab/fat_cache (slab)
UEVENT[1213346085.966743] add      /module/vfat (module)
UDEV  [1213346085.976058] add      /slab/fat_inode_cache (slab)
UDEV  [1213346085.978029] add      /module/vfat (module)
UEVENT[1213346086.007601] add      /module/nls_cp437 (module)
UDEV  [1213346086.009049] add      /module/nls_cp437 (module)
UEVENT[1213346086.037991] add      /module/nls_iso8859_1 (module)
UDEV  [1213346086.039641] add      /module/nls_iso8859_1 (module)

Bis zur udev-Version 0.58 lädt das Hotplug-Paket Treiber und Firmware. Dabei bleibt "/sbin/hotplug" der Hotplug-Manager und ruft nach getaner Arbeit als Multiplayer alle in "/etc/hotplug.d" eingetragenen Programme auf. Ab Version 0.59 übernimmt udev beide Aufgaben.

Konfiguration

Die udev-Konfigurationsdateien befinden sich im Verzeichnis "/etc/udev", bei einigen Distributionen auch in "/lib/udev".

Die wichtigsten Variablen für allgemeine Einstellungen stehen in der Datei "/etc/udev/udev.conf". Sie speichern beispielsweise das Wurzelverzeichnis der Gerätedateien, den Ort der internen udev-Datenbank, das Verzeichnis der regeln für das Anlegen und Benennen der Gerätedatei und den Logging-Level:

# more /etc/udev/udev.conf
udev_root="/dev/"
udev_db="/dev/.udevdb"
udev_rules="/etc/udev/rules.d"
udev_log="err"

Zur Konfiguration seiner Funktionsweise bietet udev zwei weitere Eingriffspunkte:

  • In "/etc/udev/rules.d" befinden sich Dateien, die regeln, wie die Devicenodes zu benennen sind, die udev bei bedarf erzeugt.
  • In "/etc/udev/make-dev.d" liegen Skripte mit den Namen der statischen Gerätedateien, die z. B. für die Parallelschnittstelle nötig sind. Bei einigen Distributionen fehlt diese Datei.

Die Zugriffsrechte stehen bei aktuellen udev-Versionen nicht mehr im Verzeichnis "/etc/udev/permissions.d", sondern in der normalen udev-Konfiguration.

Regeln

Der erste Teil jeder Regel gibt jene Bedingung an, die erfüllt sein muss, damit udev den zweiten Teil ausführt bzw. anwendet. Im einfachsten Fall muss nur der kernelinterne Name eines Geräts oder eines Subsystems zutreffen. Für eine Tastatur lautet die Regel z. B.

KERNEL=="kbd"

Die Bedingungen sind wie bei einer Programmiersprache mit doppelten Gleichheitszeichen gekennzeichnet. Nach einem Komma können weitere Bedingungen folgen. Die auszuführenden Aktionen enthalten dagegen nur einfache Gleichheitszeichen. Z. B. setzt folgender Ausdruck die Zugriffsrechte:

MODE="0660"

Analog lassen sich mit "OWNER" der Eigentümer oder mit "GROUP" die Gruppe bestimmen, die eine Gerätedatei zugeordnet bekommt. Ihren namen gibt das Schlüsselwort "NAME" vor, das einige Platzhalter verarbeitet. So steht etwa "%k" für den oben genannten Kernelnamen. Eine Regel nach diesem Muster könnte z. B. wie folgt aussehen. Dabei wird für jedes Gerät, dessen Kernelname mit "isdn" beginnt, ein Devicenode gleichen Namens mit Lese- und Schreibrechten für den Eigentümer und seine Gruppe angelegt.

KERNEL=="isdn", NAME="%k", MODE="0660"

Normalerweise geht udev alle zutreffenden Regeln durch, bis keine weiteren mehr vorhanden sind. Zum Abbruch der Verarbeitung nach dem Zutreffen einer Regel ist unter "OPTIONS" die Anweisung "last_rule" anzugeben.

Die udev-Regeln können auch externe Programmaufrufe enthalten, die ebenfalls als Bedingung gelten. Nur wenn der Aufruf das gewünschte Ergebnis liefert, führt udev die anschliessend aufgeführten Aktionen aus. Die Manpage enthält ein Beispiel für ATAPI-CD-ROMs, das untersucht, ob ein entsprechendes "/proc"-Verzeichnis vorhanden ist, das ein Gerät als CD-ROM identifiziert. Dabei gibt udev für alle Geräte, deren Name mit "hd" beginnt, mit "/bin/cat" den Inhalt der entsprechenden "media"-Datei aus. Wenn sie "cdrom" enthält ("RESULT"), behält udev die Gerätedatei bei ("NAME="%k""), legt aber zusätzlich mit "SYMLINK" einen symbolischen Link "cdrom" an, wobei "%e" die nächste freie Dezimalzahl bestimmt, falls eine gleichnamige Datei bereits vorhanden ist.

KERNEL=="hd[a-z]", PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="cdrom", NAME="%k", SYMLINK="cdrom%e"

Wertet man mit Hilfe einer udev-Regel die eindeutige Serienummer eines angeschlossenen Geräts aus, so lassen sich auch für Hotplug-Geräte stabile Namen erreichen, die unabhängig von der Anschluss- oder Einschaltreihenfolge sind. Eine Regel dafür könnte wie folgt aussehen. Damit erhält der eingesteckte Drucker mit der zutreffenden Serienummer stets den Gerätenamen "lp-kyocera".

BUS=="usb", SYSFS_serial=="W09090207101241330", NAME="lp-kyocera"

Die häufigsten Anwendungen für selbst geschriebene oder von Benutzern geänderte udev-Regeln sind wohl individuell angepasste Gerätenamen oder besondere Rechte für Gerätedateien. Beispielsweise soll der in die Arbeitsumgebung eingeloggte Benutzer auf die zur Laufzeit hinzugefügte USB-Festplatte schreiben dürfen. Fedora löst dieses Problem z. B. dadurch, dass udev deren gerätedateien einfach dem in die Arbeitsumgebung eingeloggten Benutzer übereignet.

Fehlersuche

Bei der Fehlersuche hilft der udev-Daemon durch seinen einstellbaren Logging-Level, der bei der Standardeinstellung "err" allerdings nur Fehler ausgibt. Mit der Vorgabe "info" wird der udev-Daemon etwas mitteilsamer, die Vorgabe "debug" macht ihn noch geschwätziger. Diese Werte können entweder in die Konfigurationsdatei eingetragen oder zur Laufzeit über das Werkzeug "udevcontrol" eingestellt werden. Den Loglevel setzt z. B. der Eintrag "udevcontrol log_priority=debug". Über die Anweisung "reload_rules" bewegt udevcontrol den udev-Daemon zum erneuten Laden aller Regeln.

Weblinks

Herausgeber Sprache Webseitentitel Anmerkungen