Il filesystem indica l'insieme dei supporti di memorizzazione, fisici o virtuali, collegati al sistema (in gergo: montati sul sistema). Con il DOS ogni unità disco è identificata da una lettera dell'alfabeto: solitamente, A per il floppy disk, C per il primo disco rigido, D per il secondo e così via. In ambiente Unix la situazione cambia radicalmente.
Il filesystem rappresenta una delle parti fondamentali del sistema Unix, provvedendo all'organizzazione gerarchica delle directory e dei file (vedi Filesystem tree). Tipicamente esso divide ciascun disco in porzioni (la cui taglia dipende dal sistema) chiamate blocchi numerati a partire da zero che sono poi raggruppati in quattro sezioni. Il blocco zero viene chiamato 'boot block'(blocco di inizializzazione) e non viene usato dal filesystem. Il blocco uno è chiamato 'super block' e contiene la taglia del disco e delle altre due sezioni.Il terzo blocco contiene la i-list. Tale lista è costituita da un numero variabile di blocchi che contengono l'i-node (vedi Inode). La parte restante del disco viene utilizzata per memorizzare il contenuto dei vari file.
Bisogna ricordare che la rappresentazione logica di un file non coincide di solito con quella fisica. Logicamente un file è come lo visualizziamo eseguendo per esempio il comando cat, cioè la stringa di caratteri che mi rappresenta il suo contenuto. La rappresentazione fisica invece è come il file è memorizzato sul disco. Si potrebbe per esempio pensare che un file sia memorizzato sul disco su blocchi continui, ma ciò in realtà non capita mai, poichè un file più lungo di un blocco viene suddiviso in vari pezzi memorizzati nei blocchi che sono liberi e che non sono necessariamente contigui. Quando si desidera accedere al file il filesystem va a prendere i vari blocchi e li organizza in modo tale da recuperare la sua rappresentazione logica. Le informazioni per la conversione da rappresentazione logica a rappresentazione fisica sono contenute nell'inode (vedi Inode).
Esiste una unità principale (root, radice, da non confondersi però con l'account del system manager) a cui vengono "agganciate" come sottodirectory tutte le altre unità. Questa unità rappresenta la radice (da qui il nome root) di un albero che è la struttura sulla quale si basa il filesystem di Unix. Generalmente, su quasi ogni sistema Unix, sono presenti alcune directory che rivestono una certa importanza all'interno del sistema e che hanno quasi sempre lo stesso nome. Tra queste ricordiamo :
Queste directory a loro volta possono contenere delle sotto directory. Per esempio nella directory /etc abbiamo il file delle password /ect/passwd (vedi Username e password).
Ogni directory ha due entrate sempre presenti: la prima è "." (punto) che rappresenta un riferimento a se stessa, mentre la seconda è ".." che punta al genitore nella struttura ad albero. Un'eccezione è costituita dalla directory root che è denominata con "/" e inoltre ".." è un link a "/".
![]() |
Ciascun oggetto nel filesystem con un nome può essere specificato con un pathname, che rappresenta il percorso di un'entrata dalla radice del filesystem. Grazie a questo percorso il sistema trova l'inode relativo all'entrata. I pathnames possono essere assoluti, quando partono dalla directory root e quindi iniziano con "/", o relativi quando iniziano dalla directory corrente del processo al quale si riferisce.
Una directory non è altro che una lista di nomi e numeri di inode. Il nome consiste di stringhe di caratteri, esclusi "/" e il carattere nullo, di lunghezza di solito di 1024 byte. Tali stringhe rappresentano nomi di file, directory o altri oggetti memorizzati nel filesystem.
Associati a ciascun nome c'è un puntatore numerico che è un indice su disco per un inode, che contiene informazioni su una particolare entrata del filesystem. Questo è tutto quello che è contenuto nella directory. Non ci sono informazioni sui nomi dei possessori o sui dati. Una directory è solo un semplice database relazionale che mappa i nomi con i numeri di inode. Non esiste nessuna restrizione su quanti nomi possono puntare allo stesso inode e inoltre diverse directory possono avere nomi associati allo stesso inode. Questi sono conosciuti come link al file. Questo implica che non si può effettivamente cancellare un file se prima non sono stati rimossi tutti i links ad esso. Dopo che l'ultimo link è stato rimosso e il file chiuso, il kernel può liberare la memoria occupata dal file perché senza link nessun utente può accedere ad esso.
Per ogni oggetto nel filesystem, Unix memorizza le informazioni gestionali in una struttura chiamata inode, che risiede su disco ed ha un indice che indica la sua posizione all'interno di un array di inode. Contiene di solito:
Il primo elemento restituisce una lista di 13 numeri di blocchi dove nei primi dieci sono memorizzati i primi dieci blocchi del file. Se il file è più lungo di dieci blocchi, l'undicesimo elemento della lista nell'inode contiene un puntatore ad un blocco nel quale sono memorizzati altri 256 numeri di blocchi. Analogamente avviene per il dodicesimo e il tredicesimo elemento della lista. Con tale struttura un file Unix può aver al massimo una taglia di 16842762 blocchi (17246988288 byte) anche se il sistema Unix (fortunatamente!) impone di solito un limite pratico alle dimensioni di un file di uno o due milioni di byte. Tale elemento quindi è quello che permette la ricostruzione logica del file.
Le ultime tre caratteristiche associate alle informazioni UID/GID circa i processi eseguibili, sono i dati fondamentali che Unix usa per gestire tutte le operazioni sulla sicurezza. La struttura dell'inode è visualizzata nella figura 5.2.
posizione dell'oggetto | tipo dell'oggetto | taglia dell'oggetto (in bytes) |
ctime | mtime | atime |
UID | GID | permessi per i file |
contatore dei riferimenti | posizione dei dati sul disco |
Ad ogni entrata del filesystem sono associate delle autorizzazioni che stabiliscono quello che i vari utenti possono fare con essa. In Unix questi permessi sono rappresentati da dieci caratteri. Il primo carattere indica il tipo di file descritto nella tabella 5.1.
I successivi nove caratteri presi a gruppi di tre indicano chi può fare che cosa su un determinato file. Ci sono tre tipi di permessi: r = permesso di lettura, w = permesso di scrittura ed x = permesso di esecuzione. In modo simile, ci sono tre classi di permessi: owner = il possessore del file, group = gli utenti che appartengono al gruppo del possessore file ed infine other = tutti gli altri utenti del sistema eccetto il superuser. Se eseguiamo il comando ls -la possiamo farci un'idea dei permessi in UNIX:
Prendiamo ad esempio la terza riga della lista. Leggendo i permessi nella colonna più a sinistra sappiamo che il file .pinetemp.000 è posseduto dall'utente berry che appartiene al gruppo users con i seguenti permessi: il possessore può accederlo sia in lettura sia in scrittura ma non in esecuzione (rw-) mentre tutti gli utenti appartenenti allo stesso gruppo users e tutti gli altri indistintamente, possono accedere al file esclusivamente in lettura (r--).
$ ls -la total 7 drwxrwxrwt root root 8192 Jan 25 23:05 . drwxr-xr-x root root 1024 Dec 28 18:07 .. -rw-r--r-- berry users 6 Jan 25 23:05 .pinetemp.000 drwxr-xr-x berry users 1024 Jan 25 23:05 .test -rwx------ wood users 1 Jan 25 18:28 19067haa -rw-r--r-- berry 1 Jan 16 12:38 filter.14428 drwxr-xr-x root root 1024 Jan 12 13:18 screens
I permessi possono essere applicati anche ai device e alle FIFO, ma non sono applicabili ai link simbolici. Si può osservare che si può avere un accesso in esecuzione senza avere un accesso in lettura, perché il proprietario del file può non voler rendere nota la funzione di un programma e può voler evitare le copie del programma. Si può avere anche l'accesso in lettura ma non in esecuzione. In questo caso si può fare una copia del file ed eseguirlo. Ci sono due differenze importanti: la prima è che il file avrà un differente pathname assoluto, la seconda è che si è possessori della copia senza esserlo dell'originale. Un'altra osservazione riguarda alcune versioni di Unix (compreso Linux), per le quali uno script per essere eseguibile deve avere sia il permesso in lettura che in esecuzione.
Un buon "settaggio" del file dei permessi garantisce una buona sicurezza del sistema.
Per cambiare i permessi si utilizza il comando chmod(), che permette di scrivere i permessi in notazione ottale con quattro digit. Nella notazione ottale il 2 sta per il permesso in scrittura, 4 per permesso in lettura e 1 per permesso in esecuzione.
L'umask (abbreviazione di user file-creation mode mask) è un numero ottale di quattro cifre che viene usato per determinare i permessi su un file appena creato. Ogni processo ha un umask che viene ereditato dal processo padre. L'umask specifica i permessi che non vuoi dare per default a un nuovo file creato o ad una directory. L'umask funziona effettuando l'AND bit a bit tra i permessi originali e il complemento ad 1 dell'umask stessa. Ci spieghiamo meglio con un esempio:
supponiamo di creare un file di nome "pippo" (scusate l'eccesso di fantasia) e l'umask a 002. Assegniamogli i permessi in lettura e scrittura per tutti con il comando:
chmod 0666 pippo
L'operazione compiuta dall'umask sarà la seguente:
000 110 110 110 (permessi assegnati al file pippo)
111 111 111 101 (complemento ad 1 dell'umask)
---------------
000 110 110 100
Come risultato abbiamo l'annullamento del permesso di scrittura per gli altri!
I più usati valori per l'umask sono 022, 027, 077. Per default è usato il valore 022 che nega i permessi in scrittura ai componenti del gruppo e agli altri.
Precedente | Torna su | Successivo |