9.3. Oversikt over enhets- og modulhåndtering

I Kapittel 8, installerte vi udev nissen når systemd ble bygget. Før vi går inn i detaljer om hvordan dette fungerer, er en kort historie om tidligere metoder for å håndtere utstyr i orden.

Generelt brukte Linux systemer tradisjonelt en statisk enhetsopprettingsmetode , hvor mange enhetsnoder ble opprettet under /dev (noen ganger bokstavelig talt tusenvis av noder), uavhengig av om de tilsvarende maskinvareenhetene faktisk eksisterte. Dette ble vanligvis gjort via en MAKEDEV skript, som inneholder et antall anrop til mknod programmet med det aktuelle hoved- og mindre enhetsnumre for alle mulige enheter som kan eksistere i verden.

Ved å bruke udev metoden vil bare de enhetene som oppdages av kjernen få enhetsnoder opprettet for dem. Fordi disse enhetsnodene vil være opprettet hver gang systemet starter, vil de bli lagret på et devtmpfs filsystem (et virtuelt filsystem som ligger utelukkende i systemminnet). Enhetsnoder krever ikke mye plass, så minnet som brukes er ubetydelig.

9.3.1. Historie

I februar 2000 ble et nytt filsystem kalt devfs flettet inn i 2.3.46-kjernen og ble gjort tilgjengelig under 2.4-serien med stabile kjerner. Selv om den var til stede i selve kjernekilden, fikk denne metoden for å lage enheter dynamisk aldri overveldende støtte fra kjerneutviklere.

Hovedproblemet med tilnærmingen vedtatt av devfs var måten den håndterte enheten på ved oppdagelse, opprettelse og navngivning. Det siste problemet enhetsnavnet på en enhetsnode, var kanskje den mest kritiske. Det er generelt akseptert at hvis enhetsnavn kan konfigureres, så skal enhetsnavn politikken være opp til en systemadministrator, og ikke pålagt dem av en spesiell(e) utvikler(e). devfs filsystemet led også av kjøreforhold som var iboende i utformingen og ikke kunne fikses uten en betydelig revisjon av kjernen. devfs ble merket som utdatert i lang tid, og ble til slutt fjernet fra kjernen i juni 2006.

Med utviklingen av det ustabile 2.5 kjernetreet, senere utgitt som 2.6-serien med stabile kjerner, et nytt virtuelt filsystem kalt sysfs ble opprettet. Jobben til sysfs er å eksportere en visning av systemets maskinvarekonfigurasjon til brukerprosesser. Med dette brukersynlige representasjonen, ble det mulig å utvikle et brukerområde erstatning for devfs.

9.3.2. Udev Implementering

9.3.2.1. Sysfs

sysfs filsystemet ble kort nevnt ovenfor. Man kan lure på hvordan sysfs vet om enhetene som finnes på et system og hvilke enhetsnumre som skal brukes for dem. Drivere som har blitt kompilert inn i kjernen, registrerer objektene deres direkte med sysfs (devtmpfs internt) når de oppdages av kjernen. For drivere kompilert som moduler, vil registreringen skje når modulen blir lastet. Først når sysfs filsystemet er montert (på /sys), data som driverne registrerer med sysfs er tilgjengelig for brukerområdets prosesser og til udevd for behandling (inkludert modifikasjoner av enhetens noder).

9.3.2.2. Oppretting av enhetsnode

Enhetsfiler opprettes av kjernen i devtmpfs filsystemet. Enhver driver som ønsker å registrere en enhetsnode vil bruke devtmpfs (via driverkjernen) for å gjøre det. Når en devtmpfs forekomst er montert på /dev, vil enhetsnoden i utgangspunktet bli eksponert for brukerrom med et fast navn, tillatelser og eieren.

Kort tid senere vil kjernen sende en uevent til udevd. Basert på reglene spesifisert i filene i /etc/udev/rules.d, /usr/lib/udev/rules.d, og /run/udev/rules.d mappene, udevd vil opprette flere symbolkoblinger til enhetsnoden, eller endre tillatelsene, eieren eller gruppen, eller endre den interne udevd databaseoppføring (navn) for det objektet.

Reglene i disse tre mappene er nummererte og alle tre mappene slås sammen. Hvis udevd ikke finner en regel for enheten den oppretter, vil den opprettholde tillatelsene og eierskapet som devtmpfs brukte i utgangspunktet.

9.3.2.3. Modullasting

Enhetsdrivere kompilert som moduler kan ha innebygde aliaser. Aliaser er synlige i utdataene til modinfo programmet og er vanligvis relatert til de bussspesifikke identifikatorene til enheter støttet av en modul. For eksempel snd-fm801 driveren støtter PCI-enheter med leverandør-ID 0x1319 og enhets-ID 0x0801, og har et alias pci:v00001319d00000801sv*sd*bc04sc01i*. For de fleste enheter eksporterer bussdriveren aliaset til driveren som vil håndtere enheten via sysfs. F.eks, /sys/bus/pci/devices/0000:00:0d.0/modalias filen kan inneholde strengen pci:v00001319d00000801sv00001319sd00001319bc04sc01i00. Standardreglene som følger med udev vil gjøre at udevd kaller /sbin/modprobe med innholdet i MODALIAS uevent miljøvariabel (som skal være samme som innholdet i modalias filen i sysfs), laster dermed alle moduler hvis aliaser samsvarer med denne strengen etter jokertegn ekspansjonen.

I dette eksemplet betyr dette at i tillegg til snd-fm801, det foreldede (og uønskede) forte driveren vil bli lastet hvis den er tilgjengelig. Se nedenfor for måter lasting av uønskede drivere kan bli forhindret.

Kjernen selv er også i stand til å laste moduler for nettverksprotokoller, filsystemer og NLS-støtte på forespørsel.

9.3.2.4. Håndtering av direktekoblingsbare/dynamiske enheter

Når du kobler til en enhet, for eksempel en Universal Serial Bus (USB) MP3 spiller, gjenkjenner kjernen at enheten nå er tilkoblet og genererer en uevent. Denne uevent håndteres deretter av udevd som beskrevet ovenfor.

9.3.3. Problemer med å laste moduler og lage enheter

Det er noen mulige problemer når det kommer til å automatisk opprette enhetsnoder.

9.3.3.1. En kjernemodul lastes ikke automatisk

Udev vil bare laste en modul hvis den har et bussspesifikt alias og bussdriveren eksporterer de nødvendige aliasene til sysfs. I andre tilfeller bør man ordne modullasting på andre måter. Med Linux-6.7.4, udev er kjent for å laste riktig skrevne drivere for INPUT, IDE, PCI, USB, SCSI, SERIO, og FireWire-enheter.

For å finne ut om enhetsdriveren du trenger har den nødvendige støtten for udev, kjør modinfo med modulnavnet som argument. Prøv nå å finne enhetsmappen under /sys/bus og sjekk om det er en modalias fil der.

Hvis modalias filen finnes i sysfs, driveren støtter enheten og kan snakke med den direkte, men har ikke aliaset, det er en feil i driveren. Last inn driveren uten hjelp fra udev og forvent at problemet blir fikset senere.

Hvis det ikke er noen modalias fil i den aktuelle mappen under /sys/bus, dette betyr at kjerneutviklerne ennå ikke har lagt til støtte for modalias for denne busstypen. Med Linux-6.7.4, dette er tilfellet med ISA busser. Forvent at dette problemet blir løst i senere kjerneversjoner.

Udev er ikke ment å laste innpakkede (wrapper) drivere som f.eks snd-pcm-oss og ikke-maskinvaredrivere som f.eks loop i det hele tatt.

9.3.3.2. En kjernemodul lastes ikke automatisk, og udev er ikke beregnet på å laste den

Hvis den innpakkede modulen bare forbedrer funksjonalitet levert av en annen modul (f.eks., snd-pcm-oss forbedrer funksjonaliteten til snd-pcm ved å gjøre lydkortene tilgjengelige for OSS applikasjoner), konfigurer modprobe til å laste inn innpakkningen etter at udev har lastet den innpakkede modulen. For å gjøre dette, legg til en softdep linje til den tilsvarende /etc/modprobe.d/<filename>.conf filen. For eksempel:

softdep snd-pcm post: snd-pcm-oss

Merk at softdep kommandoen tillater også pre: avhengigheter, eller en blanding av begge (Før) pre: og (Etter) post: avhengigheter. Se modprobe.d(5) manualside for mer informasjon om softdep syntaks og muligheter.

9.3.3.3. Udev laster inn noen uønskede moduler

Enten ikke bygg modulen, eller svarteliste den i en /etc/modprobe.d/blacklist.conf fil som gjort med forte modulen i eksemplet nedenfor:

blacklist forte

Svartelistede moduler kan fortsatt lastes inn manuelt med eksplisitt modprobe kommando.

9.3.3.4. Udev oppretter en enhet feil, eller lager en feil symbolkobling

Dette skjer vanligvis hvis en regel uventet samsvarer med en enhet. For eksempel kan en dårlig skrevet regel matche både en SCSI-disk (som ønsket) og den tilsvarende generiske SCSI-enheten (feil) av leverandøren. Finn den krenkende regelen og gjør den mer spesifikk, ved hjelp av udevadm info kommandoen.

9.3.3.5. Udev regel fungerer upålitelig

Dette kan være en annen manifestasjon av det forrige problemet. Hvis ikke, og regelen din bruker sysfs attributter, kan det være et problem med kjernetiming, som bør fikses i senere kjerner. Foreløpig kan du omgå det ved å lage en regel som venter på den brukte sysfs attributten og tilføye den til /etc/udev/rules.d/10-wait_for_sysfs.rules filen (opprett denne filen hvis den ikke eksisterer). Gi beskjed til LFS Utviklingsliste hvis du gjør det, og det hjelper.

9.3.3.6. Udev oppretter ikke en enhet

Først må du være sikker på at driveren er innebygd i kjernen eller allerede lastet inn som en modul, og at udev ikke oppretter en enhet med feil navn.

Hvis en kjernedriver ikke eksporterer dataene sine til sysfs, mangler udev informasjon som trengs for å opprette en enhetsnode. Dette vil mest sannsynlig skje med tredjepartsdrivere fra utenfor kjernetreet. Lag en statisk enhetsnode i /usr/lib/udev/devices med passende hoved/under nummer (se filen devices.txt inne i kjernedokumentasjonen eller dokumentasjon levert av tredjeparts driverleverandør). Det statiske enhetsnoden vil bli kopiert til /dev av udev.

9.3.3.7. Rekkefølgen for enhetsnavn endres tilfeldig etter omstart

Dette skyldes det faktum at udev, etter design, håndterer uevents og laster moduler parallelt, og dermed i en uforutsigbar rekkefølge. Dette vil aldri bli fikset. Du bør ikke stole på at kjerneenhetens navn er stabile. Lag heller dine egne regler som lager symbolkoblinger med stabile navn basert på noen stabile attributter til enheten, for eksempel et serienummer eller utdata fra forskjellige *_id-verktøy installert av udev. Se Section 9.4, “Administrere enheter” og Section 9.2, “Generell nettverkskonfigurasjon” for eksempler.

9.3.4. Nyttig lesning

Ytterligere nyttig dokumentasjon er tilgjengelig på følgende nettsteder: