X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=fileintro.tex;h=78c2a714e4f652c00dfc270aec4234535ee9474a;hp=0d9de52bd9977d16c014fc8a868231d45b3692e1;hb=3ad06e8129067dccfa3fad74e7cf6c051231d150;hpb=9efe28fd24b23b1fca69f4c5296cb29e4372438c diff --git a/fileintro.tex b/fileintro.tex index 0d9de52..78c2a71 100644 --- a/fileintro.tex +++ b/fileintro.tex @@ -19,7 +19,7 @@ file di dati. Questo significa che si può accedere a qualunque periferica del computer, dalla seriale, alla parallela, alla console, e agli stessi dischi attraverso i -cosiddetti file di dispositivo\index{file!di dispositivo} (i \textit{device +cosiddetti file di dispositivo\index{file!di~dispositivo} (i \textit{device file}). Questi sono dei file speciali agendo sui quali i programmi possono leggere, scrivere e compiere operazioni direttamente sulle periferiche, usando le stesse funzioni che si usano per i normali file di dati. @@ -53,20 +53,21 @@ file ed introducendo le interfacce disponibili e le loro caratteristiche. \subsection{L'organizzazione di file e directory} \label{sec:file_organization} +\index{\textit{pathname}|(} In Unix, a differenza di quanto avviene in altri sistemi operativi, tutti i file vengono tenuti all'interno di un unico albero la cui radice (quella che viene chiamata \textit{root directory}) viene montata all'avvio. Un file viene identificato dall'utente usando quello che viene chiamato -\textit{pathname}\index{pathname}\footnote{il manuale della \acr{glibc} - depreca questa nomenclatura, che genererebbe confusione poiché \textit{path} - indica anche un insieme di directory su cui effettuare una ricerca (come - quello in cui si cercano i comandi). Al suo posto viene proposto l'uso di - \textit{filename} e di componente per il nome del file all'interno della - directory. Non seguiremo questa scelta dato che l'uso della parola - \textit{pathname} è ormai così comune che mantenerne l'uso è senz'altro più - chiaro dell'alternativa proposta.}, cioè il percorso che si deve fare per -accedere al file a partire dalla \textit{root directory}, che è composto da -una serie di nomi separati da una \file{/}. +\textit{pathname}\footnote{il manuale della \acr{glibc} depreca questa + nomenclatura, che genererebbe confusione poiché \textit{path} indica anche + un insieme di directory su cui effettuare una ricerca (come quello in cui si + cercano i comandi). Al suo posto viene proposto l'uso di \textit{filename} e + di componente per il nome del file all'interno della directory. Non + seguiremo questa scelta dato che l'uso della parola \textit{pathname} è + ormai così comune che mantenerne l'uso è senz'altro più chiaro + dell'alternativa proposta.}, cioè il percorso che si deve fare per accedere +al file a partire dalla \textit{root directory}, che è composto da una serie +di nomi separati da una \file{/}. All'avvio del sistema, completata la fase di inizializzazione, il kernel riceve dal bootloader l'indicazione di quale dispositivo contiene il @@ -86,38 +87,38 @@ particolare che il kernel riconosce come tale. Il suo scopo contenere una lista di nomi di file e le informazioni che associano ciascun nome al contenuto. Dato che questi nomi possono corrispondere ad un qualunque oggetto del filesystem, compresa un'altra directory, si ottiene naturalmente -un'organizzazione ad albero inserendo directory in altre directory. +un'organizzazione ad albero inserendo nomi di directory in altre directory. Un file può essere indicato rispetto alla directory corrente semplicemente specificandone il nome\footnote{Il manuale delle \acr{glibc} chiama i nomi - contenuti nelle directory \textsl{componenti} (in inglese \textit{file name - components}), noi li chiameremo più semplicemente \textit{nomi}.} da essa -contenuto. All'interno dello stesso albero si potranno poi inserire anche -tutti gli altri oggetti visti attraverso l'interfaccia che manipola i file -come le fifo, i link, i socket\index{socket} e gli stessi file di dispositivo -\index{file!di dispositivo} (questi -ultimi, per convenzione, sono inseriti nella directory \file{/dev}). +contenuti nelle directory \textsl{componenti} (in inglese \textit{file name +components}), noi li chiameremo più semplicemente \textsl{nomi} o +\textsl{voci}.} da essa contenuto. All'interno dello stesso albero si +potranno poi inserire anche tutti gli altri oggetti visti attraverso +l'interfaccia che manipola i file come le fifo, i link, i socket\index{socket} +e gli stessi file di dispositivo \index{file!di~dispositivo} (questi ultimi, +per convenzione, sono inseriti nella directory \file{/dev}). Il nome completo di un file viene chiamato \textit{pathname} ed il procedimento con cui si individua il file a cui esso fa riferimento è chiamato -risoluzione del nome (\textit{file name resolution} o \textit{pathname - resolution}). La risoluzione viene fatta esaminando il \textit{pathname} da +risoluzione del nome (\textit{filename resolution} o \textit{pathname +resolution}). La risoluzione viene fatta esaminando il \textit{pathname} da sinistra a destra e localizzando ogni nome nella directory indicata dal nome -precedente usando \file{/} come separatore\footnote{nel caso di nome vuoto, il - costrutto \file{//} viene considerato equivalente a \file{/}.}: ovviamente, +precedente usando \texttt{/} come separatore\footnote{nel caso di nome vuoto, +il costrutto \file{//} viene considerato equivalente a \file{/}.}: ovviamente, perché il procedimento funzioni, occorre che i nomi indicati come directory esistano e siano effettivamente directory, inoltre i permessi (si veda sez.~\ref{sec:file_access_control}) devono consentire l'accesso all'intero \textit{pathname}. -Se il \textit{pathname}\index{pathname} comincia per \file{/} la ricerca parte -dalla directory radice del processo; questa, a meno di un \func{chroot} (su -cui torneremo in sez.~\ref{sec:file_chroot}) è la stessa per tutti i processi -ed equivale alla directory radice dell'albero dei file: in questo caso si -parla di un \textsl{pathname assoluto}\index{pathname!assoluto}. Altrimenti la -ricerca parte dalla directory corrente (su cui torneremo in +Se il \textit{pathname} comincia per \texttt{/} la ricerca parte dalla +directory radice del processo; questa, a meno di un \func{chroot} (su cui +torneremo in sez.~\ref{sec:file_chroot}) è la stessa per tutti i processi ed +equivale alla directory radice dell'albero dei file: in questo caso si parla +di un \textsl{pathname assoluto}\index{\textit{pathname}!assoluto}. Altrimenti +la ricerca parte dalla directory corrente (su cui torneremo in sez.~\ref{sec:file_work_dir}) ed il pathname è detto \textsl{pathname - relativo}\index{pathname!relativo}. +relativo}\index{\textit{pathname}!relativo}. I nomi \file{.} e \file{..} hanno un significato speciale e vengono inseriti in ogni directory: il primo fa riferimento alla directory corrente e il @@ -134,7 +135,7 @@ Come detto in precedenza, in Unix esistono vari tipi di file; in Linux questi sono implementati come oggetti del \textit{Virtual File System} (vedi sez.~\ref{sec:file_vfs_work}) e sono presenti in tutti i filesystem unix-like utilizzabili con Linux. L'elenco dei vari tipi di file definiti dal -\textit{Virtual File System}\index{Virtual File System} è riportato in +\textit{Virtual File System}\index{\textit{Virtual~File~System}} è riportato in tab.~\ref{tab:file_file_types}. Si tenga ben presente che questa classificazione non ha nulla a che fare con @@ -145,7 +146,7 @@ Alcuni di essi, come le \textit{fifo} (che tratteremo in sez.~\ref{sec:ipc_named_pipe}) ed i \textit{socket}\index{socket} (che tratteremo in cap.~\ref{cha:socket_intro}) non sono altro che dei riferimenti per utilizzare delle funzionalità di comunicazione fornite dal kernel. Gli -altri sono i \textsl{file di dispositivo}\index{file!di dispositivo} (o +altri sono i \textsl{file di dispositivo}\index{file!di~dispositivo} (o \textit{device file}) che costituiscono una interfaccia diretta per leggere e scrivere sui dispositivi fisici; essi vengono suddivisi in due grandi categorie, \textsl{a blocchi} e \textsl{a caratteri} a seconda delle modalità @@ -198,7 +199,7 @@ VMS.\footnote{questo vale anche per i dispositivi a blocchi: la strutturazione ed è completamente trasparente all'utente. Inoltre talvolta si parla di \textsl{accesso diretto} riferendosi alla capacità, che non ha niente a che fare con tutto ciò, di effettuare, attraverso degli appositi file di - dispositivo\index{file!di dispositivo}, operazioni di I/O direttamente sui + dispositivo\index{file!di~dispositivo}, operazioni di I/O direttamente sui dischi senza passare attraverso un filesystem (il cosiddetto \textit{raw access}, introdotto coi kernel della serie 2.4.x).} @@ -296,53 +297,6 @@ infatti segue solo lo standard POSIX.1 dei sistemi Unix, ed portabilità più limitata. -% \subsection{Caratteristiche specifiche dei file in Unix} -% \label{sec:fileint_unix_spec} - -% Essendo un sistema multitasking e multiutente esistono alcune caratteristiche -% specifiche di un sistema unix-like che devono essere tenute in conto -% nell'accesso ai file. È infatti normale che più processi o programmi possano -% accedere contemporaneamente allo stesso file e devono poter eseguire le loro -% operazioni indipendentemente da quello che fanno gli altri processi. - -% Per questo motivo le strutture usate per all'accesso ai file sono relative al -% processo che effettua l'accesso. All'apertura di ogni file infatti viene -% creata all'interno del processo una apposita struttura in cui sono memorizzati -% tutti gli attributi del medesimo, che viene utilizzata per tutte le -% operazioni. Questa è una struttura che resta locale al processo stesso; in -% questo modo processi diversi possono usare le proprie strutture locali per -% accedere ai file (che può essere sempre lo stesso) in maniera assolutamente -% indipendente. - -% Questo ha delle conseguenze di cui è bene tenere conto; ad esempio in tutti i -% sistemi POSIX uno degli attributi di un file aperto è la posizione corrente nel -% file, cioè il punto nel file in cui verrebbe letto o scritto alla operazione -% successiva. Essa è rappresentata da un numero intero che indica il numero di -% byte dall'inizio del file, che viene (a meno che non si apra il file in -% append) inizializzato a zero all'apertura del medesimo. - -% Questo è uno dei dati che viene mantenuto nella suddetta struttura, per cui -% ogni processo avrà la sua posizione corrente nel file, che non sarà -% influenzata da quello che altri processi possono fare. Anzi, aprire un file -% significa appunto creare ed inizializzare una tale struttura, per cui se si -% apre due volte lo stesso file all'interno dello stesso processo, si otterranno -% due file descriptor o due stream che avranno ancora una posizione corrente nel -% file assolutamente indipendente. - -% Si tenga conto inoltre che un'altro dei dati contenuti nella struttura di -% accesso è un riferimento all'inode del file, pertanto anche se il file viene -% cancellato da un altro processo, sarà sempre possibile mantenere l'accesso ai -% dati, e lo spazio su disco non verrà rilasciato fintanto che il file non sarà -% chiuso e l'ultimo riferimento cancellato. È pertanto possibile (come vedremo -% in dettaglio in sez.~\ref{sec:file_link}) aprire un file provvisorio per -% cancellarlo immediatamente dopo; in questo modo all'uscita del programma il -% file scomparirà definitivamente dal disco, ma il file ed il suo contenuto -% saranno disponibili per tutto il tempo in cui il processo è attivo. - -% Ritorneremo su questo più avanti in sez.~\ref{sec:file_fd}, quando tratteremo -% l'input/output sui file, esaminando in dettaglio come tutto ciò viene -% realizzato. - \section{L'architettura della gestione dei file} \label{sec:file_arch_func} @@ -376,14 +330,14 @@ Linux, l'\acr{ext2}. % \textit{inode}, \textit{dentry}, \textit{dcache}. In Linux il concetto di \textit{everything is a file} è stato implementato -attraverso il \textit{Virtual File System} (da qui in avanti VFS) che è uno -strato intermedio che il kernel usa per accedere ai più svariati filesystem -mantenendo la stessa interfaccia per i programmi in user space. Esso fornisce -un livello di indirezione che permette di collegare le operazioni di -manipolazione sui file alle operazioni di I/O, e gestisce l'organizzazione di -queste ultime nei vari modi in cui i diversi filesystem le effettuano, -permettendo la coesistenza di filesystem differenti all'interno dello stesso -albero delle directory. +attraverso il \textit{Virtual File System}\index{\textit{Virtual~File~System}} +(da qui in avanti VFS) che è uno strato intermedio che il kernel usa per +accedere ai più svariati filesystem mantenendo la stessa interfaccia per i +programmi in user space. Esso fornisce un livello di indirezione che permette +di collegare le operazioni di manipolazione sui file alle operazioni di I/O, e +gestisce l'organizzazione di queste ultime nei vari modi in cui i diversi +filesystem le effettuano, permettendo la coesistenza di filesystem differenti +all'interno dello stesso albero delle directory. Quando un processo esegue una system call che opera su un file, il kernel chiama sempre una funzione implementata nel VFS; la funzione eseguirà le @@ -439,21 +393,22 @@ il descrittore di file contiene i puntatori alle funzioni che vengono usate sui file già aperti. -\subsection{Il funzionamento del VFS} +\subsection{Il funzionamento del \textit{Virtual File System}} \label{sec:file_vfs_work} -La funzione più importante implementata dal VFS è la system call \func{open} -che permette di aprire un file. Dato un pathname viene eseguita una ricerca -dentro la \textit{directory entry cache} (in breve \textit{dcache}), una -tabella che contiene tutte le \textit{directory entry} (in breve -\textit{dentry}) che permette di associare in maniera rapida ed efficiente il -pathname a una specifica \textit{dentry}. +La funzione più importante implementata dal +VFS\index{\textit{Virtual~File~System}} è la system call \func{open} che +permette di aprire un file. Dato un \index{\textit{pathname}}\textit{pathname} +viene eseguita una ricerca dentro la \textit{directory entry cache} (in breve +\textit{dcache}), una tabella che contiene tutte le \textit{directory entry} +(in breve \textit{dentry}) che permette di associare in maniera rapida ed +efficiente il \textit{pathname} a una specifica \textit{dentry}. Una singola \textit{dentry} contiene in genere il puntatore ad un \textit{inode}\index{inode}; quest'ultimo è la struttura base che sta sul disco e che identifica un singolo oggetto del VFS sia esso un file ordinario, una directory, un link simbolico, una FIFO, un file di -dispositivo\index{file!di dispositivo}, o una qualsiasi altra cosa che possa +dispositivo\index{file!di~dispositivo}, o una qualsiasi altra cosa che possa essere rappresentata dal VFS (i tipi di file riportati in tab.~\ref{tab:file_file_types}). A ciascuno di essi è associata pure una struttura che sta in memoria, e che, oltre alle informazioni sullo specifico @@ -471,8 +426,8 @@ La \textit{dcache} costituisce perci l'albero dei file, ovviamente per non riempire tutta la memoria questa vista è parziale (la \textit{dcache} cioè contiene solo le \textit{dentry} per i file per i quali è stato richiesto l'accesso), quando si vuole risolvere un nuovo -pathname il VFS deve creare una nuova \textit{dentry} e caricare -l'inode\index{inode} corrispondente in memoria. +\index{\textit{pathname}}\textit{pathname} il VFS deve creare una nuova +\textit{dentry} e caricare l'inode\index{inode} corrispondente in memoria. Questo procedimento viene eseguito dal metodo \code{lookup()} dell'inode\index{inode} della directory che contiene il file; questo viene @@ -548,7 +503,7 @@ unix-like) organizza i dati che tiene su disco attraverso l'uso di un filesystem. Una delle caratteristiche di Linux rispetto agli altri Unix è quella di poter supportare, grazie al VFS, una enorme quantità di filesystem diversi, ognuno dei quali ha una sua particolare struttura e funzionalità -proprie. Per questo, per il momento non entreremo nei dettagli di un +proprie. Per questo per il momento non entreremo nei dettagli di un filesystem specifico, ma daremo una descrizione a grandi linee che si adatta alle caratteristiche comuni di qualunque filesystem di sistema unix-like. @@ -556,7 +511,7 @@ Lo spazio fisico di un disco viene usualmente diviso in partizioni; ogni partizione può contenere un filesystem. La strutturazione tipica dell'informazione su un disco è riportata in fig.~\ref{fig:file_disk_filesys}; in essa si fa riferimento alla struttura del filesystem \acr{ext2}, che -prevede una separazione dei dati in \textit{blocks group} che replicano il +prevede una separazione dei dati in \textit{block group} che replicano il superblock (ma sulle caratteristiche di \acr{ext2} torneremo in sez.~\ref{sec:file_ext2}). È comunque caratteristica comune di tutti i filesystem per Unix, indipendentemente da come poi viene strutturata nei @@ -691,7 +646,7 @@ non sono presenti sugli altri filesystem Unix. Le principali sono le seguenti: La struttura di \acr{ext2} è stata ispirata a quella del filesystem di BSD: un filesystem è composto da un insieme di blocchi, la struttura generale è quella riportata in fig.~\ref{fig:file_filesys_detail}, in cui la partizione è divisa -in gruppi di blocchi.\footnote{non si confonda la questa definizione con +in gruppi di blocchi.\footnote{non si confonda questa definizione con quella riportata in fig.~\ref{fig:file_dirent_struct}; in quel caso si fa riferimento alla struttura usata in user space per riportare i dati contenuti in una directory generica, questa fa riferimento alla struttura