Translation(s): English - Français - Italiano - Русский


udev - gestione dinamica dei dispositivi in Linux

udev è un rimpiazzo per il Device File System (DevFS) a partire dalla serie 2.6 del ?kernel Linux. Permette di identificare dinamicamente i dispositivi in base alle loro proprietà, come ID del produttore e ID di device. udev viene eseguito in spazio utente (a differenza di devfs che girava in spazio kernel).

udev permette l'uso di regole che specificano quale nome venga assegnato ad un dato dispositivo, indipendentemente dalla porta a cui è collegato. Per esempio è possibile avere una regola per montare sempre un disco fisso che produttore "iRiver" e codice di dispositivo "ABC" come {/dev/iriver}. Questa assegnazione costante dei nomi di device garantisce che script che dipendono dall'esistenza di un particolare device non smettano di funzionare.

Introduzione

Il sistema udev è composto da alcuni servizi kernel e dal demone udevd. Il kernel informa il demone udevd quando accadono determinati eventi; il demone udevd è configurato per rispondere ad eventi con le corrispondenti azioni. Le informazioni sugli eventi arrivano dal kernel, le azioni avvengono in spazio utente. Le risposte agli eventi sono configurabili con "regole".

Il demone udevd, come altri demoni, si avvia all'avvio del sistema grazie ad uno script init: /etc/rcS.d/udev. Il suo file di configurazione è /etc/udev/udev.conf. I file di regole (che sono un'ulteriore configurazione di udevd) sono in /run/udev/rules.d, /etc/udev/rules.d o /lib/udev/rules.d (Debian mette la maggior parte delle regole in /lib/udev/rules.d). Se un file con lo stesso nome è presente in più di una di queste directory, allora i file dopo il primo verranno ignorati. I file in questa directory sono analizzati in ordine alfabetico, sempre che il loro nome termini con ".rules". Quando il file di configurazione o i file delle regole vengono modificati, il demone udevd dovrebbe essere riavviato (o, come detto più avanti, si può usare il programma udevadm).

Molti dei file in /etc/udev/rules.d sono collegamenti a file presenti altrove. L'autore immagina che ciò sia fatto in modo che quando i file di regole sono modificati, i file di backup degli editor non rimangono in giro dove potrebbero venir usati al prossimo riavvio del demone udevd. Inoltre, dato che i collegamenti possono avere nomi diversi dai file originali, possono essere ordinati senza doversi preoccupare di quale nome abbiano (come con gli script init).

udev è stato creato per rispondere ad eventi di connessioni a caldo. Molta documentazione parla della creazione di device in risposta all'apparizione di nuovi device. Ma udev è molto più generico; può eseguire comandi arbitrari in spazio utente in risposta all'apparizione di un nuovo device, o a qualsiasi altro evento riceva dal kernel.

I momenti in cui udevd è attivo sono:

  1. all'avvio; analizza tutti i file di configurazione e i file di regole e crea un database di regole in memoria;
  2. quando avviene un evento; controlla nel suo database delle regole ed effettua l'azione appropriata.

Regole

Regole per le regole:

  1. le regole devono essere ciascuna su un'unica riga (le righe possono essere spezzate con \ immediatamente prima del ritorno a capo)
  2. le regole consistono di "corrispondenze" ed "azioni"
  3. le corrispondenze e le azioni sono compostd da triplette "chiave" "operatore" "valore"
  4. le corrispondenze contengono l'operatore == o !=
  5. le azioni contengono l'operatore = (assegnazione)
  6. le corrispondenze controllano uno o più attributi dell'evento per vedere se l'azione verrà effettuata;
  7. le azioni specificano ciò che accadrà
  8. esempio di corrispondenza: BUS=="usb"

  9. esempio di azione: NAME="mydev"

  10. esempio di regola:

    KERNEL=="sd*[0-9]|dasd*[0-9]", ENV{ID_SERIAL}=="?*", \
            SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}-part%n"
  11. tutte le regole che fanno corrispondenza verranno eseguite
  12. le regole che vengono prima hanno precedenza sulle regole successive: quindi mettere le proprie personalizzazioni tra i primi file in rules.d
  13. le azioni come key="value" sovrascrivono le altre
  14. le azioni come key+="value" si aggiungono alle azioni che vengono eseguite, es. SYMLINK+="foo" significa "oltre a qualsiasi altro collegamento simbolico che viene creato per questo evento, crearne anche uno chiamato foo"

Insiemi di regole

Regole per gli insiemi di regole:

  1. Tutte le regole sono in un unico grande spazio delle regole, anche se sono suddivise in vari file
  2. L'unica organizzazione nello spazio delle regole è data dalla possibilità di impostare etichette e quindi di saltare un gruppo di regole al momento della "ricerca delle corrispondenze con questo evento nelle regole" saltando in avanti con un'azione GOTO

  3. Esiste un altro tipo di regole chiamata etichette, ad esempio LABEL="persistent_storage_end", vengono usate da regole normali che hanno azioni "GOTO", ad esempio:

    ACTION!="add", GOTO="persistent_storage_end"
    Notare che in questa regola, il termine ACTION è un attributo di un evento e viene usato come condizione per decidere se deve scattare l'azione GOTO
  4. È bene limitare i salti GOTO all'interno di uno stesso file (o ci si dovrà preoccupare in caso di riordino dei file)
  5. Non saltare indietro ad un'etichetta (l'autore non ha provato a farlo, ma immagina che la cosa risulterebbe in un ciclo infinito. Forse il codice di udev controlla che ciò non avvenga, ma se, nel caso migliore, la cosa è ignorata, perché farla?)
  6. Si possono impostare variabili nello spazio ENV di ambiente in regole e fare riferimento ad esse nelle regole successive
  7. Esiste la funzione per la creazione di regole dinamiche (esempio: vedere z45_persistent-net-generator.rules)

Liste nere

Liste nere per i moduli del kernel

Nomi di device persistenti

In questo esempio, si vuole fare in modo che la scheda 3G ottenga un nome costante.

1. Inserire la "scheda" (o il dispositivo)

2. Eseguire il comando seguente, sul device appropriato:

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

udevadm si avvia sul device specificato da devpath e poi si muove verso l'alto lungo la catena di device genitori. Stampa per ogni device trovato tutti i possibili attributi nel formato delle chiavi delle regole di udev. Una regola per una corrispondenza può essere composta dagli attributi del device e dagli attributi di un solo device genitore.

  looking at device '/class/tty/ttyS1':
    KERNEL=="ttyS1"
    SUBSYSTEM=="tty"
    DRIVER==""
    ATTR{dev}=="4:65"

  looking at parent device '/devices/pci0000:00/0000:00:1e.0/0000:15:00.0/0.0':
    KERNELS=="0.0"
    SUBSYSTEMS=="pcmcia"
    DRIVERS=="serial_cs"
    ATTRS{modalias}=="pcmcia:m00A4c1AAFf02fn00pfn00pa32607776pbD9E73B13pcAF9C4D7Fpd00000000"
    ATTRS{prod_id3}=="NRM6831"
    ATTRS{prod_id2}=="Merlin UMTS Modem"
    ATTRS{prod_id1}=="Novatel Wireless"
    ATTRS{card_id}=="0x1aaf"
    ATTRS{manf_id}=="0x00a4"
    ATTRS{func_id}=="0x02"
    ATTRS{pm_state}=="on"
    ATTRS{function}=="0x00"

  looking at parent device '/devices/pci0000:00/0000:00:1e.0/0000:15:00.0':
    KERNELS=="0000:15:00.0"
    SUBSYSTEMS=="pci"
    DRIVERS=="yenta_cardbus"
    ATTRS{msi_bus}=="1"
    ATTRS{broken_parity_status}=="0"
    ATTRS{enable}=="2"
    ATTRS{numa_node}=="0"
    ATTRS{modalias}=="pci:v00001180d00000476sv000017AAsd000020C6bc06sc07i00"
    ATTRS{local_cpus}=="00000003"
    ATTRS{irq}=="16"
    ATTRS{class}=="0x060700"
    ATTRS{subsystem_device}=="0x20c6"
    ATTRS{subsystem_vendor}=="0x17aa"
    ATTRS{device}=="0x0476"
    ATTRS{vendor}=="0x1180"

  looking at parent device '/devices/pci0000:00/0000:00:1e.0':
    KERNELS=="0000:00:1e.0"
    SUBSYSTEMS=="pci"
    DRIVERS==""
    ATTRS{msi_bus}=="1"
    ATTRS{broken_parity_status}=="0"
    ATTRS{enable}=="1"
    ATTRS{numa_node}=="0"
    ATTRS{modalias}=="pci:v00008086d00002448sv00000000sd00000000bc06sc04i01"
    ATTRS{local_cpus}=="00000003"
    ATTRS{irq}=="0"
    ATTRS{class}=="0x060401"
    ATTRS{subsystem_device}=="0x0000"
    ATTRS{subsystem_vendor}=="0x0000"
    ATTRS{device}=="0x2448"
    ATTRS{vendor}=="0x8086"

  looking at parent device '/devices/pci0000:00':
    KERNELS=="pci0000:00"
    SUBSYSTEMS==""
    DRIVERS==""
    ATTRS{uevent}==""

3. Creare un file in /etc/udev/rules.d, tipicamente chiamato z21_persistent-local.rules.

ATTRS{prod_id2}=="Merlin UMTS Modem", ATTRS{prod_id1}=="Novatel Wireless", SYMLINK+="MerlinUMTS"
## Alternatively we could use :
# ATTRS{card_id}=="0x1aaf", ATTRS{manf_id}=="0x00a4", SYMLINK+="MerlinUMTS"

4. Forzare la riesecuzione degli script (o riavviare ;)

udevadm control --reload-rules
udevadm test -a -p $(udevadm info -q path -n /dev/ttyS1)

Un esempio più dettagliato scritto da semu5 su comp.os.linux.questions. Esiste anche una guida su come Scrivere regole udev.

Riferimenti


CategorySystemAdministration | CategoryLocalResourcesManagement