4.6.3 I tipi di file

In GNU/Linux possono essere utilizzati vari tipi di file, ognuno identificato da uno specifico codice che filesystem ext2 memorizza nei metadati relativi al file considerato (i primi 4 bit del campo i_mode).


Codice|-Tipo-di file----------|
|---1|-FIFO-(o named pipe)---|
|   2| dispositivo a caratteri   |
|   4| directory              |
|   6| dispositivo a blocchi    |
|  1102| fisylem sbtoanldica lrindk (o(o regsyumllarin fikl)e)
---14--socket-----------------

Tabella 4.5: Possibili tipi di file.

La tab. 4.5 riporta i tipi di file riconosciuti da GNU/Linux che sono illustrati di seguito.
4.6.3.1 I file “standard” o regular file

A tale categoria appartiene la maggior parte dei file presenti sui filesystem. Tale tipo rappresenta il file nella sua accezione di base, ovvero un contenitore di informazioni senza caratteristiche particolari. I file di questo tipo sono anche detti regular file.

4.6.3.2 Le directory

Una directory è un file particolare che contiene un elenco di elementi detti dentry (directory entry), ognuno dei quali è costituito da (v. fig. 4.7)


pict
Figura 4.7: L’elemento delle directory: la dentry.

I numeri degli inode presenti in tale elenco, costituiscono i riferimenti univoci agli inode relativi ai file (o directory) accessibili da tale directory, cioè i file (o directory) contenuti all’interno della directory. Più in dettaglio, le dentry hanno la struttura riportata di seguito (sintassi C)

struct ext2_dir_entry_2
{
    __u32   inode;                  /* Inode number */
    __u16   rec_len;                /* Directory entry length */
    __u8    name_len;               /* File name length */
    __u8    file_type;              /* File type */
    char    name[EXT2_NAME_LEN];    /* File name */
}
Si tenga presente che la dimensione del campo name è variabile, ovvero contiene il nome del file (o directory) allineato a double word, mediante l’inserimento di eventuali caratteri nulli aggiunti alla fine del nome. Il numero dei byte nulli (padding byte) da aggiungere in coda al nome dell’inode, per l’allineamento a double word (4 byte) è dato da18

padding byte = 4- (namexlenmod 4)

Il campo name_len contiene la lunghezza effettiva del nome del file, ovvero il numero di caratteri dai quali esso è effettivamente costituito, mentre il campo rec_len indica la lunghezza dell’intera dentry. Il campo file_type contiene un numero che indica il tipo del file secondo quanto riportato nella tab. 4.6.


filextype-|Tipo-di file-----------|
|----0-|Sconosciuto------------|
|    1 |File standard (o regular file)|
|    2 |Directory              |
|    3 |Dispositivo a caratteri    |
|    45 |DFiIspFoOsit(oivona amebdlocpchipie)    |
|    6 |Socket                |
-----7--Symbolic link (o symlink)

Tabella 4.6: Possibili valori del campo file_type delle dentry.

Ad esempio la dentry relativa ad un inode per mezzo del nome pippo, conterrà nel campo name_len il valore 5 (“pippo” è formato da 5 caratteri), nel campo name il valore pippo seguito da 3 caratteri nulli (NUL) per l’allineamento a double word (infatti 5 mod 4 = 1, per cui i byte nulli da aggiungere in coda al nome sono 4 - 1 = 3). Il campo rec_len conterrà la dimensione totale della dentry, ovvero 4 + 2 + 1 + 1 + 5 + 3 = 16.

Di seguito è riportato il contenuto di una directory.

00000000  dc b9 03 00 0c 00 01 02  2e 00 00 00 fd 05 00 00  |................|
00000010  0c 00 02 02 2e 2e 00 00  f4 b9 03 00 10 00 05 02  |................|
00000020  6d 79 64 69 72 00 00 00  f9 b9 03 00 10 00 07 02  |mydir...........|
00000030  74 65 73 74 64 69 72 00  0d ba 03 00 10 00 08 01  |testdir.........|
00000040  74 65 73 74 66 69 6c 65  fe b9 03 00 14 00 09 01  |testfile........|
00000050  6f 74 68 65 72 2e 6f 67  67 00 00 00 fa b9 03 00  |other.ogg.......|
00000060  a4 0f 0a 01 6d 79 66 69  6c 65 2e 6a 70 67 00 00  |....myfile.jpg..|
00000070  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
[...]
L’esempio riportato mostra una directory contenente al suo interno le directory mydir e testdir ed i file testfile, other.ogg e myfile.jpg. Come precedentemente illustrato, all’interno della directory sono sempre presenti le directory . e .. che indicano rispettivamente la directory stessa e la directory padre.

Quando viene specificato il percorso di un file (path), il kernel ricerca nelle dentry delle varie directory che costituiscono il path del file, il nome indicato, per trovare di volta in volta il relativo numero di inode e per poter così accedere alle informazioni in esso contenute. Una volta raggiunto l’inode relativo al file indicato, il sistema ha i riferimenti per poter accedere alle informazioni contenute nel file stesso (si ricordi che la root directory è sempre contenuta nell’inode 2). Un esempio di accesso ad un file è riportato nella fig. 4.8).


pict
Figura 4.8: Esempio di accesso ad un file.

4.6.3.3 I link

Nei sistemi Unix-like dunque un file (o directory) è rappresentato da un inode, all’interno del quale sono memorizzati i sui metadati, ovvero i suoi dati caratteristici ed in esso vi sono i riferimenti ai blocchi che contengono il contenuto vero e proprio del file. Come si può notare dalla struttura, negli inode non viene memorizzato il nome del file, poiché esso non è una caratteristica intrinseca del file stesso (il file è individuato univocamente dal numero di inode), ma è semplicemente un’etichetta memorizzata nelle dentry che serve come riferimento per poter accedere all’inode relativo al file. Quindi, sebbene un nome di file individui un solo inode, lo stesso inode può essere individuato da più nomi di file. L’associazione tra il nome del file e l’inode a cui si riferisce, memorizzato nelle dentry, è detta hard link (physical link, collegamento fisico o collegamento diretto). Dunque, un file (inode) può avere più hard link (più nomi) che si riferiscono ad esso.

Quando viene creato un hard link, viene incrementato il contatore dei riferimenti nell’inode relativo (i_links_count). In questo modo il sistema tiene traccia di quanti hard link sono riferiti ad ogni inode. L’eliminazione di un hard link non implica l’eliminazione di un file, ovvero dell’inode relativo, ma un file viene effettivamente eliminato dal filesystem soltanto quando l’ultimo degli hard link ad esso relativi viene eliminato e nessun processo sta utilizzando il file (inode) in questione.19

Alla creazione di un file viene sempre creato un hard link ad esso relativo, cioè il primo riferimento a se stesso che è una dentry all’interno della directory che lo contiene. In tale dentry sarà memorizzato il nome associato a tale hard link (il nome del file).

È possibile creare hard link soltanto sui filesystem che li supportano e, comunque, sia l’inode che il relativo hard link devono trovarsi sullo stesso filesystem;

In GNU/Linux è possibile creare hard link relativi soltanto a file, non a directory, poiché sarebbe altrimenti possibile creare dei riferimenti circolari (catene di collegamenti chiuse su se stesse), complessi da gestire e soprattutto da rimuovere.

GNU/Linux permette la creazione di file particolari che il sistema riconosce come tali: i symbolic link (symlink, soft link o collegamenti simbolici). Essi sono dei file che contengono soltanto il path relativo al file o directory a cui si riferiscono. Quando i comandi di sistema hanno a che fare con un symbolic link essi per default considerano direttamente il file a cui essi si riferiscono (ricavandolo dal loro contenuto), piuttosto che considerarli alla stregua degli altri file. Si dice in genere che i comandi “seguono” i symbolic link (symbolic link dereference), nel senso che si accorgono che si tratta di un symbolic link e quindi compiono l’operazione sul file o directory a cui il symbolic link si riferisce (le system call del kernel fanno automaticamente l’operazione di dereference dei symbolic link), tranne l’operazione di eliminazione (rm - v. sez. 5.6) che si limita a cancellare soltanto il symbolic link e non il file a cui esso si riferisce. È comunque possibile, in genere, indicare ai comandi, con un’apposita opzione, di non seguire automaticamente i symlink ma di trattarli come tutti gli altri file.

È importante sottolineare il fatto che il sistema non tiene conto, all’interno degli inode, dei symbolic link che si riferiscono ad essi, come invece avviene per gli hard link: quindi è possibile ottenere dei dangling link (collegamenti penzolanti) ovvero dei symbolic link che non sono collegati ad un file o ad una directory esistente. Infatti, alla creazione di un symbolic link il sistema non attua nessun controllo relativo al fatto che il file o la directory a cui esso si riferisce esista e neanche alla cancellazione di un file (rimozione dell’ultimo hard link) il sistema tiene conto di eventuali symbolic link che si riferiscono ad esso.

Per contro, i symbolic link non hanno le restrizioni degli hard link, quindi è possibile anche creare symbolic link relativi a file o directory situati in filesystem diversi da quello in cui viene creato il link.

I link vengono creati per mezzo del comando ln (man page ln(1)).

____________________________________________________________________

Comando: ln
Path: /bin/ln

SINTASSI  
$ ln [option] target [link_name]  
DESCRIZIONE

____________________________________________________________________

Ad esempio, è possibile creare un hard link al file ~/.bashrc20 (cioè una dentry in una directory, non un file) con il comando

 
$ ln ~/.bashrc myhlink  
e così i nomi myhlink (nella working directory) e .bashrc (nella home directory) si riferiranno in seguito allo stesso identico file, che sarà fisicamente rimosso dal sistema soltanto quando lo saranno entrambi i link ad esso relativi.

È possibile creare un symbolic link al file ~/.bashrc (cioè un file vero e proprio) con il comando

 
$ ln -s ~/.bashrc myslink  
anche nel caso in cui il file ~/.bashrc non esista. In tal caso myslink sarebbe un dangling link poiché non si riferirebbe ad un file (o directory) effettivamente esitente.

Con i symbolic link possono essere creati dei riferimenti circolari (catene di collegamenti chiuse su se stesse) che potrebbero essere problematici per certi comandi. Si supponga infatti di creare un symbolic link /boot/myboot alla directory /boot e di visualizzare il contenuto della directory /boot in modo da scendere ricorsivamente in tutte le sottodirectory in essa contenute, impartendo il comando

 
$ ls -r /boot  
Così facendo il comando ls esaminerebbe la directory /boot, quindi la directory /boot/myboot, ovvero la directory /boot stessa che ovviamente contiene /boot/myboot e quindi esaminerebbe /boot/myboot/myboot, e così via, entrando in un loop infinito. In pratica ciò non genera un loop infinito poiché il sistema è limitato ad effettuare un determinato numero massimo di dereferenziazioni (seguimenti) di symbolic link quando viene effettuata un’operazione di risoluzione del nome di un oggetto del filesystem.

La creazione di un link, sia hard che symbolic, non occupa molto spazio sul disco, poiché non effettua la copia del contenuto del file al quale il link si riferisce.

Il filesystem ext2 gestisce anche i cosiddetti fast link, cioè speciali symbolic link che si riferiscono ad un oggetto del filesystem il cui path ha una lunghezza inferiore a 60 caratteri. In tal caso infatti non vengono utilizzati dei blocchi di dati per memorizzare il path dell’oggetto del filesystem al quale il symbolic (fast) link si riferisce, ma questo viene memorizzato direttamente nell’inode, nello spazio usualmente riservato per memorizzare i riferimenti ai blocchi contenenti i dati del file (lo spazio a disposizione è proprio 15 × 4 = 60 byte - v. il campo i_block della struttura dell’inode riportata a pag. 383). I fast link sono quindi caratterizzati dal fatto che non utilizzano alcun blocco dati per la memorizzazione del loro contenuto (utilizzano soltanto un inode). Un fast link viene creato automaticamente con il comando ln, quando si crea un symbolic link che si riferisce ad un oggetto del filesystem il cui path è inferiore a 60 caratteri.

Il contenuto di un symbolic link (o fast link) può essere visualizzato con il comando readlink (man page readlink(1)).

____________________________________________________________________

Comando: readlink
Path: /usr/bin/readlink

SINTASSI  
$ readlink [option] filename  
DESCRIZIONE

____________________________________________________________________________________________________________________
4.6.3.4 I file speciali

Alcuni file in GNU/Linux hanno caratteristiche particolari e per questo sono detti file speciali e si dividono in FIFO (o named pipe), file di dispositivo e socket (Unix domain socket). Le FIFO ed i file di dispositivo possono essere creati con il comando mknod (man page mknod(1)) (make inode).

__________________________________________________________________________________________________________

Comando: mknod
Path: /bin/mknod

SINTASSI  
$ mknod [option] name type [major minor]  
DESCRIZIONE

________________________

mentre i socket possono essere creati con il comando socket (man page socket(2)).