Disclaimer :
Questo documento non è più valido e non è più mantenuto.
|
Guida al Device File System
1.
Cos'è devfs?
I (bei?) vecchi tempi
Avvertenza:
devfs è obsoleto e è stato rimosso dall'albero 2.6 del kernel stabile
nella versione 2.6.13. Utenti di kernel 2.6 sono avvisati di passare a udev. Per
maggiori informazioni fare riferimento alla Guida Gentoo a udev
|
Implementazioni tradizionali di Linux provvedono ai loro utenti un percorso
astratto dei dispositivi, chiamato /dev. In questa directory, gli
utenti possono trovare i device nodes, file speciali che rappresentano le
periferiche presenti nei loro sistemi. Per intenderci, /dev/hda
rappresenta la prima periferica IDE del nostro sistema. Attraverso questi file
di periferica, gli utenti possono creare programmi che interagiscono con
l'hardware come se fosse un file regolare invece che attraverso speciali API.
I file di periferica sono suddivisi in due gruppi chiamati periferiche a
caratteri (character devices) e periferiche a blocchi (block
devices). Il primo gruppo racchiude l'hardware la cui scrittura/lettura non è
bufferizzata. Il secondo gruppo, quindi, racchiude invece l'hardware la cui
scrittura/lettura è bufferizzata. Le periferiche di ambedue i gruppi possono
leggere un carattere alla volta o in blocchi. Per questo, la nomenclatura
potrebbe confondere ed infatti non è corretta.
Se date un'occhiata a certi file di periferica, potreste trovare qualcosa del
genere:
Codice 1.1: Controllare le informazioni di un file di periferica |
# ls -l /dev/hda
brw-rw---- 1 root disk 3, 0 Jul 5 2000 /dev/hda
|
Nell'esempio precedente abbiamo visto che /dev/hda è una periferica
a blocchi (block device). Rivestono molta importanza i due numeri speciali
assegnati al file di periferica: 3,0. Questa coppia di numeri è chiamata
major-minor ed è usata dal kernel per mappare un file di periferica al
dispositivo reale. Il major corrisponde a certi dispositivi mentre il minor a
sotto dispositivi.
Due esempi sono /dev/hda4 e /dev/tty5. Il primo file
di periferica corrisponde alla quarta partizione della prima periferica IDE. La
sua coppia major-minor è 3, 4. In altre parole, il minor corrisponde
alla partizione dove il major corrisponde alla periferica. Il secondo esempio ha
4, 5 come coppia major-minor. In questo caso, il major corrisponde ad un
terminal driver, mentre il minor corrisponde al numero del terminale (in questo
caso, al quinto terminale).
I problemi
Se fate un rapido controllo in /dev, troverete che sono listate non
solo le vostre periferiche, ma tutte le possibili periferiche voi
possiate immaginare. In altre parole, sono presenti file di periferica anche per
i dispositivi non presenti sul vostro sistema. Il controllo di un numero così
elevato di gruppi di periferiche è quanto mai difficoltoso. Immaginate di dover
cambiare i permessi di tutti i file di periferica che hanno un corrispondente
dispositivo sul vostro sistema, e lasciare il resto invariato.
Quando aggiungete nuovo hardware al vostro sistema che non ha un file di
periferica per il nuovo dispositivo, dovrete crearne uno. Utenti esperti sanno
che questo può essere fatto con ./MAKEDEV all'interno della directory
/dev, ma dovete conoscere quale dispositivo creare.
Quando avete programmi che interagiscono con hardware usando i file di
periferica, non potete avere la partizione principale montata in sola lettura,
mentre non c'è ulteriore necessità di averla montata in lettura-scrittura. E non
potete avere /dev su una partizione separata, dato che mount
necessita di /dev per montare le partizioni.
Le soluzioni
Come potete immaginare, gli sviluppatori del kernel hanno trovato un certo
numero di soluzioni ai summenzionati problemi. Comunque molte di queste
presentano altri difetti come descritto in
http://www.atnf.csiro.au/people/rgooch/linux/docs/devfs.html#faq-why.
Non faremo una panoramica su queste implementazioni, ma ci focalizzeremo su
quella che è diventata parte dei sorgenti ufficiali del kernel: devfs.
devfs vince completamente
devfs risolve tutti i problemi elencati. Provvede solo le periferiche esistenti,
aggiunge nuovi nodi quando trova nuove periferiche e rende possibile montare il
root filesystem in sola lettura. Risolve anche altri problemi che non abbiamo
discusso perché di minore interesse per gli utenti.
Inoltre, con devfs non dobbiamo preoccuparci della coppia major/minor. È ancora
supportata (per compatibilità all'indietro), ma non è necessaria. Questo rende
possibile per Linux il supporto di ancora più periferiche, dato che non ci sono
più limiti (i numeri hanno sempre dei confini :)
Anche devfs ha i propri problemi che per gli utenti finali non sono realmente
visibili, ma lo sono per i manutentori del kernel. E per loro sono talmente
gravi che hanno marcato devfs come obsoleto in favore di udev che Gentoo supporta e usa come default su molte
architetture a partire dalla release 2005.0 usando kernel della serie 2.6.
Per avere maggiori informazioni sul perché devfs è marcato come obsoleto, potete
leggere queste udev
FAQ e il documento udev
contro devfs.
2.
Navigare attraverso l'albero dei device
Directory
Una delle prime cose che potreste notare è che devfs usa directory per
raggruppare insieme le periferiche. Questo migliora la leggibilità dato che
tutte le periferiche dello stesso tipo occupano la stessa directory.
Per intenderci, tutte le periferiche IDE sono all'interno della directory
/dev/ide/, così come tutte le periferiche SCSI sono in
/dev/scsi/. Dischi SCSI e IDE sono visti nello stesso modo, il che
significa che entrambe hanno la stessa struttura di sottodirectory.
Dischi IDE e SCSI sono controllati da un adattatore (integrato su scheda madre o
su schede separate), chiamato host. Ogni adattatore può avere diversi
canali. Un canale è chiamato bus. Su ogni canale, è possibile avere
diversi ID. Ogni ID identifica un disco. Questo ID è chiamato target.
Alcuni device SCSI possono avere lun multipli (Logial Unit Numbers),
device che possono controllare multipli media simultaneamente (hi-end
tapedrive). Voi avrete principalmente un singolo lun, lun0/.
Così, mentre prima avevamo /dev/hda4, ora abbiamo
/dev/ide/host0/bus0/target0/lun0/part4. Questo è molto più
semplice... no, non discutete con me... è semplice...
Nota:
Potete anche usare una nomenclatura più Unix-like per gli hard disk, come
c0b0t0u0p2. Possono essere trovati in /dev/ide/hd,
/dev/scsi/hd, ecc.
|
Per darvi un'idea delle directory, questa è una lista delle directory che ho
sul mio portatile:
Codice 2.1: Directory in /dev |
cdroms/ cpu/ discs/ floppy/
ide/ input/ loop/ misc/
netlink/ printers/ pts/ pty/
scsi/ sg/ shm/ sound/
sr/ usb/ vc/ vcc/
|
Compatibilità all'indietro usando devfs
Usare questo nuovo schema sembra divertente, ma alcuni tools e programmi
continuano ad usare il vecchio schema. Per assicurare la compatibilità è stato
creato devfsd. Questo daemon crea link simbolici con i vecchi nomi che
puntano ai nuovi file di periferica.
Codice 2.2: Link simbolico |
$ ls -l /dev/hda4
lr-xr-xr-x 1 root root 33 Aug 25 12:08 /dev/hda4 -> ide/host0/bus0/target0/lun0/part4
|
Con devfsd, potete anche configurare i permessi, creare nuovi device
file, definire azioni, ecc. Tutto questo è descritto nel prossimo capitolo.
3.
Amministrare l'albero dei dispositivi
Riavvio di devfsd
Quando modificate il file /etc/devfsd.conf, e volete forzare queste
modifiche nel vostro sistema, non dovete riavviare la macchina. A seconda delle
vostre necessità, potete usare uno dei seguenti segnali:
SIGHUP forzerà devfsd a rileggere il file di configurazione,
ricaricare gli oggetti condivisi e generare il REGISTER degli eventi per ogni
nodo in vita nell'albero dei dispositivi.
SIGUSR1 come il precedente, ma non verrà rigenerato il REGISTER degli
eventi.
Per inviare un segnale, usate semplicemente kill o killall:
Codice 3.1: Inviare un segnale SIGHUP a devfsd |
# kill -s SIGHUP `pidof devfsd`
# killall -s SIGHUP devfsd
|
Rimuovere la compatibilità attraverso i symlink
Avvertenza:
Attualmente, Gentoo non può vivere senza la compatibilità attraverso i symlink.
|
Se volete rimuovere la compatibilità ottenuta con la creazione dei numerosi
symlink in /dev dal vostro sistema Gentoo (dato che Gentoo attiva
la compatibilità di default), editate /etc/devfsd.conf e rimuovete
le seguenti due righe:
Codice 3.2: /etc/devfsd.conf per la compatibilità all'indietro |
REGISTER .* MKOLDCOMPAT
UNREGISTER .* RMOLDCOMPAT
|
Dovrete quindi riavviare il vostro sistema per rendere attive le modifiche.
Rimuovere la funzionalità di auto caricamento
Quando caricate un modulo, devfs creerà automaticamente un file di periferica.
Se non volete questo comportamento, rimuovete la seguente riga da
/etc/devfsd.conf:
Codice 3.3: /etc/devfsd.conf, funzionalità autoload |
LOOKUP .* MODLOAD
|
4.
Punti riguardanti i permessi
Impostare/cambiare i permessi con devfsd
Importante:
Queste istruzioni sono valide finché pam_console è disabilitato in
/etc/pam.d/system-auth. Se pam_console viene abilitato, PAM ha
l'ultima parola sui permessi. Ad ogni modo non si dovrebbe comunque utilizzare
pam_console, in quanto è stato rimosso da
Portage.
|
Se realmente volete impostare i permessi attraverso
/etc/devfsd.conf, usate la sintassi del seguente esempio:
Codice 4.1: Permessi in /etc/devfsd.conf |
REGISTER ^cdroms/.* PERMISSIONS root.cdrom 0660
|
Il secondo campo è il gruppo di dispositivi, partendo da /dev. È
un'espressione regolare attraverso la quale potete selezionare diversi file di
periferica con una sola regola.
Il quarto campo è il proprietario del file di periferica. Il quinto campo
contiene i permessi del file di periferica.
Impostare i permessi manualmente e farli salvare a devfsd
Questo è ciò che Gentoo fa di default: se cambiate proprietario (con
chown) e permessi (con chmod) di alcuni file di periferica,
devfsd salverà le informazioni in modo tale da renderle persistenti ad
ogni riavvio del sistema. Questo perché il file /etc/devfsd.conf
contiene le seguenti righe:
Codice 4.2: /etc/devfsd.conf per il salvataggio dei permessi |
REGISTER ^pt[sy]/.* IGNORE
CHANGE ^pt[sy]/.* IGNORE
CREATE ^pt[sy]/.* IGNORE
DELETE ^pt[sy] IGNORE
REGISTER ^log IGNORE
CHANGE ^log IGNORE
CREATE ^log IGNORE
DELETE ^log IGNORE
REGISTER .* COPY /lib/dev-state/$devname $devpath
CHANGE .* COPY $devpath /lib/dev-state/$devname
CREATE .* COPY $devpath /lib/dev-state/$devname
DELETE .* CFUNCTION GLOBAL unlink
/lib/dev-state/$devname
RESTORE /lib/dev-state
|
In altre parole, le modifiche ai file di periferica sono copiate
in /lib/dev-state non appena avviene il cambiamento
e ripristinate in /dev all'avvio
del sistema.
Un'altra possibilità è di montare /lib/dev-state in
/dev al momento dell'avvio. Per fare questo dovete essere sicuri
che devfs non venga montato automaticamente (il che significa che dovrete
ricompilare il kernel) e che esista /dev/console. Quindi, da
qualche parte all'inizio degli script di avvio del vostro sistema, dovete
mettere:
Codice 4.3: Montare /lib/dev-state in /dev |
mount --bind /dev /lib/dev-state
mount -t devfs none /dev
devfsd /dev
|
5.
Risorse
Per maggiori informazioni su devfs, controllate le seguenti risorse.
Le manpage di devfsd.conf spiegano la sintassi del file
/etc/devfsd.conf. Per vederle, digitate man devfsd.conf.
Le devfs
FAQ spiegano tutto ciò che riguarda devfs. Contengono anche informazioni
sulla struttura interna dei devfs e come i driver possono supportare devfs.
Su LinuxJournal c'è un
interessante articolo su devfs for Management and
Administration.
Daniel Robbins ha scritto una serie di articoli per IBM's DeveloperWorks sui
filesystem avanzati. Tre di questi riguardano devfs:
I contenuti di questo documento sono rilasciati sotto la licenza Creative
Commons - Attribution / Share Alike.
|