7.4. Gestione di dispositivi e moduli in un sistema LFS

Nel Capitolo 6, è stato installato il pacchetto Udev. Prima di scendere nel dettaglio di come funziona, facciamo un breve accenno al precedente metodo per la gestione delle periferiche.

I sistemi Linux usano tradizionalmente un metodo statico di creazione dei dispositivi. Questo metodo crea molti nodi di dispositivo nella directory /dev (qualche volta letteralmente migliaia di nodi), anche se non esiste in quel momento l'hardware corrispondente. Questo avviene tramite lo script MAKEDEV, che contiene un numero di chiamate al programma mknod, con i numeri major e minor della periferica, pari ad ogni possibile periferica che possa esistere al mondo. Usando il metodo udev, vengono creati i device node solo per quelle periferiche che vengono trovate dal kernel. Dato che questi nodi di dispositivo vengono creati ad ogni avvio del sistema, vengono memorizzati in un ramfs (un file system residente interamente in memoria e che non occupa quindi alcuno spazio disco). Dato che i nodi di dispositivo non richiedono molto spazio disco, la memoria usata è irrisoria.

7.4.1. Cronistoria

Nel febbraio 2000, un nuovo filesystem chiamato devfs venne intergrato nel kernel 2.3.46 e divenne disponibile con la serie 2.4 dei kernel stabili. Sebbene fosse presente nei sorgenti del kernel, questo metodo di creazione dinamica dei device non ha mai ricevuto un consenso ed un supporto unanime da parte degli sviluppatori del kernel.

Il problema principale dell'approccio adottato da devfs è stata la gestione dell'identificazione delle periferiche, della loro creazione e nomenclatura. D'altra parte, il problema della nomenclatura dei nodi di dispositivo era forse il più critico. E' generalmente accettato che se un device può essere configurabile, la politica di come chiamare le periferiche deve essere lasciata all'amministratore di sistema e non essere imposta da un particolare sviluppatore. Il file system devfs soffre anche di condizioni che sono inerenti alla propria progettazione e non possono essere corrette senza una sostanziale revisione del kernel. E' stato anche contrassegnato come deprecato a causa della mancanza di manutenzione.

Con lo sviluppo dell'albero instabile del kernel della serie 2.5, che ha poi portato alla serie 2.6 dei kernel stabili, è stato introdotto una nuovo filesystem virtuale chiamato sysfs. Quello che fa sysfs è di esportare una veduta della struttura del sistema nello userspace dei processi. Con questa rappresentazione visibile dello userspace, la possibilità  di vedere un sostituto di devfs diventa realistica.

7.4.2. L'implementazione di Udev

Il filesystem sysfs è stato menzionato brevemente sopra. Ci si può meravigliare di come sysfs conosca le periferiche presenti sul sistema e quale numero di device usare. I driver che sono stati compilati nel kernel direttamente registrano i propri oggetti con sysfs non appena sono riconosciuti dal kernel. Per i driver compilati come moduli, questo succede non appena il modulo viene caricato. Una volta che il filesystem sysfs viene montato (in /sys), i dati che i driver compilati nel kernel registrano attraverso sysfs divengono disponibili allo userspace dei processi e a udev per la creazione dei nodi di dispositivo.

Lo script di avvio S10udev si occupa della creazione di questi device node quando Linux viene avviato. Questo script parte registrando /sbin/udev come un gestore di eventi hotplug. Gli eventi hotplug (discussi in seguito) non dovrebbero essere generati durante questo stadio, ma solo nel momento che avviene una connessione a 'caldo' di una periferica. Il programma udevstart prende in esame il filesystem /sys e crea i device, che corrispondono alla descrizione, in /dev. Per esempio, /sys/class/tty/vcs/dev contiene la stringa “7:0” Questa stringa è usata da udevstart per creare /dev/vcs con major number 7 e minor 0. I permessi di ogni device creato da udevstart sono definiti usando i file della directory /etc/udev.d/permissions.d/. Questi sono numerati in modo simile agli script di boot di LFS. Se udev non trova un file di permessi per la creazione di un device, definisce i permessi come 600 e il proprietario root:root. I nomi dei nodi creati nella directory /dev sono configurati in accordo con le regole specificate nei file della directory /etc/udev/rules.d/.

Una volta completato questo stadio, tutte le periferiche che erano presenti e che avevano i driver compilati nel kernel sono pronte per l'uso. Vediamo cosa succede alle periferiche i cui driver sono modulari.

In precedenza abbiamo menzionato il concetto di “gestore di eventi hotplug”. Quando viene individuata dal kernel la connessione di una nuova periferica, il kernel genera un evento hotplug e controlla il file /proc/sys/kernel/hotplug per trovare il programma che gestisca la connessione di questa periferica. Lo script di avvio udev registra udev come gestore. Quando vengono generati questi eventi hotplug, il kernel istruisce udev per cercare nel filesystem /sys le informazioni pertinenti questa nuova periferica e creare una nuova registrazione per lei in /dev.

Questo ci porta ad un problema che esiste in udev, e prima di lui in devfs. Ci si riferisce comunemente come al problema “della gallina e dell'uovo”. Molte distribuzioni Linux gestiscono il caricamento dei moduli attraverso una voce nel file /etc/modules.conf. L'accesso ad un device node causa il caricamento del modulo appropriato da parte del kernel. Con udev questo metodo non funziona perché il device node non esiste finché non viene caricato il modulo. Per risolvere questo problema, è stato aggiunto al pacchetto lfs-bootscripts, lo script di avvio S05modules insieme al file /etc/sysconfig/modules. L'aggiunta del nome del modulo nel file modules, provoca il caricamento dello stesso all'avvio del computer. Questo permette a udev di individuare le periferiche e creare il nodo di dispositivo appropriato.

Da notare che su macchine lente o per driver che creano molti device node, il processo di creazione dei device può impiegare diversi secondi. Questo significa che alcuni device node possono non essere immediatamente disponibili.

7.4.3. Gestione delle periferiche dinamiche e hotplug

Quando si collega una periferica, come un lettore MP3 USB (Universal Serial Bus), il kernel riconosce che la periferica è ora collegata e genera un evento hotplug. Se il driver è già  caricato (perché è stato compilato nel kernel o perché già  caricato dallo script di avvio S05modules), udev verrà  eseguito per creare i device node rilevanti in accordo con i dati sysfs disponibili in /sys. Se il driver per la periferica è disponibile come modulo ma non caricato, al momento della connessione della periferica al sistema verrà  generato, dal kernel, un evento hotplug che notificherà  allo userspace la connessione di una nuova periferica e non ancora connessa ad un driver. Effettivamente non succede niente e la periferica non è ancora utilizzabile.

Se si costruisce un sistema che ha molti driver compilati come modulo piuttosto che direttamente nel kernel, l'uso di S05modules può non essere pratico. Il pacchetto Hotplug (vedere http://linux-hotplug.sourceforge.net/) può essere di beneficio in questi casi. Una volta installato, il pacchetto Hotplug si prenderà  il carico di rispondere agli eventi driver hotplug del kernel, caricherà  il modulo appropriato e renderà la periferica disponibile creando il device node.

7.4.4. Problemi legati alla creazione di dispositivi

Ci sono alcuni problemi conosciuti quando si creano automaticamente dei nodi di dispositivo:

1) un driver del kernel può non esportare i propri dati in sysfs.

Questo è molto comune con driver di terze parti non presenti nell'albero del kernel. Questi driver finiranno per non avere il loro device node creato. Usare il file di configurazione /etc/sysconfig/createfiles per creare manualmente i device node. Consultare il file devices.txt all'interno della documentazione del kernel o la documentazione per questo driver per trovare i numeri major/minor appropriati.

2) E' richiesto un device non hardware. Questo è molto comune con ALSA (Advanced Linux Sound Architecture) il modulo compatibile col progetto OSS (Open Sound System). Questi tipi di device possono essere gestiti in uno dei seguenti modi:

  • Aggiungendo il nome del modulo in /etc/sysconfig/modules

  • Usando una linea “install” in /etc/modprobe.conf. Questo istruisce il comando modprobea caricare questo modulo insieme a quest'altro modulo, nello stesso momento ” Per esempio:

    install snd-pcm modprobe -i snd-pcm ; modprobe \
        snd-pcm-oss ; true
    

    Questo porterà il sistema a caricare sia il modulo snd-pcm che snd-pcm-oss quando viene ricevuta la richiesta di caricare il driver snd-pcm.

7.4.5. Letture utili

Documentazione utile è disponibile nei seguenti siti: