%% License".
%%
-\chapter{File e directory}
+\chapter{La gestione di file e directory}
\label{cha:files_and_dirs}
In questo capitolo tratteremo in dettaglio le modalità con cui si gestiscono
-file e directory, iniziando dalle funzioni di libreria che si usano per
-copiarli, spostarli e cambiarne i nomi. Esamineremo poi l'interfaccia che
-permette la manipolazione dei vari attributi di file e directory ed alla fine
-prenderemo in esame la struttura di base del sistema delle protezioni e del
-controllo dell'accesso ai file e le successive estensioni (\textit{Extended
- Attributes}, ACL, quote disco, \textit{capabilities}). Tutto quello che
-riguarda invece la manipolazione del contenuto dei file è lasciato ai capitoli
-successivi.
+file e directory, iniziando da un approfondimento dell'architettura del
+sistema illustrata a grandi linee in sez.~\ref{sec:file_arch_overview} ed
+illustrando le principali caratteristiche di un filesystem e le interfacce
+che consentono di controllarne il montaggio e lo smontaggio.
+
+Esamineremo poi le funzioni di libreria che si usano per copiare, spostare e
+cambiare i nomi di file e directory ed esamineremo l'interfaccia che permette
+la manipolazione dei loro attributi. Tratteremo inoltre la struttura di base
+del sistema delle protezioni e del controllo dell'accesso ai file e le
+successive estensioni (\textit{Extended Attributes}, ACL, quote disco,
+\textit{capabilities}). Tutto quello che riguarda invece la manipolazione del
+contenuto dei file è lasciato ai capitoli successivi.
+
+
+
+\section{L'architettura della gestione dei file}
+\label{sec:file_arch_func}
+
+In questa sezione tratteremo con maggiori dettagli rispetto a quanto visto in
+sez.~\ref{sec:file_arch_overview} il \textit{Virtual File System} di Linux e
+come il kernel può gestire diversi tipi di filesystem, descrivendo prima le
+caratteristiche generali di un filesystem di un sistema unix-like, per poi
+trattare in maniera un po' più dettagliata il filesystem più usato con Linux,
+l'\acr{ext2} (e derivati).
+
+
+\subsection{Il funzionamento del \textit{Virtual File System} di Linux}
+\label{sec:file_vfs_work}
+
+% articolo interessante:
+% http://www.ibm.com/developerworks/linux/library/l-virtual-filesystem-switch/index.html?ca=dgr-lnxw97Linux-VFSdth-LXdW&S_TACT=105AGX59&S_CMP=GRlnxw97
+
+\itindbeg{Virtual~File~System}
+
+Come illustrato brevemente in sez.~\ref{sec:file_arch_overview} in Linux il
+concetto di \textit{everything is a file} è stato implementato attraverso il
+\textit{Virtual File System}, la cui struttura generale è illustrata in
+fig.~\ref{fig:file_VFS_scheme}. Il VFS definisce un insieme di funzioni che
+tutti i filesystem devono implementare. L'interfaccia comprende tutte le
+funzioni che riguardano i file e le operazioni sono suddivise su tre tipi di
+oggetti: \textit{filesystem}, \itindex{inode} \textit{inode} e \textit{file},
+corrispondenti a tre apposite strutture definite nel kernel.
+
+Il VFS usa una tabella mantenuta dal kernel che contiene il nome di ciascun
+filesystem supportato: quando si vuole inserire il supporto di un nuovo
+filesystem tutto quello che occorre è chiamare la funzione
+\code{register\_filesystem} passandole un'apposita struttura
+\code{file\_system\_type} che contiene i dettagli per il riferimento
+all'implementazione del medesimo, che sarà aggiunta alla citata tabella.
+
+In questo modo quando viene effettuata la richiesta di montare un nuovo disco
+o di qualunque altro dispositivo che può contenere un filesystem, il VFS può
+ricavare dalla citata tabella il puntatore alle funzioni da chiamare nelle
+operazioni di montaggio. Queste sono responsabili inizializzare tutte le
+variabili interne e restituire uno speciale descrittore dei filesystem montati
+al VFS; attraverso quest'ultimo diventa possibile accedere alle funzioni
+specifiche per l'uso di quel filesystem.
+
+Il primo oggetto usato dal VFS è il descrittore di filesystem (o
+\textit{filesystem descriptor}), un puntatore ad una apposita struttura che
+contiene vari dati come le informazioni comuni ad ogni filesystem, i dati
+privati relativi a quel filesystem specifico, e i puntatori alle funzioni del
+kernel relative al filesystem. Il VFS può così usare le funzioni contenute nel
+\textit{filesystem descriptor} per accedere alle funzioni specifiche di quel
+filesystem.
+
+Gli altri due descrittori usati dal VFS sono relativi agli altri due oggetti
+su cui è strutturata l'interfaccia. Ciascuno di essi contiene le informazioni
+relative al file in uso, insieme ai puntatori alle funzioni dello specifico
+filesystem usate per l'accesso dal VFS. In particolare il descrittore
+\itindex{inode} dell'\textit{inode} contiene i puntatori alle funzioni che
+possono essere usate su qualunque file (come \func{link}, \func{stat} e
+\func{open}), mentre il descrittore di file contiene i puntatori alle funzioni
+che vengono usate sui file già aperti.
+
+La funzione più importante implementata dal VFS è la \textit{system call}
+\func{open} che permette di aprire un file. Dato un \itindex{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
+\itindex{inode} \textit{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
+\index{file!di~dispositivo} 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
+file, contiene anche il riferimento alle funzioni (i \textsl{metodi} del VFS)
+da usare per poterlo manipolare.
+
+Le \textit{dentry} ``vivono'' in memoria e non vengono mai salvate su disco,
+vengono usate per motivi di velocità, gli \itindex{inode} \textit{inode} invece
+stanno su disco e vengono copiati in memoria quando serve, ed ogni cambiamento
+viene copiato all'indietro sul disco (aggiornando i cosiddetti
+\textsl{metadati} del file), gli \itindex{inode} inode che stanno in memoria
+sono \itindex{inode} inode del VFS ed è ad essi che puntano le singole
+\textit{dentry}.
+
+La \textit{dcache} costituisce perciò una sorta di vista completa di tutto
+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
+\itindex{pathname} \textit{pathname} il VFS deve creare una nuova
+\textit{dentry} e caricare \itindex{inode} l'inode corrispondente in memoria.
+
+Questo procedimento viene eseguito dal metodo \code{lookup()} \itindex{inode}
+dell'inode della directory che contiene il file; questo viene installato nelle
+relative strutture in memoria quando si effettua il montaggio lo specifico
+filesystem su cui l'inode va a vivere.
+
+Una volta che il VFS ha a disposizione la \textit{dentry} (ed il relativo
+\textit{inode}) diventa possibile accedere alle varie operazioni sul file come
+la \func{open} per aprire il file o la \func{stat} per leggere i dati
+\itindex{inode} dell'inode e passarli in user space.
+
+L'apertura di un file richiede comunque un'altra operazione, l'allocazione di
+una struttura di tipo \struct{file} in cui viene inserito un puntatore alla
+\textit{dentry} e una struttura \struct{f\_ops} che contiene i puntatori ai
+metodi che implementano le operazioni disponibili sul file. In questo modo i
+processi in \textit{user space} possono accedere alle operazioni attraverso
+detti metodi, che saranno diversi a seconda del tipo di file (o dispositivo)
+aperto (su questo torneremo in dettaglio in sez.~\ref{sec:file_fd}). Un elenco
+delle operazioni previste dal kernel è riportato in
+tab.~\ref{tab:file_file_operations}.
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|p{8cm}|}
+ \hline
+ \textbf{Funzione} & \textbf{Operazione} \\
+ \hline
+ \hline
+ \textsl{\code{open}} & Apre il file (vedi sez.~\ref{sec:file_open}).\\
+ \textsl{\code{read}} & Legge dal file (vedi sez.~\ref{sec:file_read}).\\
+ \textsl{\code{write}} & Scrive sul file (vedi
+ sez.~\ref{sec:file_write}).\\
+ \textsl{\code{llseek}} & Sposta la posizione corrente sul file (vedi
+ sez.~\ref{sec:file_lseek}).\\
+ \textsl{\code{ioctl}} & Accede alle operazioni di controllo
+ (vedi sez.~\ref{sec:file_ioctl}).\\
+ \textsl{\code{readdir}}& Legge il contenuto di una directory (vedi
+ sez.~\ref{sec:file_dir_read}).\\
+ \textsl{\code{poll}} & Usata nell'I/O multiplexing (vedi
+ sez.~\ref{sec:file_multiplexing}).\\
+ \textsl{\code{mmap}} & Mappa il file in memoria (vedi
+ sez.~\ref{sec:file_memory_map}).\\
+ \textsl{\code{release}}& Chiamata quando l'ultimo riferimento a un file
+ aperto è chiuso.\\
+ \textsl{\code{fsync}} & Sincronizza il contenuto del file (vedi
+ sez.~\ref{sec:file_sync}).\\
+ \textsl{\code{fasync}} & Abilita l'I/O asincrono (vedi
+ sez.~\ref{sec:file_asyncronous_io}) sul file.\\
+ \hline
+ \end{tabular}
+ \caption{Operazioni sui file definite nel VFS.}
+ \label{tab:file_file_operations}
+\end{table}
+
+In questo modo per ciascun file diventano possibili una serie di operazioni
+(non è detto che tutte siano disponibili), che costituiscono l'interfaccia
+astratta del VFS. Qualora se ne voglia eseguire una, il kernel andrà ad
+utilizzare l'opportuna funzione dichiarata in \struct{f\_ops} appropriata al
+tipo di file in questione.
+
+Pertanto è possibile scrivere allo stesso modo sulla porta seriale come su un
+normale file di dati; ovviamente certe operazioni (nel caso della seriale ad
+esempio la \code{seek}) non saranno disponibili, però con questo sistema
+l'utilizzo di diversi filesystem (come quelli usati da Windows o MacOS) è
+immediato e relativamente trasparente per l'utente ed il programmatore.
+\itindend{Virtual~File~System}
+
+
+\subsection{Il funzionamento di un filesystem Unix}
+\label{sec:file_filesystem}
+
+Come già accennato in sez.~\ref{sec:file_arch_overview} Linux (ed ogni sistema
+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
+filesystem specifico, ma daremo una descrizione a grandi linee che si adatta
+alle caratteristiche comuni di qualunque filesystem di un sistema unix-like.
+
+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{block group} che replicano il
+cosiddetto \textit{superblock} (ma sulle caratteristiche di \acr{ext2} e
+derivati torneremo in sez.~\ref{sec:file_ext2}). È comunque caratteristica
+comune di tutti i filesystem per Unix, indipendentemente da come poi viene
+strutturata nei dettagli questa informazione, prevedere una divisione fra la
+lista degli \itindex{inode} inode e lo spazio a disposizione per i dati e le
+directory.
+
+\begin{figure}[!htb]
+ \centering
+ \includegraphics[width=14cm]{img/disk_struct}
+ \caption{Organizzazione dello spazio su un disco in partizioni e
+ filesystem.}
+ \label{fig:file_disk_filesys}
+\end{figure}
+
+Se si va ad esaminare con maggiore dettaglio la strutturazione
+dell'informazione all'interno del singolo filesystem (tralasciando i dettagli
+relativi al funzionamento del filesystem stesso come la strutturazione in
+gruppi dei blocchi, il superblock e tutti i dati di gestione) possiamo
+esemplificare la situazione con uno schema come quello esposto in
+fig.~\ref{fig:file_filesys_detail}.
+
+\begin{figure}[!htb]
+ \centering
+ \includegraphics[width=14cm]{img/filesys_struct}
+ \caption{Strutturazione dei dati all'interno di un filesystem.}
+ \label{fig:file_filesys_detail}
+\end{figure}
+
+Da fig.~\ref{fig:file_filesys_detail} si evidenziano alcune delle
+caratteristiche di base di un filesystem, sulle quali è bene porre attenzione
+visto che sono fondamentali per capire il funzionamento delle funzioni che
+manipolano i file e le directory che tratteremo nel prossimo capitolo; in
+particolare è opportuno ricordare sempre che:
+
+\begin{enumerate}
+
+\item L'\textit{inode} \itindex{inode} contiene tutte le informazioni (i
+ cosiddetti \textsl{metadati}) riguardanti il file: il tipo di file, i
+ permessi di accesso, le dimensioni, i puntatori ai blocchi fisici che
+ contengono i dati e così via. Le informazioni che la funzione \func{stat}
+ fornisce provengono dall'\textit{inode}; dentro una directory si troverà
+ solo il nome del file e il numero \itindex{inode} dell'\textit{inode} ad esso
+ associato, cioè quella che da qui in poi chiameremo una \textsl{voce} (come
+ traduzione dell'inglese \textit{directory entry}, che non useremo anche per
+ evitare confusione con le \textit{dentry} del kernel di cui si parlava in
+ sez.~\ref{sec:file_vfs_work}).
+
+\item Come mostrato in fig.~\ref{fig:file_filesys_detail} si possono avere più
+ voci che puntano allo stesso \textit{inode}. Ogni \textit{inode} ha un
+ contatore che contiene il numero di riferimenti che sono stati fatti ad esso
+ (il cosiddetto \textit{link count}); solo quando questo contatore si annulla
+ i dati del file vengono effettivamente rimossi dal disco. Per questo la
+ funzione per cancellare un file si chiama \func{unlink}, ed in realtà non
+ cancella affatto i dati del file, ma si limita ad eliminare la relativa voce
+ da una directory e decrementare il numero di riferimenti \itindex{inode}
+ nell'\textit{inode}.
+
+\item Il numero di \textit{inode} nella voce si riferisce ad un \textit{inode}
+ nello stesso filesystem e non ci può essere una directory che contiene
+ riferimenti ad \itindex{inode} \textit{inode} relativi ad altri filesystem.
+ Questo limita l'uso del comando \cmd{ln} (che crea una nuova voce per un
+ file esistente con la funzione \func{link}) al filesystem corrente.
+
+\item Quando si cambia nome ad un file senza cambiare filesystem, il contenuto
+ del file non viene spostato fisicamente, viene semplicemente creata una
+ nuova voce per \itindex{inode} l'\textit{inode} in questione e rimossa la
+ vecchia (questa è la modalità in cui opera normalmente il comando \cmd{mv}
+ attraverso la funzione \func{rename}). Questa operazione non modifica
+ minimamente neanche l'\textit{inode} del file dato che non si opera su
+ questo ma sulla directory che lo contiene.
+
+\item Gli \textit{inode} dei file, che contengono i \textsl{metadati} ed i
+ blocchi di spazio disco, che contengono i dati, sono risorse indipendenti ed
+ in genere vengono gestite come tali anche dai diversi filesystem; è pertanto
+ possibile sia esaurire lo spazio disco (caso più comune) che lo spazio per
+ gli \textit{inode}, nel primo caso non sarà possibile allocare ulteriore
+ spazio, ma si potranno creare file (vuoti), nel secondo non si potranno
+ creare nuovi file, ma si potranno estendere quelli che ci sono.
+
+\end{enumerate}
+
+Infine si noti che, essendo file pure loro, il numero di riferimenti esiste
+anche per le directory; per cui, se a partire dalla situazione mostrata in
+fig.~\ref{fig:file_filesys_detail} creiamo una nuova directory \file{img}
+nella directory \file{gapil}, avremo una situazione come quella in
+fig.~\ref{fig:file_dirs_link}, dove per chiarezza abbiamo aggiunto dei numeri
+di \itindex{inode} inode.
+
+\begin{figure}[!htb]
+ \centering
+ \includegraphics[width=14cm]{img/dir_links}
+ \caption{Organizzazione dei \textit{link} per le directory.}
+ \label{fig:file_dirs_link}
+\end{figure}
+
+La nuova directory avrà allora un numero di riferimenti pari a due, in quanto
+è referenziata dalla directory da cui si era partiti (in cui è inserita la
+nuova voce che fa riferimento a \texttt{img}) e dalla voce ``\texttt{.}'' che
+è sempre inserita in ogni directory; questo vale sempre per ogni directory che
+non contenga a sua volta altre directory. Al contempo, la directory da cui si
+era partiti avrà un numero di riferimenti di almeno tre, in quanto adesso sarà
+referenziata anche dalla voce ``\texttt{..}'' di \texttt{img}.
+
+
+\subsection{I filesystem di uso comune}
+\label{sec:file_ext2}
+
+Il filesystem standard più usato con Linux è il cosiddetto \textit{third
+ extended filesystem}, identificato dalla sigla \acr{ext3}.\footnote{si fa
+ riferimento al momento della stesura di questo paragrafo, l'inizio del
+ 2010.} Esso nasce come evoluzione del precedente \textit{second extended
+ filesystem}, o \acr{ext2}, di cui eredita gran parte delle caratteristiche
+di base, per questo motivo parleremo anzitutto di questo, dato che molto di
+quanto diremo si applica anche ad \acr{ext3}. A partire dal kernel 2.6.XX è
+stato dichiarato stabile il nuovo filsesystem \textit{ext4}, ulteriore
+evoluzione di \textit{ext3} dotato di molte caratteristiche avanzate, che sta
+iniziando a sostituirlo gradualmente.
+
+Il filesystem \acr{ext2} nasce come filesystem nativo di Linux a partire dalle
+prime versioni del kernel e supporta tutte le caratteristiche di un filesystem
+standard Unix: è in grado di gestire nomi di file lunghi (256 caratteri,
+estensibili a 1012) e supporta una dimensione massima dei file fino a 4~Tb. I
+successivi filesystem \acr{ext3} ed \acr{ext4} sono evoluzioni di questo
+filesystem, e sia pure con molti miglioramenti ed estensioni significative ne
+mantengono in sostanza le caratteristiche fondamentali.
+
+Oltre alle caratteristiche standard, \acr{ext2} fornisce alcune estensioni che
+non sono presenti su un classico filesystem di tipo Unix; le principali sono
+le seguenti:
+\begin{itemize}
+\item i \textit{file attributes} consentono di modificare il comportamento del
+ kernel quando agisce su gruppi di file. Possono essere impostati su file e
+ directory e in quest'ultimo caso i nuovi file creati nella directory
+ ereditano i suoi attributi.
+\item sono supportate entrambe le semantiche di BSD e SVr4 come opzioni di
+ montaggio. La semantica BSD comporta che i file in una directory sono creati
+ con lo stesso identificatore di gruppo della directory che li contiene. La
+ semantica SVr4 comporta che i file vengono creati con l'identificatore del
+ gruppo primario del processo, eccetto il caso in cui la directory ha il bit
+ di \acr{sgid} impostato (per una descrizione dettagliata del significato di
+ questi termini si veda sez.~\ref{sec:file_access_control}), nel qual caso
+ file e subdirectory ereditano sia il \acr{gid} che lo \acr{sgid}.
+\item l'amministratore può scegliere la dimensione dei blocchi del filesystem
+ in fase di creazione, a seconda delle sue esigenze (blocchi più grandi
+ permettono un accesso più veloce, ma sprecano più spazio disco).
+\item il filesystem implementa link simbolici veloci, in cui il nome del file
+ non è salvato su un blocco, ma tenuto all'interno \itindex{inode} dell'inode
+ (evitando letture multiple e spreco di spazio), non tutti i nomi però
+ possono essere gestiti così per limiti di spazio (il limite è 60 caratteri).
+\item vengono supportati i file immutabili (che possono solo essere letti) per
+ la protezione di file di configurazione sensibili, o file
+ \textit{append-only} che possono essere aperti in scrittura solo per
+ aggiungere dati (caratteristica utilizzabile per la protezione dei file di
+ log).
+\end{itemize}
+
+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 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
+ usata dal kernel per un filesystem \acr{ext2}, definita nel file
+ \texttt{ext2\_fs.h} nella directory \texttt{include/linux} dei sorgenti del
+ kernel.}
+
+Ciascun gruppo di blocchi contiene una copia delle informazioni essenziali del
+filesystem (superblock e descrittore del filesystem sono quindi ridondati) per
+una maggiore affidabilità e possibilità di recupero in caso di corruzione del
+superblock principale. L'utilizzo di raggruppamenti di blocchi ha inoltre
+degli effetti positivi nelle prestazioni dato che viene ridotta la distanza
+fra i dati e la tabella degli \itindex{inode} inode.
+
+\begin{figure}[!htb]
+ \centering
+ \includegraphics[width=9cm]{img/dir_struct}
+ \caption{Struttura delle directory nel \textit{second extented filesystem}.}
+ \label{fig:file_ext2_dirs}
+\end{figure}
+
+Le directory sono implementate come una \itindex{linked~list} \textit{linked
+ list} con voci di dimensione variabile. Ciascuna voce della lista contiene
+il numero di inode \itindex{inode}, la sua lunghezza, il nome del file e la sua
+lunghezza, secondo lo schema in fig.~\ref{fig:file_ext2_dirs}; in questo modo
+è possibile implementare nomi per i file anche molto lunghi (fino a 1024
+caratteri) senza sprecare spazio disco.
+
+Con l'introduzione del filesystem \textit{ext3} sono state introdotte anche
+alcune modifiche strutturali, la principale di queste è quella che
+\textit{ext3} è un filesystem \textit{jounrnaled}, è cioè in grado di eseguire
+una registrazione delle operazioni di scrittura su un giornale (uno speciale
+file interno) in modo da poter garantire il ripristino della coerenza dei dati
+del filesystem\footnote{si noti bene che si è parlato di dati \textsl{del}
+ filesystem, non di dati \textsl{nel} filesystem, quello di cui viene
+ garantito un veloce ripristino è relativo ai dati della struttura interna
+ del filesystem, non di eventuali dati contenuti nei file che potrebbero
+ essere stati persi.} in brevissimo tempo in caso di interruzione improvvisa
+della corrente o di crollo del sistema che abbia causato una interruzione
+della scrittura dei dati sul disco.
+
+Oltre a questo \textit{ext3} introduce ulteriori modifiche volte a migliorare
+sia le prestazioni che la semplicità di gestione del filesystem, in
+particolare per le directory si è passato all'uso di alberi binari con
+indicizzazione tramite hash al posto delle \textit{linked list}, ottenendo un
+forte guadagno di prestazioni in caso di directory contenenti un gran numero
+di file.
+
+% TODO portare a ext3, ext4 e btrfs ed illustrare le problematiche che si
+% possono incontrare (in particolare quelle relative alla perdita di contenuti
+% in caso di crash del sistema)
+
+
+\subsection{La gestione dei filesystem}
+\label{sec:sys_file_config}
+
+Come accennato in sez.~\ref{sec:file_arch_overview} per poter accedere ai file
+occorre prima rendere disponibile al sistema il filesystem su cui essi sono
+memorizzati; l'operazione di attivazione del filesystem è chiamata
+\textsl{montaggio}, per far questo in Linux\footnote{la funzione è specifica
+ di Linux e non è portabile.} si usa la funzione \funcd{mount} il cui
+prototipo è:
+\begin{prototype}{sys/mount.h}
+{mount(const char *source, const char *target, const char *filesystemtype,
+ unsigned long mountflags, const void *data)}
+
+Monta il filesystem di tipo \param{filesystemtype} contenuto in \param{source}
+sulla directory \param{target}.
+
+ \bodydesc{La funzione ritorna 0 in caso di successo e -1 in caso di
+ fallimento, nel qual caso gli errori comuni a tutti i filesystem che possono
+ essere restituiti in \var{errno} sono:
+ \begin{errlist}
+ \item[\errcode{EPERM}] il processo non ha i privilegi di amministratore.
+ \item[\errcode{ENODEV}] \param{filesystemtype} non esiste o non è configurato
+ nel kernel.
+ \item[\errcode{ENOTBLK}] non si è usato un \textit{block device} per
+ \param{source} quando era richiesto.
+ \item[\errcode{EBUSY}] \param{source} è già montato, o non può essere
+ rimontato in read-only perché ci sono ancora file aperti in scrittura, o
+ \param{target} è ancora in uso.
+ \item[\errcode{EINVAL}] il device \param{source} presenta un
+ \textit{superblock} non valido, o si è cercato di rimontare un filesystem
+ non ancora montato, o di montarlo senza che \param{target} sia un
+ \textit{mount point} o di spostarlo quando \param{target} non è un
+ \textit{mount point} o è \file{/}.
+ \item[\errcode{EACCES}] non si ha il permesso di accesso su uno dei
+ componenti del \itindex{pathname} \textit{pathname}, o si è cercato
+ di montare un filesystem disponibile in sola lettura senza averlo
+ specificato o il device \param{source} è su un filesystem montato con
+ l'opzione \const{MS\_NODEV}.
+ \item[\errcode{ENXIO}] il \itindex{major~number} \textit{major number} del
+ device \param{source} è sbagliato.
+ \item[\errcode{EMFILE}] la tabella dei device \textit{dummy} è piena.
+ \end{errlist}
+ ed inoltre \errval{ENOTDIR}, \errval{EFAULT}, \errval{ENOMEM},
+ \errval{ENAMETOOLONG}, \errval{ENOENT} o \errval{ELOOP}.}
+\end{prototype}
+
+La funzione monta sulla directory \param{target}, detta \textit{mount point},
+il filesystem contenuto in \param{source}. In generale un filesystem è
+contenuto su un disco, e l'operazione di montaggio corrisponde a rendere
+visibile al sistema il contenuto del suddetto disco, identificato attraverso
+il file di dispositivo ad esso associato.
+
+Ma la struttura del \textit{Virtual File System} vista in
+sez.~\ref{sec:file_vfs_work} è molto più flessibile e può essere usata anche
+per oggetti diversi da un disco. Ad esempio usando il \textit{loop device} si
+può montare un file qualunque (come l'immagine di un CD-ROM o di un floppy)
+che contiene un filesystem, inoltre alcuni filesystem, come \file{proc} o
+\file{devfs} sono del tutto virtuali, i loro dati sono generati al volo ad
+ogni lettura, e passati al kernel ad ogni scrittura.
+
+Il tipo di filesystem è specificato da \param{filesystemtype}, che deve essere
+una delle stringhe riportate nel file \procfile{/proc/filesystems}, che
+contiene l'elenco dei filesystem supportati dal kernel; nel caso si sia
+indicato uno dei filesystem virtuali, il contenuto di \param{source} viene
+ignorato.
+
+Dopo l'esecuzione della funzione il contenuto del filesystem viene resto
+disponibile nella directory specificata come \textit{mount point}, il
+precedente contenuto di detta directory viene mascherato dal contenuto della
+directory radice del filesystem montato.
+
+Dal kernel 2.4.x inoltre è divenuto possibile sia spostare atomicamente un
+\textit{mount point} da una directory ad un'altra, sia montare in diversi
+\textit{mount point} lo stesso filesystem, sia montare più filesystem sullo
+stesso \textit{mount point} (nel qual caso vale quanto appena detto, e solo il
+contenuto dell'ultimo filesystem montato sarà visibile).
+
+Ciascun filesystem è dotato di caratteristiche specifiche che possono essere
+attivate o meno, alcune di queste sono generali (anche se non è detto siano
+disponibili in ogni filesystem), e vengono specificate come opzioni di
+montaggio con l'argomento \param{mountflags}.
+
+In Linux \param{mountflags} deve essere un intero a 32 bit i cui 16 più
+significativi sono un \textit{magic number}\footnote{cioè un numero speciale
+ usato come identificativo, che nel caso è \code{0xC0ED}; si può usare la
+ costante \const{MS\_MGC\_MSK} per ottenere la parte di \param{mountflags}
+ riservata al \textit{magic number}.} mentre i 16 meno significativi sono
+usati per specificare le opzioni; essi sono usati come maschera binaria e
+vanno impostati con un OR aritmetico della costante \const{MS\_MGC\_VAL} con i
+valori riportati in tab.~\ref{tab:sys_mount_flags}.
+
+\begin{table}[htb]
+ \footnotesize
+ \centering
+ \begin{tabular}[c]{|l|r|l|}
+ \hline
+ \textbf{Parametro} & \textbf{Valore}&\textbf{Significato}\\
+ \hline
+ \hline
+ \const{MS\_RDONLY} & 1 & Monta in sola lettura.\\
+ \const{MS\_NOSUID} & 2 & Ignora i bit \itindex{suid~bit} \acr{suid} e
+ \itindex{sgid~bit} \acr{sgid}.\\
+ \const{MS\_NODEV} & 4 & Impedisce l'accesso ai file di dispositivo.\\
+ \const{MS\_NOEXEC} & 8 & Impedisce di eseguire programmi.\\
+ \const{MS\_SYNCHRONOUS}& 16 & Abilita la scrittura sincrona.\\
+ \const{MS\_REMOUNT} & 32 & Rimonta il filesystem cambiando le opzioni.\\
+ \const{MS\_MANDLOCK} & 64 & Consente il \textit{mandatory locking}
+ \itindex{mandatory~locking} (vedi
+ sez.~\ref{sec:file_mand_locking}).\\
+ \const{S\_WRITE} & 128 & Scrive normalmente.\\
+ \const{S\_APPEND} & 256 & Consente la scrittura solo in
+ \itindex{append~mode} \textit{append mode}
+ (vedi sez.~\ref{sec:file_sharing}).\\
+ \const{S\_IMMUTABLE} & 512 & Impedisce che si possano modificare i file.\\
+ \const{MS\_NOATIME} &1024 & Non aggiorna gli \textit{access time} (vedi
+ sez.~\ref{sec:file_file_times}).\\
+ \const{MS\_NODIRATIME}&2048 & Non aggiorna gli \textit{access time} delle
+ directory.\\
+ \const{MS\_BIND} &4096 & Monta il filesystem altrove.\\
+ \const{MS\_MOVE} &8192 & Sposta atomicamente il punto di montaggio.\\
+ \hline
+ \end{tabular}
+ \caption{Tabella dei codici dei flag di montaggio di un filesystem.}
+ \label{tab:sys_mount_flags}
+\end{table}
+
+% TODO aggiornare con i nuovi flag di man mount
+% gli S_* non esistono più come segnalato da Alessio...
+% verificare i readonly mount bind del 2.6.26
+
+Per l'impostazione delle caratteristiche particolari di ciascun filesystem si
+usa invece l'argomento \param{data} che serve per passare le ulteriori
+informazioni necessarie, che ovviamente variano da filesystem a filesystem.
+
+La funzione \func{mount} può essere utilizzata anche per effettuare il
+\textsl{rimontaggio} di un filesystem, cosa che permette di cambiarne al volo
+alcune delle caratteristiche di funzionamento (ad esempio passare da sola
+lettura a lettura/scrittura). Questa operazione è attivata attraverso uno dei
+bit di \param{mountflags}, \const{MS\_REMOUNT}, che se impostato specifica che
+deve essere effettuato il rimontaggio del filesystem (con le opzioni
+specificate dagli altri bit), anche in questo caso il valore di \param{source}
+viene ignorato.
+
+Una volta che non si voglia più utilizzare un certo filesystem è possibile
+\textsl{smontarlo} usando la funzione \funcd{umount}, il cui prototipo è:
+\begin{prototype}{sys/mount.h}{umount(const char *target)}
+
+ Smonta il filesystem montato sulla directory \param{target}.
+
+ \bodydesc{La funzione ritorna 0 in caso di successo e -1 in caso di
+ fallimento, nel qual caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EPERM}] il processo non ha i privilegi di amministratore.
+ \item[\errcode{EBUSY}] \param{target} è la directory di lavoro di qualche
+ processo, o contiene dei file aperti, o un altro mount point.
+ \end{errlist}
+ ed inoltre \errval{ENOTDIR}, \errval{EFAULT}, \errval{ENOMEM},
+ \errval{ENAMETOOLONG}, \errval{ENOENT} o \errval{ELOOP}.}
+\end{prototype}
+\noindent la funzione prende il nome della directory su cui il filesystem è
+montato e non il file o il dispositivo che è stato montato,\footnote{questo è
+ vero a partire dal kernel 2.3.99-pre7, prima esistevano due chiamate
+ separate e la funzione poteva essere usata anche specificando il file di
+ dispositivo.} in quanto con il kernel 2.4.x è possibile montare lo stesso
+dispositivo in più punti. Nel caso più di un filesystem sia stato montato
+sullo stesso \textit{mount point} viene smontato quello che è stato montato
+per ultimo.
+
+Si tenga presente che la funzione fallisce quando il filesystem è
+\textsl{occupato}, questo avviene quando ci sono ancora file aperti sul
+filesystem, se questo contiene la directory di lavoro corrente di un qualunque
+processo o il mount point di un altro filesystem; in questo caso l'errore
+restituito è \errcode{EBUSY}.
+
+Linux provvede inoltre una seconda funzione, \funcd{umount2}, che in alcuni
+casi permette di forzare lo smontaggio di un filesystem, anche quando questo
+risulti occupato; il suo prototipo è:
+\begin{prototype}{sys/mount.h}{umount2(const char *target, int flags)}
+
+ La funzione è identica a \func{umount} per comportamento e codici di errore,
+ ma con \param{flags} si può specificare se forzare lo smontaggio.
+\end{prototype}
+
+Il valore di \param{flags} è una maschera binaria, e al momento l'unico valore
+definito è il bit \const{MNT\_FORCE}; gli altri bit devono essere nulli.
+Specificando \const{MNT\_FORCE} la funzione cercherà di liberare il filesystem
+anche se è occupato per via di una delle condizioni descritte in precedenza. A
+seconda del tipo di filesystem alcune (o tutte) possono essere superate,
+evitando l'errore di \errcode{EBUSY}. In tutti i casi prima dello smontaggio
+viene eseguita una sincronizzazione dei dati.
+
+% TODO documentare MNT_DETACH e MNT_EXPIRE ...
+
+Altre due funzioni specifiche di Linux,\footnote{esse si trovano anche su BSD,
+ ma con una struttura diversa.} utili per ottenere in maniera diretta
+informazioni riguardo al filesystem su cui si trova un certo file, sono
+\funcd{statfs} e \funcd{fstatfs}, i cui prototipi sono:
+\begin{functions}
+ \headdecl{sys/vfs.h}
+ \funcdecl{int statfs(const char *path, struct statfs *buf)}
+
+ \funcdecl{int fstatfs(int fd, struct statfs *buf)}
+
+ Restituisce in \param{buf} le informazioni relative al filesystem su cui è
+ posto il file specificato.
+
+ \bodydesc{Le funzioni ritornano 0 in caso di successo e -1 in caso di
+ errore, nel qual caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{ENOSYS}] il filesystem su cui si trova il file specificato non
+ supporta la funzione.
+ \end{errlist}
+ e \errval{EFAULT} ed \errval{EIO} per entrambe, \errval{EBADF} per
+ \func{fstatfs}, \errval{ENOTDIR}, \errval{ENAMETOOLONG}, \errval{ENOENT},
+ \errval{EACCES}, \errval{ELOOP} per \func{statfs}.}
+\end{functions}
+
+Queste funzioni permettono di ottenere una serie di informazioni generali
+riguardo al filesystem su cui si trova il file specificato; queste vengono
+restituite all'indirizzo \param{buf} di una struttura \struct{statfs} definita
+come in fig.~\ref{fig:sys_statfs}, ed i campi che sono indefiniti per il
+filesystem in esame sono impostati a zero. I valori del campo \var{f\_type}
+sono definiti per i vari filesystem nei relativi file di header dei sorgenti
+del kernel da costanti del tipo \var{XXX\_SUPER\_MAGIC}, dove \var{XXX} in
+genere è il nome del filesystem stesso.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{\textwidth}
+ \includestruct{listati/statfs.h}
+ \end{minipage}
+ \normalsize
+ \caption{La struttura \structd{statfs}.}
+ \label{fig:sys_statfs}
+\end{figure}
+
+
+Le \acr{glibc} provvedono infine una serie di funzioni per la gestione dei due
+file \conffile{/etc/fstab} ed \conffile{/etc/mtab}, che convenzionalmente sono
+usati in quasi tutti i sistemi unix-like per mantenere rispettivamente le
+informazioni riguardo ai filesystem da montare e a quelli correntemente
+montati. Le funzioni servono a leggere il contenuto di questi file in
+opportune strutture \struct{fstab} e \struct{mntent}, e, per
+\conffile{/etc/mtab} per inserire e rimuovere le voci presenti nel file.
+
+In generale si dovrebbero usare queste funzioni (in particolare quelle
+relative a \conffile{/etc/mtab}), quando si debba scrivere un programma che
+effettua il montaggio di un filesystem; in realtà in questi casi è molto più
+semplice invocare direttamente il programma \cmd{mount}, per cui ne
+tralasceremo la trattazione, rimandando al manuale delle \acr{glibc}
+\cite{glibc} per la documentazione completa.
+
+% TODO scrivere relativamente alle varie funzioni (getfsent e getmntent &C)
+% TODO documentare swapon e swapoff (man 2 ...)
+
+
Questo è possibile anche in ambiente Unix, dove tali collegamenti sono
usualmente chiamati \textit{link}; ma data l'architettura del sistema riguardo
-la gestione dei file (ed in particolare quanto trattato in
-sez.~\ref{sec:file_arch_func}) ci sono due metodi sostanzialmente diversi per
-fare questa operazione.
+la gestione dei file ci sono due metodi sostanzialmente diversi per fare
+questa operazione.
Come spiegato in sez.~\ref{sec:file_filesystem} l'accesso al contenuto di un
file su disco avviene passando attraverso il suo \itindex{inode}
sono contenute in due campi (rispettivamente \var{pwd} e \var{root}) di
\struct{fs\_struct}; vedi fig.~\ref{fig:proc_task_struct}.} che, pur essendo
di norma corrispondente alla radice dell'albero di file e directory come visto
-dal kernel (ed illustrato in sez.~\ref{sec:file_organization}), ha per il
-processo il significato specifico di directory rispetto alla quale vengono
-risolti i \itindsub{pathname}{assoluto}\textit{pathname}
-assoluti.\footnote{cioè quando un processo chiede la risoluzione di un
- \textit{pathname}, il kernel usa sempre questa directory come punto di
- partenza.} Il fatto che questo valore sia specificato per ogni processo apre
-allora la possibilità di modificare le modalità di risoluzione dei
-\textit{pathname} assoluti da parte di un processo cambiando questa directory,
-così come si fa coi \itindsub{pathname}{relativo}\textit{pathname} relativi
-cambiando la directory di lavoro.
+dal kernel (ed illustrato in sez.~\ref{sec:file_pathname}), ha per il processo
+il significato specifico di directory rispetto alla quale vengono risolti i
+\itindsub{pathname}{assoluto}\textit{pathname} assoluti.\footnote{cioè quando
+ un processo chiede la risoluzione di un \textit{pathname}, il kernel usa
+ sempre questa directory come punto di partenza.} Il fatto che questo valore
+sia specificato per ogni processo apre allora la possibilità di modificare le
+modalità di risoluzione dei \textit{pathname} assoluti da parte di un processo
+cambiando questa directory, così come si fa coi
+\itindsub{pathname}{relativo}\textit{pathname} relativi cambiando la directory
+di lavoro.
Normalmente la directory radice di un processo coincide anche con la radice
del filesystem usata dal kernel, e dato che il suo valore viene ereditato dal
%% License".
%%
-\chapter{L'architettura dei file}
-\label{cha:file_intro}
-
-Uno dei concetti fondamentali dell'architettura di un sistema Unix è il
-cosiddetto \textit{everything is a file}, cioè il fatto che l'accesso ai vari
-dispositivi di input/output del computer viene effettuato attraverso
-un'interfaccia astratta che tratta le periferiche allo stesso modo dei normali
-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 \index{file!di~dispositivo} file di dispositivo (i cosiddetti
-\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.
-
-In questo capitolo forniremo una descrizione dell'architettura dei file in
-Linux, iniziando da una panoramica sulle caratteristiche principali delle
-interfacce con cui i processi accedono ai file (che tratteremo in dettaglio
-nei capitoli seguenti), per poi passare ad una descrizione più dettagliata
-delle modalità con cui detto accesso viene realizzato dal sistema.
-
-
-
-\section{L'architettura generale}
-\label{sec:file_access_arch}
-
-Per poter accedere ai file, il kernel deve mettere a disposizione dei
-programmi le opportune interfacce che consentano di leggerne il contenuto; il
-sistema cioè deve provvedere ad organizzare e rendere accessibile in maniera
-opportuna l'informazione tenuta sullo spazio grezzo disponibile sui dischi.
-Questo viene fatto strutturando l'informazione sul disco attraverso quello che
-si chiama un \textit{filesystem} (vedi sez.~\ref{sec:file_arch_func}), essa
-poi viene resa disponibile ai processi attraverso quello che viene chiamato il
-\textsl{montaggio} del \textit{filesystem}.
-
-In questa sezione faremo una panoramica generica su come il sistema presenta
-i file ai processi, trattando l'organizzazione di file e directory, i tipi di
-file ed introducendo le interfacce disponibili e le loro caratteristiche.
-
-
-\subsection{L'organizzazione di file e directory}
-\label{sec:file_organization}
-
-\itindbeg{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}\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
-filesystem da usare come punto di partenza e questo viene montato come radice
-dell'albero (cioè nella directory \file{/}); tutti gli ulteriori filesystem
-che possono essere su altri dispositivi dovranno poi essere inseriti
-nell'albero montandoli su opportune directory del filesystem montato come
-radice.
-
-Alcuni filesystem speciali (come \file{/proc} che contiene un'interfaccia ad
-alcune strutture interne del kernel) sono generati automaticamente dal kernel
-stesso, ma anche essi devono essere montati all'interno dell'albero dei file.
-
-Una directory, come vedremo in maggior dettaglio in
-sez.~\ref{sec:file_vfs_work}, è anch'essa un file, solo che è un file
-particolare che il kernel riconosce come tale. Il suo scopo è quello di
-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 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 \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 e gli stessi
-\index{file!di~dispositivo} 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{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 il carattere ``\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} comincia con il carattere ``\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} \itindsub{pathname}{assoluto}.
-Altrimenti la ricerca parte dalla directory corrente (su cui torneremo in
-sez.~\ref{sec:file_work_dir}) ed il pathname è detto
-\itindsub{pathname}{relativo} \textsl{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 secondo alla directory \textsl{genitrice} (o \textit{parent directory})
-cioè la directory che contiene il riferimento alla directory corrente; nel
-caso la directory corrente coincida con la directory radice, allora il
-riferimento è a se stessa.
-
-\itindend{pathname}
-
-
-\subsection{I tipi di file}
-\label{sec:file_file_types}
-
-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
-\itindex{Virtual~File~System} \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
-la classificazione dei file (che in questo caso sono sempre file di dati) in
-base al loro contenuto, o tipo di accesso. Essa riguarda invece il tipo di
-oggetti; in particolare è da notare la presenza dei cosiddetti file speciali.
-Alcuni di essi, come le \textit{fifo} (che tratteremo in
-sez.~\ref{sec:ipc_named_pipe}) ed i \textit{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
-\index{file!di~dispositivo} \textsl{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à in cui il
-dispositivo sottostante effettua le operazioni di I/O.\footnote{in sostanza i
- dispositivi a blocchi (ad esempio i dischi) corrispondono a periferiche per
- le quali è richiesto che l'I/O venga effettuato per blocchi di dati di
- dimensioni fissate (ad esempio le dimensioni di un settore), mentre nei
- dispositivi a caratteri l'I/O viene effettuato senza nessuna particolare
- struttura.}
-
-\begin{table}[htb]
- \footnotesize
- \centering
- \begin{tabular}[c]{|l|l|p{7cm}|}
- \hline
- \multicolumn{2}{|c|}{\textbf{Tipo di file}} & \textbf{Descrizione} \\
- \hline
- \hline
- \textit{regular file} & \textsl{file regolare} &
- Un file che contiene dei dati (l'accezione normale di file).\\
- \textit{directory} & \textsl{cartella o direttorio} &
- Un file che contiene una lista di nomi associati a degli
- \itindex{inode} \textit{inode} (vedi sez.~\ref{sec:file_vfs}).\\
- \textit{symbolic link} & \textsl{collegamento simbolico} &
- Un file che contiene un riferimento ad un altro file/directory.\\
- \textit{char device} & \textsl{dispositivo a caratteri} &
- Un file che identifica una periferica ad accesso a caratteri.\\
- \textit{block device} & \textsl{dispositivo a blocchi} &
- Un file che identifica una periferica ad accesso a blocchi.\\
- \textit{fifo} & ``\textsl{coda}'' &
- Un file speciale che identifica una linea di comunicazione software
- unidirezionale (vedi sez.~\ref{sec:ipc_named_pipe}).\\
- \textit{socket} & ``\textsl{presa}''&
- Un file speciale che identifica una linea di comunicazione software
- bidirezionale (vedi cap.~\ref{cha:socket_intro}).\\
- \hline
- \end{tabular}
- \caption{Tipologia dei file definiti nel VFS}
- \label{tab:file_file_types}
-\end{table}
-
-Una delle differenze principali con altri sistemi operativi (come il VMS o
-Windows) è che per Unix tutti i file di dati sono identici e contengono un
-flusso continuo di byte. Non esiste cioè differenza per come vengono visti dal
-sistema file di diverso contenuto o formato (come nel caso di quella fra file
-di testo e binari che c'è in Windows) né c'è una strutturazione a record per
-il cosiddetto ``\textsl{accesso diretto}'' come nel caso del
-VMS.\footnote{questo vale anche per i dispositivi a blocchi: la strutturazione
- dell'I/O in blocchi di dimensione fissa avviene solo all'interno del kernel,
- 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
- \index{file!di~dispositivo} 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 ed
- in sostanziale disuso.}
-
-Una seconda differenza è nel formato dei file di testo: in Unix la fine riga è
-codificata in maniera diversa da Windows o dal vecchio MacOS, in particolare
-il fine riga è il carattere \texttt{LF} (o \verb|\n|) al posto del \texttt{CR}
-(\verb|\r|) del vecchio MacOS e del \texttt{CR LF} di Windows.\footnote{per
- questo esistono in Linux dei programmi come \cmd{unix2dos} e \cmd{dos2unix}
- che effettuano una conversione fra questi due formati di testo.} Questo può
-causare alcuni problemi qualora nei programmi si facciano assunzioni sul
-terminatore della riga.
-
-Si ricordi infine che un kernel Unix non fornisce nessun supporto per la
-tipizzazione dei file di dati e che non c'è nessun supporto del sistema per le
-estensioni come parte del filesystem.\footnote{non è così ad esempio nel
- filesystem HFS dei Mac, che supporta delle risorse associate ad ogni file,
- che specificano fra l'altro il contenuto ed il programma da usare per
- leggerlo. In realtà per alcuni filesystem esiste la possibilità di
- associare delle risorse ai file con gli \textit{extended attributes} (vedi
- sez.~\ref{sec:file_xattr}), ma è una caratteristica tutt'ora poco
- utilizzata, dato che non corrisponde al modello classico dei file in un
- sistema Unix.} Ciò nonostante molti programmi adottano delle convenzioni per
-i nomi dei file, ad esempio il codice C normalmente si mette in file con
-l'estensione \file{.c}; un'altra tecnica molto usata è quella di utilizzare i
-primi 4 byte del file per memorizzare un \textit{magic number} che classifichi
-il contenuto; entrambe queste tecniche, per quanto usate ed accettate in
-maniera diffusa, restano solo delle convenzioni il cui rispetto è demandato
-alle applicazioni stesse.
-
-
-\subsection{Le due interfacce ai file}
-\label{sec:file_io_api}
-
-In Linux le modalità di accesso ai file e le relative interfacce di
-programmazione sono due, basate su due diversi meccanismi con cui è possibile
-accedere al loro contenuto.
-
-La prima è l'interfaccia standard di Unix, quella che il manuale delle
-\textsl{glibc} chiama interfaccia dei descrittori di file (o \textit{file
- descriptor}). È un'interfaccia specifica dei sistemi unix-like e fornisce
-un accesso non bufferizzato; la tratteremo in dettaglio in
-cap.~\ref{cha:file_unix_interface}.
-
-L'interfaccia è primitiva ed essenziale, l'accesso viene detto non
-bufferizzato in quanto la lettura e la scrittura vengono eseguite chiamando
-direttamente le system call del kernel (in realtà il kernel effettua al suo
-interno alcune bufferizzazioni per aumentare l'efficienza nell'accesso ai
-dispositivi); i \index{file!descriptor} \textit{file descriptor} sono
-rappresentati da numeri interi (cioè semplici variabili di tipo \ctyp{int}).
-L'interfaccia è definita nell'header \file{unistd.h}.
-
-La seconda interfaccia è quella che il manuale della \acr{glibc} chiama degli
-\index{file!stream} \textit{stream}.\footnote{in realtà una interfaccia con lo
- stesso nome è stata introdotta a livello di kernel negli Unix derivati da
- \textit{System V}, come strato di astrazione per file e socket; in Linux
- questa interfaccia, che comunque ha avuto poco successo, non esiste, per cui
- facendo riferimento agli \index{file!stream} \textit{stream} useremo il
- significato adottato dal manuale delle \acr{glibc}.} Essa fornisce funzioni
-più evolute e un accesso bufferizzato (controllato dalla implementazione fatta
-dalle \acr{glibc}), la tratteremo in dettaglio nel
-cap.~\ref{cha:files_std_interface}.
-
-Questa è l'interfaccia standard specificata dall'ANSI C e perciò si trova
-anche su tutti i sistemi non Unix. Gli \index{file!stream} \textit{stream}
-sono oggetti complessi e sono rappresentati da puntatori ad un opportuna
-struttura definita dalle librerie del C; si accede ad essi sempre in maniera
-indiretta utilizzando il tipo \type{FILE *}. L'interfaccia è definita
-nell'header \file{stdio.h}.
-
-Entrambe le interfacce possono essere usate per l'accesso ai file come agli
-altri oggetti del VFS (fifo, socket, dispositivi, sui quali torneremo in
-dettaglio a tempo opportuno), ma per poter accedere alle operazioni di
-controllo (descritte in sez.~\ref{sec:file_fcntl} e sez.~\ref{sec:file_ioctl})
-su un qualunque tipo di oggetto del VFS occorre usare l'interfaccia standard
-di Unix con i \textit{file descriptor}. Allo stesso modo devono essere usati i
-\index{file!descriptor} \textit{file descriptor} se si vuole ricorrere a
-modalità speciali di I/O come il \index{file!locking} \textit{file locking} o
-l'I/O non-bloccante (vedi cap.~\ref{cha:file_advanced}).
-
-Gli \textit{stream} forniscono un'interfaccia di alto livello costruita sopra
-quella dei \textit{file descriptor}, che permette di poter scegliere tra
-diversi stili di bufferizzazione. Il maggior vantaggio degli \textit{stream}
-è che l'interfaccia per le operazioni di input/output è enormemente più ricca
-di quella dei \textit{file descriptor}, che forniscono solo funzioni
-elementari per la lettura/scrittura diretta di blocchi di byte. In
-particolare gli \index{file!stream} \textit{stream} dispongono di tutte le
-funzioni di formattazione per l'input e l'output adatte per manipolare anche i
-dati in forma di linee o singoli caratteri.
-
-In ogni caso, dato che gli stream sono implementati sopra l'interfaccia
-standard di Unix, è sempre possibile estrarre il \textit{file descriptor} da
-uno stream ed eseguirvi operazioni di basso livello, o associare in un secondo
-tempo uno \index{file!stream} \textit{stream} ad un \index{file!descriptor}
-\textit{file descriptor}.
-
-In generale, se non necessitano specificatamente le funzionalità di basso
-livello, è opportuno usare sempre gli \index{file!stream} \textit{stream} per
-la loro maggiore portabilità, essendo questi ultimi definiti nello standard
-ANSI C; l'interfaccia con i \index{file!descriptor} \textit{file descriptor}
-infatti segue solo lo standard POSIX.1 dei sistemi Unix, ed è pertanto di
-portabilità più limitata.
-
-
-
-\section{L'architettura della gestione dei file}
-\label{sec:file_arch_func}
-
-In questa sezione esamineremo come viene implementato l'accesso ai file in
-Linux, come il kernel può gestire diversi tipi di filesystem, descrivendo
-prima le caratteristiche generali di un filesystem di un sistema unix-like,
-per poi trattare in maniera un po' più dettagliata il filesystem più usato con
-Linux, l'\acr{ext2} (e derivati).
-
-
-\subsection{Il \textit{Virtual File System} di Linux}
-\label{sec:file_vfs}
-
-% articolo interessante:
-% http://www.ibm.com/developerworks/linux/library/l-virtual-filesystem-switch/index.html?ca=dgr-lnxw97Linux-VFSdth-LXdW&S_TACT=105AGX59&S_CMP=GRlnxw97
-
-\itindbeg{Virtual~File~System}
-
-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.
-
-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
-manipolazioni sulle strutture generiche e utilizzerà poi la chiamata alle
-opportune funzioni del filesystem specifico a cui si fa riferimento. Saranno
-queste a chiamare le funzioni di più basso livello che eseguono le operazioni
-di I/O sul dispositivo fisico, secondo lo schema riportato in
-fig.~\ref{fig:file_VFS_scheme}.
-
-\begin{figure}[!htb]
- \centering
- \includegraphics[width=7cm]{img/vfs}
- \caption{Schema delle operazioni del VFS.}
- \label{fig:file_VFS_scheme}
-\end{figure}
-
-Il VFS definisce un insieme di funzioni che tutti i filesystem devono
-implementare. L'interfaccia comprende tutte le funzioni che riguardano i file;
-le operazioni sono suddivise su tre tipi di oggetti: \textit{filesystem},
-\itindex{inode} \textit{inode} e \textit{file}, corrispondenti a tre apposite
-strutture definite nel kernel.
-
-Il VFS usa una tabella mantenuta dal kernel che contiene il nome di ciascun
-filesystem supportato: quando si vuole inserire il supporto di un nuovo
-filesystem tutto quello che occorre è chiamare la funzione
-\code{register\_filesystem} passandole un'apposita struttura
-\code{file\_system\_type} che contiene i dettagli per il riferimento
-all'implementazione del medesimo, che sarà aggiunta alla citata tabella.
-
-In questo modo quando viene effettuata la richiesta di montare un nuovo disco
-(o qualunque altro \textit{block device} che può contenere un filesystem), il
-VFS può ricavare dalla citata tabella il puntatore alle funzioni da chiamare
-nelle operazioni di montaggio. Quest'ultima è responsabile di leggere da disco
-il superblock (vedi sez.~\ref{sec:file_ext2}), inizializzare tutte le variabili
-interne e restituire uno speciale descrittore dei filesystem montati al VFS;
-attraverso quest'ultimo diventa possibile accedere alle funzioni specifiche per
-l'uso di quel filesystem.
-
-Il primo oggetto usato dal VFS è il descrittore di filesystem, un puntatore ad
-una apposita struttura che contiene vari dati come le informazioni comuni ad
-ogni filesystem, i dati privati relativi a quel filesystem specifico, e i
-puntatori alle funzioni del kernel relative al filesystem. Il VFS può così
-usare le funzioni contenute nel \textit{filesystem descriptor} per accedere
-alle funzioni specifiche di quel filesystem.
-
-Gli altri due descrittori usati dal VFS sono relativi agli altri due oggetti
-su cui è strutturata l'interfaccia. Ciascuno di essi contiene le informazioni
-relative al file in uso, insieme ai puntatori alle funzioni dello specifico
-filesystem usate per l'accesso dal VFS; in particolare il descrittore
-\itindex{inode} dell'inode contiene i puntatori alle funzioni che possono essere
-usate su qualunque file (come \func{link}, \func{stat} e \func{open}), mentre
-il descrittore di file contiene i puntatori alle funzioni che vengono usate
-sui file già aperti.
-
-
-\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 \itindex{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
-\itindex{inode} \textit{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
-\index{file!di~dispositivo} 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
-file, contiene anche il riferimento alle funzioni (i \textsl{metodi} del VFS)
-da usare per poterlo manipolare.
-
-Le \textit{dentry} ``vivono'' in memoria e non vengono mai salvate su disco,
-vengono usate per motivi di velocità, gli \itindex{inode} \textit{inode} invece
-stanno su disco e vengono copiati in memoria quando serve, ed ogni cambiamento
-viene copiato all'indietro sul disco (aggiornando i cosiddetti
-\textsl{metadati} del file), gli \itindex{inode} inode che stanno in memoria
-sono \itindex{inode} inode del VFS ed è ad essi che puntano le singole
-\textit{dentry}.
-
-La \textit{dcache} costituisce perciò una sorta di vista completa di tutto
-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
-\itindex{pathname} \textit{pathname} il VFS deve creare una nuova
-\textit{dentry} e caricare \itindex{inode} l'inode corrispondente in memoria.
-
-Questo procedimento viene eseguito dal metodo \code{lookup()} \itindex{inode}
-dell'inode della directory che contiene il file; questo viene installato nelle
-relative strutture in memoria quando si effettua il montaggio lo specifico
-filesystem su cui l'inode va a vivere.
-
-Una volta che il VFS ha a disposizione la \textit{dentry} (ed il relativo
-\textit{inode}) diventa possibile accedere alle varie operazioni sul file come
-la \func{open} per aprire il file o la \func{stat} per leggere i dati
-\itindex{inode} dell'inode e passarli in user space.
-
-L'apertura di un file richiede comunque un'altra operazione, l'allocazione di
-una struttura di tipo \struct{file} in cui viene inserito un puntatore alla
-\textit{dentry} e una struttura \struct{f\_ops} che contiene i puntatori ai
-metodi che implementano le operazioni disponibili sul file. In questo modo i
-processi in user space possono accedere alle operazioni attraverso detti
-metodi, che saranno diversi a seconda del tipo di file (o dispositivo) aperto
-(su questo torneremo in dettaglio in sez.~\ref{sec:file_fd}). Un elenco delle
-operazioni previste dal kernel è riportato in
-tab.~\ref{tab:file_file_operations}.
-
-\begin{table}[htb]
- \centering
- \footnotesize
- \begin{tabular}[c]{|l|p{8cm}|}
- \hline
- \textbf{Funzione} & \textbf{Operazione} \\
- \hline
- \hline
- \textsl{\code{open}} & Apre il file (vedi sez.~\ref{sec:file_open}).\\
- \textsl{\code{read}} & Legge dal file (vedi sez.~\ref{sec:file_read}).\\
- \textsl{\code{write}} & Scrive sul file (vedi
- sez.~\ref{sec:file_write}).\\
- \textsl{\code{llseek}} & Sposta la posizione corrente sul file (vedi
- sez.~\ref{sec:file_lseek}).\\
- \textsl{\code{ioctl}} & Accede alle operazioni di controllo
- (vedi sez.~\ref{sec:file_ioctl}).\\
- \textsl{\code{readdir}}& Legge il contenuto di una directory (vedi
- sez.~\ref{sec:file_dir_read}).\\
- \textsl{\code{poll}} & Usata nell'I/O multiplexing (vedi
- sez.~\ref{sec:file_multiplexing}).\\
- \textsl{\code{mmap}} & Mappa il file in memoria (vedi
- sez.~\ref{sec:file_memory_map}).\\
- \textsl{\code{release}}& Chiamata quando l'ultimo riferimento a un file
- aperto è chiuso.\\
- \textsl{\code{fsync}} & Sincronizza il contenuto del file (vedi
- sez.~\ref{sec:file_sync}).\\
- \textsl{\code{fasync}} & Abilita l'I/O asincrono (vedi
- sez.~\ref{sec:file_asyncronous_io}) sul file.\\
- \hline
- \end{tabular}
- \caption{Operazioni sui file definite nel VFS.}
- \label{tab:file_file_operations}
-\end{table}
-
-In questo modo per ciascun file diventano possibili una serie di operazioni
-(non è detto che tutte siano disponibili), che costituiscono l'interfaccia
-astratta del VFS. Qualora se ne voglia eseguire una, il kernel andrà ad
-utilizzare l'opportuna funzione dichiarata in \struct{f\_ops} appropriata al
-tipo di file in questione.
-
-Pertanto è possibile scrivere allo stesso modo sulla porta seriale come su un
-normale file di dati; ovviamente certe operazioni (nel caso della seriale ad
-esempio la \code{seek}) non saranno disponibili, però con questo sistema
-l'utilizzo di diversi filesystem (come quelli usati da Windows o MacOS) è
-immediato e (relativamente) trasparente per l'utente ed il programmatore.
-\itindend{Virtual~File~System}
-
-
-\subsection{Il funzionamento di un filesystem Unix}
-\label{sec:file_filesystem}
-
-Come già accennato in sez.~\ref{sec:file_organization} Linux (ed ogni sistema
-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
-filesystem specifico, ma daremo una descrizione a grandi linee che si adatta
-alle caratteristiche comuni di qualunque filesystem di sistema unix-like.
-
-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{block group} che replicano il
-superblock (ma sulle caratteristiche di \acr{ext2} e derivati torneremo in
-sez.~\ref{sec:file_ext2}). È comunque caratteristica comune di tutti i
-filesystem per Unix, indipendentemente da come poi viene strutturata nei
-dettagli questa informazione, prevedere una divisione fra la lista degli
-\itindex{inode} inode e lo spazio a disposizione per i dati e le directory.
-
-\begin{figure}[!htb]
- \centering
- \includegraphics[width=14cm]{img/disk_struct}
- \caption{Organizzazione dello spazio su un disco in partizioni e
- filesystem.}
- \label{fig:file_disk_filesys}
-\end{figure}
-
-Se si va ad esaminare con maggiore dettaglio la strutturazione
-dell'informazione all'interno del singolo filesystem (tralasciando i dettagli
-relativi al funzionamento del filesystem stesso come la strutturazione in
-gruppi dei blocchi, il superblock e tutti i dati di gestione) possiamo
-esemplificare la situazione con uno schema come quello esposto in
-fig.~\ref{fig:file_filesys_detail}.
-
-\begin{figure}[!htb]
- \centering
- \includegraphics[width=14cm]{img/filesys_struct}
- \caption{Strutturazione dei dati all'interno di un filesystem.}
- \label{fig:file_filesys_detail}
-\end{figure}
-
-Da fig.~\ref{fig:file_filesys_detail} si evidenziano alcune delle
-caratteristiche di base di un filesystem, sulle quali è bene porre attenzione
-visto che sono fondamentali per capire il funzionamento delle funzioni che
-manipolano i file e le directory che tratteremo nel prossimo capitolo; in
-particolare è opportuno ricordare sempre che:
-
-\begin{enumerate}
-
-\item L'\textit{inode} \itindex{inode} contiene tutte le informazioni (i
- cosiddetti \textsl{metadati}) riguardanti il file: il tipo di file, i
- permessi di accesso, le dimensioni, i puntatori ai blocchi fisici che
- contengono i dati e così via. Le informazioni che la funzione \func{stat}
- fornisce provengono dall'\textit{inode}; dentro una directory si troverà
- solo il nome del file e il numero \itindex{inode} dell'\textit{inode} ad esso
- associato, cioè quella che da qui in poi chiameremo una \textsl{voce} (come
- traduzione dell'inglese \textit{directory entry}, che non useremo anche per
- evitare confusione con le \textit{dentry} del kernel di cui si parlava in
- sez.~\ref{sec:file_vfs}).
-
-\item Come mostrato in fig.~\ref{fig:file_filesys_detail} si possono avere più
- voci che puntano allo stesso \textit{inode}. Ogni \textit{inode} ha un
- contatore che contiene il numero di riferimenti che sono stati fatti ad esso
- (il cosiddetto \textit{link count}); solo quando questo contatore si annulla
- i dati del file vengono effettivamente rimossi dal disco. Per questo la
- funzione per cancellare un file si chiama \func{unlink}, ed in realtà non
- cancella affatto i dati del file, ma si limita ad eliminare la relativa voce
- da una directory e decrementare il numero di riferimenti \itindex{inode}
- nell'\textit{inode}.
-
-\item Il numero di \textit{inode} nella voce si riferisce ad un \textit{inode}
- nello stesso filesystem e non ci può essere una directory che contiene
- riferimenti ad \itindex{inode} \textit{inode} relativi ad altri filesystem.
- Questo limita l'uso del comando \cmd{ln} (che crea una nuova voce per un
- file esistente con la funzione \func{link}) al filesystem corrente.
-
-\item Quando si cambia nome ad un file senza cambiare filesystem, il contenuto
- del file non viene spostato fisicamente, viene semplicemente creata una
- nuova voce per \itindex{inode} l'\textit{inode} in questione e rimossa la
- vecchia (questa è la modalità in cui opera normalmente il comando \cmd{mv}
- attraverso la funzione \func{rename}). Questa operazione non modifica
- minimamente neanche l'\textit{inode} del file dato che non si opera su
- questo ma sulla directory che lo contiene.
-
-\item Gli \textit{inode} dei file, che contengono i \textsl{metadati} ed i
- blocchi di spazio disco, che contengono i dati, sono risorse indipendenti ed
- in genere vengono gestite come tali anche dai diversi filesystem; è pertanto
- possibile sia esaurire lo spazio disco (caso più comune) che lo spazio per
- gli \textit{inode}, nel primo caso non sarà possibile allocare ulteriore
- spazio, ma si potranno creare file (vuoti), nel secondo non si potranno
- creare nuovi file, ma si potranno estendere quelli che ci sono.
-
-\end{enumerate}
-
-Infine si noti che, essendo file pure loro, il numero di riferimenti esiste
-anche per le directory; per cui, se a partire dalla situazione mostrata in
-fig.~\ref{fig:file_filesys_detail} creiamo una nuova directory \file{img}
-nella directory \file{gapil}, avremo una situazione come quella in
-fig.~\ref{fig:file_dirs_link}, dove per chiarezza abbiamo aggiunto dei numeri
-di \itindex{inode} inode.
-
-\begin{figure}[!htb]
- \centering
- \includegraphics[width=14cm]{img/dir_links}
- \caption{Organizzazione dei \textit{link} per le directory.}
- \label{fig:file_dirs_link}
-\end{figure}
-
-La nuova directory avrà allora un numero di riferimenti pari a due, in quanto
-è referenziata dalla directory da cui si era partiti (in cui è inserita la
-nuova voce che fa riferimento a \texttt{img}) e dalla voce ``\texttt{.}'' che
-è sempre inserita in ogni directory; questo vale sempre per ogni directory che
-non contenga a sua volta altre directory. Al contempo, la directory da cui si
-era partiti avrà un numero di riferimenti di almeno tre, in quanto adesso sarà
-referenziata anche dalla voce ``\texttt{..}'' di \texttt{img}.
-
-
-\subsection{I filesystem di uso comune}
-\label{sec:file_ext2}
-
-Il filesystem standard più usato con Linux è il cosiddetto \textit{third
- extended filesystem}, identificato dalla sigla \acr{ext3}.\footnote{si fa
- riferimento al momento della stesura di questo paragrafo, l'inizio del
- 2010.} Esso nasce come evoluzione del precedente \textit{second extended
- filesystem}, o \acr{ext2}, di cui eredita gran parte delle caratteristiche
-di base, per questo motivo parleremo anzitutto di questo, dato che molto di
-quanto diremo si applica anche ad \acr{ext3}. A partire dal kernel 2.6.XX è
-stato dichiarato stabile il nuovo filsesystem \textit{ext4}, ulteriore
-evoluzione di \textit{ext3} dotato di molte caratteristiche avanzate, che sta
-iniziando a sostituirlo gradualmente.
-
-Il filesystem \acr{ext2} nasce come filesystem nativo di Linux a partire dalle
-prime versioni del kernel e supporta tutte le caratteristiche di un filesystem
-standard Unix: è in grado di gestire nomi di file lunghi (256 caratteri,
-estensibili a 1012) e supporta una dimensione massima dei file fino a 4~Tb. I
-successivi filesystem \acr{ext3} ed \acr{ext4} sono evoluzioni di questo
-filesystem, e sia pure con molti miglioramenti ed estensioni significative ne
-mantengono in sostanza le caratteristiche fondamentali.
-
-Oltre alle caratteristiche standard, \acr{ext2} fornisce alcune estensioni che
-non sono presenti su un classico filesystem di tipo Unix; le principali sono
-le seguenti:
-\begin{itemize}
-\item i \textit{file attributes} consentono di modificare il comportamento del
- kernel quando agisce su gruppi di file. Possono essere impostati su file e
- directory e in quest'ultimo caso i nuovi file creati nella directory
- ereditano i suoi attributi.
-\item sono supportate entrambe le semantiche di BSD e SVr4 come opzioni di
- montaggio. La semantica BSD comporta che i file in una directory sono creati
- con lo stesso identificatore di gruppo della directory che li contiene. La
- semantica SVr4 comporta che i file vengono creati con l'identificatore del
- gruppo primario del processo, eccetto il caso in cui la directory ha il bit
- di \acr{sgid} impostato (per una descrizione dettagliata del significato di
- questi termini si veda sez.~\ref{sec:file_access_control}), nel qual caso
- file e subdirectory ereditano sia il \acr{gid} che lo \acr{sgid}.
-\item l'amministratore può scegliere la dimensione dei blocchi del filesystem
- in fase di creazione, a seconda delle sue esigenze (blocchi più grandi
- permettono un accesso più veloce, ma sprecano più spazio disco).
-\item il filesystem implementa link simbolici veloci, in cui il nome del file
- non è salvato su un blocco, ma tenuto all'interno \itindex{inode} dell'inode
- (evitando letture multiple e spreco di spazio), non tutti i nomi però
- possono essere gestiti così per limiti di spazio (il limite è 60 caratteri).
-\item vengono supportati i file immutabili (che possono solo essere letti) per
- la protezione di file di configurazione sensibili, o file
- \textit{append-only} che possono essere aperti in scrittura solo per
- aggiungere dati (caratteristica utilizzabile per la protezione dei file di
- log).
-\end{itemize}
-
-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 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
- usata dal kernel per un filesystem \acr{ext2}, definita nel file
- \texttt{ext2\_fs.h} nella directory \texttt{include/linux} dei sorgenti del
- kernel.}
-
-Ciascun gruppo di blocchi contiene una copia delle informazioni essenziali del
-filesystem (superblock e descrittore del filesystem sono quindi ridondati) per
-una maggiore affidabilità e possibilità di recupero in caso di corruzione del
-superblock principale. L'utilizzo di raggruppamenti di blocchi ha inoltre
-degli effetti positivi nelle prestazioni dato che viene ridotta la distanza
-fra i dati e la tabella degli \itindex{inode} inode.
-
-\begin{figure}[!htb]
- \centering
- \includegraphics[width=9cm]{img/dir_struct}
- \caption{Struttura delle directory nel \textit{second extented filesystem}.}
- \label{fig:file_ext2_dirs}
-\end{figure}
-
-Le directory sono implementate come una \itindex{linked~list} \textit{linked
- list} con voci di dimensione variabile. Ciascuna voce della lista contiene
-il numero di inode \itindex{inode}, la sua lunghezza, il nome del file e la sua
-lunghezza, secondo lo schema in fig.~\ref{fig:file_ext2_dirs}; in questo modo
-è possibile implementare nomi per i file anche molto lunghi (fino a 1024
-caratteri) senza sprecare spazio disco.
-
-Con l'introduzione del filesystem \textit{ext3} sono state introdotte anche
-alcune modifiche strutturali, la principale di queste è quella che
-\textit{ext3} è un filesystem \textit{jounrnaled}, è cioè in grado di eseguire
-una registrazione delle operazioni di scrittura su un giornale (uno speciale
-file interno) in modo da poter garantire il ripristino della coerenza dei dati
-del filesystem\footnote{si noti bene che si è parlato di dati \textsl{del}
- filesystem, non di dati \textsl{nel} filesystem, quello di cui viene
- garantito un veloce ripristino è relativo ai dati della struttura interna
- del filesystem, non di eventuali dati contenuti nei file che potrebbero
- essere stati persi.} in brevissimo tempo in caso di interruzione improvvisa
-della corrente o di crollo del sistema che abbia causato una interruzione
-della scrittura dei dati sul disco.
-
-Oltre a questo \textit{ext3} introduce ulteriori modifiche volte a migliorare
-sia le prestazioni che la semplicità di gestione del filesystem, in
-particolare per le directory si è passato all'uso di alberi binari con
-indicizzazione tramite hash al posto delle \textit{linked list}, ottenendo un
-forte guadagno di prestazioni in caso di directory contenenti un gran numero
-di file.
-
-% TODO portare a ext3, ext4 e btrfs ed illustrare le problematiche che si
-% possono incontrare (in particolare quelle relative alla perdita di contenuti
-% in caso di crash del sistema)
+%\chapter{L'architettura dei file}
+%\label{cha:file_intro}
+% capitolo eliminato, inglobando altrove
% LocalWords: everything is device kernel filesystem sez pathname root glibc
% LocalWords: path filename bootloader proc name components fifo socket dev LF
\include{intro}
\include{process}
\include{prochand}
-\include{fileintro}
+%\include{fileintro}
\include{filedir}
\include{fileunix}
\include{filestd}
Le periferiche infine vengono normalmente viste attraverso un'interfaccia
astratta che permette di trattarle come se fossero dei file, secondo uno dei
concetti base della architettura di Unix, per cui ``\textsl{tutto è in file}''
-(\textit{everything is a file}) su cui torneremo in dettaglio in
-cap.~\ref{cha:file_intro}. In realtà questo non è sempre vero (ad esempio non
-lo è per le interfacce di rete) dato che ci sono periferiche che non
+(\textit{everything is a file}) su cui torneremo in
+sez.~\ref{sec:intro_file_dir}. In realtà questo non è sempre vero (ad esempio
+non lo è per le interfacce di rete) dato che ci sono periferiche che non
rispondendo bene a questa astrazione richiedono un'interfaccia diversa. Anche
in questo caso però resta valido il concetto generale che tutto il lavoro di
accesso e gestione delle periferiche a basso livello viene effettuato dal
impossibile, di far eseguire un programma a partire da un computer appena
acceso che appunto non ne contiene nessuno; non è impossibile perché in
realtà c'è un programma iniziale, che è il BIOS.} incaricandosi di caricare
-il kernel in memoria e di farne partire l'esecuzione. A questo punto il
-controllo passerà al kernel, il quale però da parte sua, una volta
-inizializzato opportunamente l'hardware, si limiterà a lanciare un unico
-processo di inizializzazione (che per questo in genere genere si chiama
-\cmd{init}). A questo punto tutto il lavoro verrà eseguito \textit{user space}
-da questo programma, che sua volta si incaricherà di lanciare tutti gli altri,
-fra cui ci sarà quello che si occupa di dialogare con la tastiera e lo schermo
-della console, quello che mette a disposizione un terminale e la
-\textit{shell} da cui inviare i comandi all'utente che si vuole collegare, ed
-in generale tutto quanto necessario ad avere un sistema utilizzabile.
+il kernel in memoria e di farne partire l'esecuzione.
+
+A questo punto il controllo passerà al kernel, il quale però da parte sua, una
+volta inizializzato opportunamente l'hardware, si limiterà a due sole
+operazioni, montare il filesystem radice (torneremo su questo in
+sez.~\ref{sec:file_arch_overview}) e lanciare il primo processo che eseguirà
+il programma di inizializzazione del sistema, che in genere, visto il suo
+scopo, si chiama \cmd{init}.
+
+Una volta lanciato \cmd{init} tutto il lavoro successivo verrà eseguito
+\textit{user space} da questo programma, che sua volta si incaricherà di
+lanciare tutti gli altri programmi, fra cui ci sarà quello che si occupa di
+dialogare con la tastiera e lo schermo della console, quello che mette a
+disposizione un terminale e la \textit{shell} da cui inviare i comandi
+all'utente che si vuole collegare, ed in generale tutto quanto necessario ad
+avere un sistema utilizzabile.
E' da rimarcare come tutto ciò che riguarda l'interazione con l'utente, che
usualmente viene visto come parte del sistema, non abbia in realtà niente a
attraverso dei normali programmi utilizzando le interfacce di programmazione
che il kernel mette a disposizione.
-%Una delle caratteristiche base di unix \`e perci\`o che \`e possibile
-%realizzare un sistema di permessi e controlli che evitano che i programmi
-%eseguano accessi non autorizzati.
-
È per questo motivo che quando ci si riferisce al sistema nella sua interezza
viene spesso sottolineato come sia corretto parlare di ``GNU/Linux'' e non di
Linux; da solo infatti il kernel non è sufficiente, quello che costruisce un
il cui \acr{uid} è zero. Esso identifica l'amministratore del sistema, che
deve essere in grado di fare qualunque operazione; per l'utente \textit{root}
infatti i meccanismi di controllo cui si è accennato in precedenza sono
-disattivati.\footnote{i controlli infatti vengono eseguiti da uno pseudocodice
+disattivati.\footnote{i controlli infatti vengono eseguiti da uno pseudo-codice
del tipo: ``\code{if (uid) \{ \textellipsis\ \}}''.}
+%Rimosse
+% \section{L'architettura della gestione dei file}
+% \label{sec:file_arch_func}
+
+\section{L'architettura di file e directory}
+\label{sec:intro_file_dir}
+
+Come accennato in sez.~\ref{sec:intro_base_concept} uno dei concetti
+fondamentali dell'architettura di un sistema Unix è il cosiddetto
+\textit{everything is a file} (\textsl{tutto è un file}), cioè il fatto che
+l'accesso ai vari dispositivi di input/output del computer viene effettuato
+attraverso un'interfaccia astratta che tratta le periferiche allo stesso modo
+dei normali file di dati.
+
+In questa sezione forniremo una descrizione a grandi linee dell'architettura
+della gestione file in Linux, partendo da una introduzione ai concetti di
+base, per poi illustrare l'organizzazione di file e directory, i tipi di file
+concludendo con una panoramica sulle caratteristiche principali delle
+interfacce con cui i processi accedono ai file.
+
+
+\subsection{Una panoramica generale}
+\label{sec:file_arch_overview}
+
+Per poter accedere ai file, il kernel deve mettere a disposizione dei
+programmi delle opportune interfacce che consentano di leggerne il
+contenuto. Questo ha due aspetti: il primo è che il kernel, per il concetto
+dell'\textit{everything is a file}, deve fornire una interfaccia che consenta
+di operare sui file, sia che questi corrispondano ai normali file di dati, sia
+che siano quei file speciali (i cosiddetti \index{file!di~dispositivo} file di
+dispositivo, o \textit{device file}) che permettono di accedere alle
+periferiche.
+
+Il secondo aspetto è che per poter utilizzare dei normali file di dati il
+kernel deve provvedere ad organizzare e rendere accessibile in maniera
+opportuna l'informazione in essi contenuta memorizzandola sullo spazio grezzo
+disponibile sui dischi. Questo viene fatto strutturando l'informazione sul
+disco attraverso quello che si chiama un
+``\textit{filesystem}''. L'informazione così strutturata poi viene resa
+disponibile ai processi attraverso quello che viene chiamato il
+``\textsl{montaggio}'' del filesystem nell'albero dei file, dove il contenuto
+sarà accessibile nella forma ordinaria di file e directory.
+
+In Linux il concetto di \textit{everything is a file} è stato implementato
+attraverso il \textit{Virtual File System} (che da qui in poi abbrevieremo in
+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.
+
+Il VFS fornisce cioè quel livello di indirezione che permette di collegare le
+operazioni interne del kernel per la manipolazione sui file con le
+\textit{system call} relative alle operazioni di I/O, e gestisce
+l'organizzazione dette operazioni nei vari modi in cui i diversi filesystem le
+effettuano, permettendo la coesistenza di filesystem differenti all'interno
+dello stesso albero delle directory. Torneremo su questa interfaccia generica
+fornita dal \textit{Virtual File System} in sez.~\ref{sec:file_vfs_work}.
+
+In sostanza quando un processo esegue una \textit{system call} che opera su un
+file, il kernel chiama sempre una funzione implementata nel VFS; la funzione
+eseguirà le manipolazioni sulle strutture generiche e utilizzerà poi la
+chiamata alle opportune funzioni del filesystem specifico a cui si fa
+riferimento. Saranno queste a chiamare le funzioni di più basso livello che
+eseguono le operazioni di I/O sul dispositivo fisico, secondo lo schema
+riportato in fig.~\ref{fig:file_VFS_scheme}.
+
+\begin{figure}[!htb]
+ \centering
+ \includegraphics[width=7cm]{img/vfs}
+ \caption{Schema delle operazioni del VFS.}
+ \label{fig:file_VFS_scheme}
+\end{figure}
+
+Questa interfaccia resta la stessa anche quando, invece che a dei normali
+file, si accede alle periferiche coi citati \index{file!di~dispositivo} file
+di dispositivo, solo che in questo caso invece di usare il codice del
+filesystem che accede al disco, il \textit{Virtual File System} eseguirà
+direttamente il codice del kernel che permette di accedere alla periferica.
+
+Come accennato all'inizio una delle funzioni essenziali per il funzionamento
+dell'interfaccia dei file è quella che consente di montare un filesystem
+nell'albero dei file, e rendere così visibili i suoi contenuti. In un sistema
+unix-like infatti, a differenza di quanto avviene in altri sistemi operativi,
+tutti i file vengono mantenuti all'interno di un unico albero la cui radice
+(quella che viene chiamata \textit{root directory}) viene montata all'avvio
+direttamente dal kernel.
+
+Come accennato in sez.~\ref{sec:intro_kern_and_sys}) montare la radice è,
+insieme al lancio di \cmd{init},\footnote{l'operazione è ovviamente anche
+ preliminare al lancio di \cmd{init}, dato il kernel deve poter accedere al
+ file che contiene detto programma.} l'unica operazione che viene effettuata
+direttamente dal kernel in fase di avvio quando, completata la fase di
+inizializzazione, esso riceve dal bootloader l'indicazione di quale
+dispositivo contiene il filesystem da usare come punto di partenza e questo
+viene posto alla radice dell'albero dei file.
+
+Tutti gli ulteriori filesystem che possono essere disponibili su altri
+dispositivi dovranno a loro volta essere inseriti nell'albero, montandoli su
+altrettante directory del filesystem radice. Questo comunque avverrà sempre in
+un secondo tempo, in genere a cura dei programmi eseguiti nella procedura di
+inizializzazione del sistema, grazie alle funzioni che tratteremo in
+sez.~\ref{sec:sys_file_config}.
+
+
+\subsection{La risoluzione del nome di file e directory}
+\label{sec:file_pathname}
+
+\itindbeg{pathname}
+
+Come appena illustrato sez.~\ref{sec:file_arch_overview} una delle
+caratteristiche distintive di un sistema unix-like è quella di avere un unico
+albero dei file. Un file deve essere identificato dall'utente usando quello
+che viene chiamato il suo \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 la shell cerca 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.} vale a dire tramite il
+percorso che si deve fare per accedere al file a partire da una certa
+``\textit{directory}''.
+
+Una directory, come vedremo in maggior dettaglio in
+sez.~\ref{sec:file_vfs_work}, è anch'essa un file (è cioè un oggetto di un
+filesystem), solo che è un file speciale che il kernel riconosce appunto come
+directory. Il suo scopo è quello di contenere una lista di nomi di file e le
+informazioni che associano ciascun nome al suo 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 nomi di directory dentro altre
+directory. All'interno dello stesso albero si potranno poi inserire anche
+tutti gli altri oggetti previsti l'interfaccia del VFS (su cui torneremo in
+sez.~\ref{sec:file_file_types}), come le fifo, i link, i socket e gli stessi
+\index{file!di~dispositivo} file di dispositivo.
+
+La convenzione usata nei sistemi unix-like per indicare i \textit{pathname}
+dei file è quella di usare il carattere ``\texttt{/}'' come separatore fra i
+nomi che indicano le directory che lo compongono. Dato che la directory radice
+sta in cima all'albero, essa viene indicata semplicemente con il
+\textit{pathname} \file{/}.
+
+Un file può essere indicato rispetto ad una directory semplicemente
+specificandone il nome, il manuale della \acr{glibc} chiama i nomi contenuti
+nelle directory \textsl{componenti} (in inglese \textit{file name
+ components}), noi li chiameremo più semplicemente \textsl{nomi} o
+\textsl{voci}. Il procedimento con cui dato un \textit{pathname} si individua
+il file a cui esso fa riferimento è chiamato 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 il carattere ``\texttt{/}'' come separatore. Nel caso si indichi un
+nome vuoto il costrutto ``\texttt{//}'' viene considerato equivalente a
+``\texttt{/}''. 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} comincia con il carattere ``\texttt{/}'' la ricerca
+parte dalla directory radice del processo. Questa, a meno di non avere
+eseguito una \func{chroot} (funzione 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} \itindsub{pathname}{assoluto}. Altrimenti la
+ricerca parte dalla directory di lavoro corrente del processo (su cui
+torneremo in sez.~\ref{sec:file_work_dir}) ed il \textit{pathname} è detto
+\itindsub{pathname}{relativo} \textsl{pathname relativo}.
+
+Infine nomi di directory ``\file{.}'' e ``\file{..}'' hanno un significato
+speciale e vengono inseriti in ogni directory quando questa viene creata (vedi
+sez.~\ref{sec:file_dir_creat_rem}). Il primo fa riferimento alla directory
+corrente e il secondo alla directory \textsl{genitrice} (o \textit{parent
+ directory}) cioè la directory che contiene il riferimento alla directory
+corrente.
+
+In questo modo con ``\file{..}'' si può usare un \textsl{pathname relativo}
+per indicare un file posto al di sopra della directory corrente, tornando
+all'indietro nell'albero dei file. Questa retromarcia però su fermerà una
+volta raggiunta la directory radice, perché non esistendo in questo caso una
+directory superiore, il nome ``\file{..}'' farà riferimento alla radice
+stessa.
+
+\itindend{pathname}
+
+
+\subsection{I tipi di file}
+\label{sec:file_file_types}
+
+Parlare dei tipi di file su Linux, come per qualunque sistema unix-like,
+significa anzitutto chiarire il proprio vocabolario e sottolineare le
+differenze che ci sono rispetto ad altri sistemi operativi.
+
+Come accennato in sez.~\ref{sec:file_arch_overview} su Linux l'uso del
+\itindex{Virtual~File~System} \textit{Virtual File System} consente di
+trattare come file oggetti molto diversi fra loro. Oltre ai normali file di
+dati abbiamo già accennato ad altri due di questi oggetti, i file di
+dispositivo e le directory, ma ne esistono altri. In genere quando si parla di
+tipo di file su Linux si fa riferimento a questi, di cui si riportato l'elenco
+completo in tab.~\ref{tab:file_file_types}.
+
+\begin{table}[htb]
+ \footnotesize
+ \centering
+ \begin{tabular}[c]{|l|l|p{6cm}|}
+ \hline
+ \multicolumn{2}{|c|}{\textbf{Tipo di file}} & \textbf{Descrizione} \\
+ \hline
+ \hline
+ \textit{regular file} & \textsl{file regolare} &
+ Un file che contiene dei dati (l'accezione normale di file).\\
+ \textit{directory} & \textsl{cartella o direttorio} &
+ Un file che contiene una lista di nomi associati a degli
+ \itindex{inode} \textit{inode} (vedi sez.~\ref{sec:file_vfs_work}).\\
+ \textit{symbolic link} & \textsl{collegamento simbolico} &
+ Un file che contiene un riferimento ad un altro file/directory.\\
+ \textit{char device} & \textsl{dispositivo a caratteri} &
+ Un file \textsl{speciale} che identifica una periferica ad accesso a
+ caratteri.\\
+ \textit{block device} & \textsl{dispositivo a blocchi} &
+ Un file \textsl{speciale} che identifica una periferica ad accesso a
+ blocchi.\\
+ \textit{fifo} & ``\textsl{coda}'' &
+ Un file \textsl{speciale} che identifica una linea di comunicazione
+ unidirezionale (vedi sez.~\ref{sec:ipc_named_pipe}).\\
+ \textit{socket} & ``\textsl{presa}''&
+ Un file \textsl{speciale} che identifica una linea di comunicazione
+ bidirezionale (vedi cap.~\ref{cha:socket_intro}).\\
+ \hline
+ \end{tabular}
+ \caption{Tipologia dei file definiti nel VFS}
+ \label{tab:file_file_types}
+\end{table}
+
+Si tenga ben presente che questa classificazione non ha nulla a che fare con
+una classificazione dei file in base al tipo loro del contenuto, dato che in
+tal caso si avrebbe a che fare sempre e solo con dei file di dati, e neanche
+con le eventuali diverse modalità con cui si potrebbe accedere al contenuto.
+La classificazione di tab.~\ref{tab:file_file_types} riguarda invece il tipo
+di oggetti gestiti dal \itindex{Virtual~File~System} \textit{Virtual File
+ System}, ed è da notare la presenza dei cosiddetti file
+``\textsl{speciali}''.
+
+Alcuni di essi, come le \textit{fifo} (che tratteremo in
+sez.~\ref{sec:ipc_named_pipe}) ed i \textit{socket} (che tratteremo in
+cap.~\ref{cha:socket_intro}) non sono altro che dei riferimenti per utilizzare
+alcune funzionalità di comunicazione fornite dal kernel. Gli altri sono
+proprio quei \index{file!di~dispositivo} \textsl{file di dispositivo} che
+costituiscono una interfaccia diretta per leggere e scrivere sui dispositivi
+fisici. Anche se finora li abbiamo messi insieme essi sono tradizionalmente
+suddivisi in due grandi categorie, \textsl{a blocchi} e \textsl{a caratteri} a
+seconda delle modalità in cui il dispositivo sottostante effettua le
+operazioni di I/O.
+
+I dispositivi a blocchi (ad esempio i dischi) sono quelli corrispondono a
+periferiche per le quali è richiesto che l'I/O venga effettuato per blocchi di
+dati di dimensioni fissate (ad esempio le dimensioni di un settore), mentre i
+dispositivi a caratteri sono quelli per cui l'I/O può essere effettuato senza
+nessuna particolare struttura.
+
+Una delle differenze principali con altri sistemi operativi (come il VMS o
+Windows) è che per Unix tutti i file di dati sono identici e contengono un
+flusso continuo di byte. Non esiste cioè differenza per come vengono visti dal
+sistema file di diverso contenuto o formato, come nel caso di quella fra file
+di testo e binari che c'è in Windows. Non c'è neanche una strutturazione a
+record per il cosiddetto ``\textsl{accesso diretto}'' come nel caso del
+VMS.\footnote{questo vale anche per i dispositivi a blocchi: la strutturazione
+ dell'I/O in blocchi di dimensione fissa avviene solo all'interno del kernel,
+ 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
+ \index{file!di~dispositivo} 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 ma
+ ormai in sostanziale disuso.}
+
+Una differenza che attiene ai contenuti di un file però esiste, ed è relativa
+al formato dei file di testo. Nei sistemi unix-like la fine riga è codificata
+in maniera diversa da Windows o dal vecchio MacOS, in particolare il fine riga
+è il carattere \texttt{LF} (\verb|\n|) al posto del \texttt{CR} (\verb|\r|)
+del vecchio MacOS e del \texttt{CR LF} (\verb|\r\n|) di Windows. Questo può
+causare alcuni problemi qualora nei programmi si facciano assunzioni sul
+terminatore della riga e per questo esistono dei programmi come \cmd{unix2dos}
+e \cmd{dos2unix} che effettuano una conversione fra questi due formati di
+testo.
+
+Si ricordi comunque che un kernel unix-like non fornisce nessun supporto per
+la tipizzazione dei file di dati in base al loro contenuto e che non c'è
+nessun supporto per una qualche interpretazione delle estensioni (nel nome del
+file) da parte del kernel,\footnote{non è così ad esempio nel filesystem HFS
+ dei Mac, che supporta delle risorse associate ad ogni file, che specificano
+ fra l'altro il contenuto ed il programma da usare per leggerlo; in realtà
+ per alcuni filesystem esiste la possibilità di associare delle risorse ai
+ file con gli \textit{extended attributes} (vedi sez.~\ref{sec:file_xattr}),
+ ma è una caratteristica tutt'ora poco utilizzata, dato che non corrisponde
+ al modello classico dei file in un sistema Unix.} ogni classificazione di
+questo tipo avviene sempre in \textit{user-space}. Gli unici file di cui il
+kernel deve essere in grado di capire il contenuto sono i binari dei
+programmi, per i quali sono supportati solo alcuni formati, anche se oggi
+viene usato quasi esclusivamente l'ELF.\footnote{il nome è l'acronimo di
+ \textit{Executable and Linkable Format} un formato per eseguibili binari
+ molto flessibile ed estendibile definito nel 1995 dal \textit{Tool Interface
+ Standard} che per le sue caratteristiche di non essere legato a nessun
+ tipo di processore o architettura è stato adottato da molti sistemi
+ unix-like e non solo.}
+
+Nonostante l'assenza di supporto da parte del kernel per la classificazione
+del contenuto dei file di dati, molti programmi adottano comunque delle
+convenzioni per i nomi dei file, ad esempio il codice C normalmente si mette
+in file con l'estensione \file{.c}. Inoltre una tecnica molto usata per
+classificare i contenuti da parte dei programmi è quella di utilizzare i primi
+4 byte del file per memorizzare un \textit{magic number} che classifichi il
+contenuto. Entrambe queste tecniche, per quanto usate ed accettate in maniera
+diffusa, restano solo delle convenzioni il cui rispetto è demandato alle
+applicazioni stesse.
+
+
+\subsection{Le due interfacce per l'accesso ai file}
+\label{sec:file_io_api}
+
+In Linux le interfacce di programmazione per l'accesso al contenuto dei file
+due. La prima è l'interfaccia nativa del sistema, quella che il manuale delle
+\textsl{glibc} chiama interfaccia dei descrittori di file (o \textit{file
+ descriptor}). Si tratta di un'interfaccia specifica dei sistemi unix-like e
+fornisce un accesso non bufferizzato.
+
+L'interfaccia è primitiva ed essenziale, l'accesso viene detto non
+bufferizzato in quanto la lettura e la scrittura vengono eseguite chiamando
+direttamente le \textit{system call} del kernel (in realtà il kernel effettua
+al suo interno alcune bufferizzazioni per aumentare l'efficienza nell'accesso
+ai dispositivi). L'accesso viene gestito attraverso i \index{file!descriptor}
+\textit{file descriptor} che sono rappresentati da numeri interi (cioè
+semplici variabili di tipo \ctyp{int}). L'interfaccia è definita
+nell'\textit{header file} \file{unistd.h} e la tratteremo in dettaglio in
+cap.~\ref{cha:file_unix_interface}.
+
+La seconda interfaccia è quella che il manuale della \acr{glibc} chiama dei
+\index{file!stream} \textit{file stream} o più semplicemente
+\textit{stream}.\footnote{in realtà una interfaccia con lo stesso nome è stata
+ introdotta a livello di kernel negli Unix derivati da \textit{System V},
+ come strato di astrazione per file e socket; in Linux questa interfaccia,
+ che comunque ha avuto poco successo, non esiste, per cui facendo riferimento
+ agli \index{file!stream} \textit{stream} useremo il significato adottato dal
+ manuale delle \acr{glibc}.} Essa fornisce funzioni più evolute e un accesso
+bufferizzato, controllato dalla implementazione fatta nella \acr{glibc}.
+Questa è l'interfaccia standard specificata dall'ANSI C e perciò si trova
+anche su tutti i sistemi non Unix. Gli \index{file!stream} \textit{stream}
+sono oggetti complessi e sono rappresentati da puntatori ad un opportuna
+struttura definita dalle librerie del C, ad essi si accede sempre in maniera
+indiretta utilizzando il tipo \type{FILE *}. L'interfaccia è definita
+nell'\textit{header file} \file{stdio.h} e la tratteremo in dettaglio nel
+cap.~\ref{cha:files_std_interface}.
+
+Entrambe le interfacce possono essere usate per l'accesso ai file come agli
+altri oggetti del VFS, ma per poter accedere alle operazioni di controllo
+(descritte in sez.~\ref{sec:file_fcntl} e sez.~\ref{sec:file_ioctl}) su un
+qualunque tipo di oggetto del VFS occorre usare l'interfaccia standard di Unix
+con i \textit{file descriptor}. Allo stesso modo devono essere usati i
+\index{file!descriptor} \textit{file descriptor} se si vuole ricorrere a
+modalità speciali di I/O come il \index{file!locking} \textit{file locking} o
+l'I/O non-bloccante (vedi cap.~\ref{cha:file_advanced}).
+
+Gli \textit{stream} forniscono un'interfaccia di alto livello costruita sopra
+quella dei \textit{file descriptor}, che permette di poter scegliere tra
+diversi stili di bufferizzazione. Il maggior vantaggio degli \textit{stream}
+è che l'interfaccia per le operazioni di input/output è molto più ricca di
+quella dei \textit{file descriptor}, che forniscono solo funzioni elementari
+per la lettura/scrittura diretta di blocchi di byte. In particolare gli
+\index{file!stream} \textit{stream} dispongono di tutte le funzioni di
+formattazione per l'input e l'output adatte per manipolare anche i dati in
+forma di linee o singoli caratteri.
+
+In ogni caso, dato che gli \textit{stream} sono implementati sopra
+l'interfaccia standard di Unix, è sempre possibile estrarre il \textit{file
+ descriptor} da uno \textit{stream} ed eseguirvi operazioni di basso livello,
+o associare in un secondo tempo uno \index{file!stream} \textit{stream} ad un
+\index{file!descriptor} \textit{file descriptor} per usare l'interfaccia più
+ricca.
+
+In generale, se non necessitano specificatamente le funzionalità di basso
+livello, è opportuno usare sempre gli \index{file!stream} \textit{stream} per
+la loro maggiore portabilità, essendo questi ultimi definiti nello standard
+ANSI C; l'interfaccia con i \index{file!descriptor} \textit{file descriptor}
+infatti segue solo lo standard POSIX.1 dei sistemi Unix, ed è pertanto di
+portabilità più limitata.
+
+
\section{Gli standard}
\label{sec:intro_standard}
talvolta poi i riferimenti cambiano nome, per cui anche solo seguire le
denominazioni usate diventa particolarmente faticoso; una pagina dove si
possono recuperare varie (e di norma piuttosto intricate) informazioni è
-\href{http://www.pasc.org/standing/sd11.html}
-{\textsf{http://www.pasc.org/standing/sd11.html}}.
+\url{http://www.pasc.org/standing/sd11.html}.
\begin{table}[htb]
\footnotesize
% LocalWords: assert ctype dirent errno fcntl limits malloc setjmp signal utmp
% LocalWords: stdarg stdio stdlib string times unistd library int short caddr
% LocalWords: address clock dev ino inode key IPC loff nlink off pid rlim size
-% LocalWords: sigset ssize ptrdiff sys IEEE Richard Portable of TR
+% LocalWords: sigset ssize ptrdiff sys IEEE Richard Portable of TR filesystem
% LocalWords: Operating Interface dell'IEEE Electrical and Electronics thread
% LocalWords: Engeneers Socket NT matching regular expression scheduling l'I
% LocalWords: XPG Portability Issue Application Programmable XTI Transport AT
% LocalWords: drand fmtmsg define SOURCE lbsd compat XOPEN version ISOC Large
% LocalWords: LARGEFILE Support LFS dell' black rectangle node fill cpu draw
% LocalWords: ellipse mem anchor west proc SysV SV Definition SCO Austin XSI
-% LocalWords: Technical TC SUS Opengroup features STRICT std ATFILE fseeko
+% LocalWords: Technical TC SUS Opengroup features STRICT std ATFILE fseeko VFS
% LocalWords: ftello fseek ftell lseek FORTIFY REENTRANT SAFE overflow memcpy
% LocalWords: mempcpy memmove memset stpcpy strcpy strncpy strcat strncat gets
% LocalWords: sprintf snprintf vsprintf vsnprintf syscall number calendar BITS
-% LocalWords: pathname Google Android standards
+% LocalWords: pathname Google Android standards device Virtual bootloader path
%%% Local Variables:
%%% mode: latex
%%% TeX-master: "gapil"
%%% End:
+% LocalWords: filename fifo name components resolution chroot parent symbolic
+% LocalWords: char block VMS raw access MacOS LF CR dos HFS Mac attributes
+% LocalWords: Executable Linkable Format Tool magic descriptor stream locking
+% LocalWords: process
La funzione è pensata per eseguire una conclusione pulita di un programma che
usi la libreria standard del C; essa esegue tutte le funzioni che sono state
registrate con \func{atexit} e \func{on\_exit} (vedi
-sez.~\ref{sec:proc_atexit}), chiude tutti i \textit{file stream} (vedi
+sez.~\ref{sec:proc_atexit}), chiude tutti gli \textit{stream} (vedi
sez.~\ref{sec:file_stream}) effettuando il salvataggio dei dati sospesi
(chiamando \func{fclose}, vedi sez.~\ref{sec:file_fopen}), infine passa il
controllo al kernel chiamando la \textit{system call} \func{\_exit} (che
La funzione termina immediatamente il processo e le eventuali funzioni
registrate con \func{atexit} e \func{on\_exit} non vengono eseguite. La
funzione chiude tutti i file descriptor appartenenti al processo, cosa che
-però non comporta il salvataggio dei dati eventualmente presenti nei buffer di
-\textit{file stream}, (torneremo sulle due interfacce dei file in
+però non comporta il salvataggio dei dati eventualmente presenti nei buffer
+degli \textit{stream}, (torneremo sulle due interfacce dei file in
cap.~\ref{cha:files_std_interface} e
cap.~\ref{cha:file_unix_interface})). Infine fa sì che ogni figlio del
processo sia adottato da \cmd{init} (vedi sez.~\ref{sec:proc_termination}),
indipendentemente dalla funzione usata per farla.
Una volta completata l'esecuzione di tutte le funzioni registrate verranno
-chiusi tutti i \textit{file stream} aperti ed infine verrà chiamata
-\func{\_exit} per la terminazione del programma. Questa è la sequenza
-ordinaria, eseguita a meno che una delle funzioni registrate non esegua al suo
-interno \func{\_exit}, nel qual caso la terminazione del programma sarà
-immediata ed anche le successive funzioni registrate non saranno invocate.
+chiusi tutti gli \textit{stream} aperti ed infine verrà chiamata \func{\_exit}
+per la terminazione del programma. Questa è la sequenza ordinaria, eseguita a
+meno che una delle funzioni registrate non esegua al suo interno
+\func{\_exit}, nel qual caso la terminazione del programma sarà immediata ed
+anche le successive funzioni registrate non saranno invocate.
Se invece all'interno di una delle funzioni registrate si chiama un'altra
volta \func{exit} lo standard POSIX.1-2001 prescrive un comportamento
Abbiamo visto in sez.~\ref{sec:proc_conclusion} le tre modalità con cui un
programma viene terminato in maniera normale: la chiamata di \func{exit}, che
-esegue le funzioni registrate per l'uscita e chiude i \textit{file stream} e
-poi esegue \func{\_exit}, il ritorno dalla funzione \func{main} equivalente
-alla chiamata di \func{exit}, e la chiamata diretta a \func{\_exit}, che passa
+esegue le funzioni registrate per l'uscita e chiude gli \textit{stream} e poi
+esegue \func{\_exit}, il ritorno dalla funzione \func{main} equivalente alla
+chiamata di \func{exit}, e la chiamata diretta a \func{\_exit}, che passa
direttamente alle operazioni di terminazione del processo da parte del kernel.
Ma abbiamo accennato che oltre alla conclusione normale esistono anche delle
-\subsection{La gestione delle proprietà dei filesystem}
-\label{sec:sys_file_config}
-
-Come accennato in sez.~\ref{sec:file_organization} per poter accedere ai file
-occorre prima rendere disponibile al sistema il filesystem su cui essi sono
-memorizzati; l'operazione di attivazione del filesystem è chiamata
-\textsl{montaggio}, per far questo in Linux\footnote{la funzione è specifica
- di Linux e non è portabile.} si usa la funzione \funcd{mount} il cui
-prototipo è:
-\begin{prototype}{sys/mount.h}
-{mount(const char *source, const char *target, const char *filesystemtype,
- unsigned long mountflags, const void *data)}
-
-Monta il filesystem di tipo \param{filesystemtype} contenuto in \param{source}
-sulla directory \param{target}.
-
- \bodydesc{La funzione ritorna 0 in caso di successo e -1 in caso di
- fallimento, nel qual caso gli errori comuni a tutti i filesystem che possono
- essere restituiti in \var{errno} sono:
- \begin{errlist}
- \item[\errcode{EPERM}] il processo non ha i privilegi di amministratore.
- \item[\errcode{ENODEV}] \param{filesystemtype} non esiste o non è configurato
- nel kernel.
- \item[\errcode{ENOTBLK}] non si è usato un \textit{block device} per
- \param{source} quando era richiesto.
- \item[\errcode{EBUSY}] \param{source} è già montato, o non può essere
- rimontato in read-only perché ci sono ancora file aperti in scrittura, o
- \param{target} è ancora in uso.
- \item[\errcode{EINVAL}] il device \param{source} presenta un
- \textit{superblock} non valido, o si è cercato di rimontare un filesystem
- non ancora montato, o di montarlo senza che \param{target} sia un
- \textit{mount point} o di spostarlo quando \param{target} non è un
- \textit{mount point} o è \file{/}.
- \item[\errcode{EACCES}] non si ha il permesso di accesso su uno dei
- componenti del \itindex{pathname} \textit{pathname}, o si è cercato
- di montare un filesystem disponibile in sola lettura senza averlo
- specificato o il device \param{source} è su un filesystem montato con
- l'opzione \const{MS\_NODEV}.
- \item[\errcode{ENXIO}] il \itindex{major~number} \textit{major number} del
- device \param{source} è sbagliato.
- \item[\errcode{EMFILE}] la tabella dei device \textit{dummy} è piena.
- \end{errlist}
- ed inoltre \errval{ENOTDIR}, \errval{EFAULT}, \errval{ENOMEM},
- \errval{ENAMETOOLONG}, \errval{ENOENT} o \errval{ELOOP}.}
-\end{prototype}
-
-La funzione monta sulla directory \param{target}, detta \textit{mount point},
-il filesystem contenuto in \param{source}. In generale un filesystem è
-contenuto su un disco, e l'operazione di montaggio corrisponde a rendere
-visibile al sistema il contenuto del suddetto disco, identificato attraverso
-il file di dispositivo ad esso associato.
-
-Ma la struttura del virtual filesystem vista in sez.~\ref{sec:file_vfs} è molto
-più flessibile e può essere usata anche per oggetti diversi da un disco. Ad
-esempio usando il \textit{loop device} si può montare un file qualunque (come
-l'immagine di un CD-ROM o di un floppy) che contiene un filesystem, inoltre
-alcuni filesystem, come \file{proc} o \file{devfs} sono del tutto virtuali, i
-loro dati sono generati al volo ad ogni lettura, e passati al kernel ad ogni
-scrittura.
-
-Il tipo di filesystem è specificato da \param{filesystemtype}, che deve essere
-una delle stringhe riportate nel file \procfile{/proc/filesystems}, che
-contiene l'elenco dei filesystem supportati dal kernel; nel caso si sia
-indicato uno dei filesystem virtuali, il contenuto di \param{source} viene
-ignorato.
-
-Dopo l'esecuzione della funzione il contenuto del filesystem viene resto
-disponibile nella directory specificata come \textit{mount point}, il
-precedente contenuto di detta directory viene mascherato dal contenuto della
-directory radice del filesystem montato.
-
-Dal kernel 2.4.x inoltre è divenuto possibile sia spostare atomicamente un
-\textit{mount point} da una directory ad un'altra, sia montare in diversi
-\textit{mount point} lo stesso filesystem, sia montare più filesystem sullo
-stesso \textit{mount point} (nel qual caso vale quanto appena detto, e solo il
-contenuto dell'ultimo filesystem montato sarà visibile).
-
-Ciascun filesystem è dotato di caratteristiche specifiche che possono essere
-attivate o meno, alcune di queste sono generali (anche se non è detto siano
-disponibili in ogni filesystem), e vengono specificate come opzioni di
-montaggio con l'argomento \param{mountflags}.
-
-In Linux \param{mountflags} deve essere un intero a 32 bit i cui 16 più
-significativi sono un \textit{magic number}\footnote{cioè un numero speciale
- usato come identificativo, che nel caso è \code{0xC0ED}; si può usare la
- costante \const{MS\_MGC\_MSK} per ottenere la parte di \param{mountflags}
- riservata al \textit{magic number}.} mentre i 16 meno significativi sono
-usati per specificare le opzioni; essi sono usati come maschera binaria e
-vanno impostati con un OR aritmetico della costante \const{MS\_MGC\_VAL} con i
-valori riportati in tab.~\ref{tab:sys_mount_flags}.
-
-\begin{table}[htb]
- \footnotesize
- \centering
- \begin{tabular}[c]{|l|r|l|}
- \hline
- \textbf{Parametro} & \textbf{Valore}&\textbf{Significato}\\
- \hline
- \hline
- \const{MS\_RDONLY} & 1 & Monta in sola lettura.\\
- \const{MS\_NOSUID} & 2 & Ignora i bit \itindex{suid~bit} \acr{suid} e
- \itindex{sgid~bit} \acr{sgid}.\\
- \const{MS\_NODEV} & 4 & Impedisce l'accesso ai file di dispositivo.\\
- \const{MS\_NOEXEC} & 8 & Impedisce di eseguire programmi.\\
- \const{MS\_SYNCHRONOUS}& 16 & Abilita la scrittura sincrona.\\
- \const{MS\_REMOUNT} & 32 & Rimonta il filesystem cambiando le opzioni.\\
- \const{MS\_MANDLOCK} & 64 & Consente il \textit{mandatory locking}
- \itindex{mandatory~locking} (vedi
- sez.~\ref{sec:file_mand_locking}).\\
- \const{S\_WRITE} & 128 & Scrive normalmente.\\
- \const{S\_APPEND} & 256 & Consente la scrittura solo in
- \itindex{append~mode} \textit{append mode}
- (vedi sez.~\ref{sec:file_sharing}).\\
- \const{S\_IMMUTABLE} & 512 & Impedisce che si possano modificare i file.\\
- \const{MS\_NOATIME} &1024 & Non aggiorna gli \textit{access time} (vedi
- sez.~\ref{sec:file_file_times}).\\
- \const{MS\_NODIRATIME}&2048 & Non aggiorna gli \textit{access time} delle
- directory.\\
- \const{MS\_BIND} &4096 & Monta il filesystem altrove.\\
- \const{MS\_MOVE} &8192 & Sposta atomicamente il punto di montaggio.\\
- \hline
- \end{tabular}
- \caption{Tabella dei codici dei flag di montaggio di un filesystem.}
- \label{tab:sys_mount_flags}
-\end{table}
-
-% TODO aggiornare con i nuovi flag di man mount
-% gli S_* non esistono più come segnalato da Alessio...
-% verificare i readonly mount bind del 2.6.26
-
-Per l'impostazione delle caratteristiche particolari di ciascun filesystem si
-usa invece l'argomento \param{data} che serve per passare le ulteriori
-informazioni necessarie, che ovviamente variano da filesystem a filesystem.
-
-La funzione \func{mount} può essere utilizzata anche per effettuare il
-\textsl{rimontaggio} di un filesystem, cosa che permette di cambiarne al volo
-alcune delle caratteristiche di funzionamento (ad esempio passare da sola
-lettura a lettura/scrittura). Questa operazione è attivata attraverso uno dei
-bit di \param{mountflags}, \const{MS\_REMOUNT}, che se impostato specifica che
-deve essere effettuato il rimontaggio del filesystem (con le opzioni
-specificate dagli altri bit), anche in questo caso il valore di \param{source}
-viene ignorato.
-
-Una volta che non si voglia più utilizzare un certo filesystem è possibile
-\textsl{smontarlo} usando la funzione \funcd{umount}, il cui prototipo è:
-\begin{prototype}{sys/mount.h}{umount(const char *target)}
-
- Smonta il filesystem montato sulla directory \param{target}.
-
- \bodydesc{La funzione ritorna 0 in caso di successo e -1 in caso di
- fallimento, nel qual caso \var{errno} assumerà uno dei valori:
- \begin{errlist}
- \item[\errcode{EPERM}] il processo non ha i privilegi di amministratore.
- \item[\errcode{EBUSY}] \param{target} è la directory di lavoro di qualche
- processo, o contiene dei file aperti, o un altro mount point.
- \end{errlist}
- ed inoltre \errval{ENOTDIR}, \errval{EFAULT}, \errval{ENOMEM},
- \errval{ENAMETOOLONG}, \errval{ENOENT} o \errval{ELOOP}.}
-\end{prototype}
-\noindent la funzione prende il nome della directory su cui il filesystem è
-montato e non il file o il dispositivo che è stato montato,\footnote{questo è
- vero a partire dal kernel 2.3.99-pre7, prima esistevano due chiamate
- separate e la funzione poteva essere usata anche specificando il file di
- dispositivo.} in quanto con il kernel 2.4.x è possibile montare lo stesso
-dispositivo in più punti. Nel caso più di un filesystem sia stato montato
-sullo stesso \textit{mount point} viene smontato quello che è stato montato
-per ultimo.
-
-Si tenga presente che la funzione fallisce quando il filesystem è
-\textsl{occupato}, questo avviene quando ci sono ancora file aperti sul
-filesystem, se questo contiene la directory di lavoro corrente di un qualunque
-processo o il mount point di un altro filesystem; in questo caso l'errore
-restituito è \errcode{EBUSY}.
-
-Linux provvede inoltre una seconda funzione, \funcd{umount2}, che in alcuni
-casi permette di forzare lo smontaggio di un filesystem, anche quando questo
-risulti occupato; il suo prototipo è:
-\begin{prototype}{sys/mount.h}{umount2(const char *target, int flags)}
-
- La funzione è identica a \func{umount} per comportamento e codici di errore,
- ma con \param{flags} si può specificare se forzare lo smontaggio.
-\end{prototype}
-
-Il valore di \param{flags} è una maschera binaria, e al momento l'unico valore
-definito è il bit \const{MNT\_FORCE}; gli altri bit devono essere nulli.
-Specificando \const{MNT\_FORCE} la funzione cercherà di liberare il filesystem
-anche se è occupato per via di una delle condizioni descritte in precedenza. A
-seconda del tipo di filesystem alcune (o tutte) possono essere superate,
-evitando l'errore di \errcode{EBUSY}. In tutti i casi prima dello smontaggio
-viene eseguita una sincronizzazione dei dati.
-
-% TODO documentare MNT_DETACH e MNT_EXPIRE ...
-
-Altre due funzioni specifiche di Linux,\footnote{esse si trovano anche su BSD,
- ma con una struttura diversa.} utili per ottenere in maniera diretta
-informazioni riguardo al filesystem su cui si trova un certo file, sono
-\funcd{statfs} e \funcd{fstatfs}, i cui prototipi sono:
-\begin{functions}
- \headdecl{sys/vfs.h}
- \funcdecl{int statfs(const char *path, struct statfs *buf)}
-
- \funcdecl{int fstatfs(int fd, struct statfs *buf)}
-
- Restituisce in \param{buf} le informazioni relative al filesystem su cui è
- posto il file specificato.
-
- \bodydesc{Le funzioni ritornano 0 in caso di successo e -1 in caso di
- errore, nel qual caso \var{errno} assumerà uno dei valori:
- \begin{errlist}
- \item[\errcode{ENOSYS}] il filesystem su cui si trova il file specificato non
- supporta la funzione.
- \end{errlist}
- e \errval{EFAULT} ed \errval{EIO} per entrambe, \errval{EBADF} per
- \func{fstatfs}, \errval{ENOTDIR}, \errval{ENAMETOOLONG}, \errval{ENOENT},
- \errval{EACCES}, \errval{ELOOP} per \func{statfs}.}
-\end{functions}
-
-Queste funzioni permettono di ottenere una serie di informazioni generali
-riguardo al filesystem su cui si trova il file specificato; queste vengono
-restituite all'indirizzo \param{buf} di una struttura \struct{statfs} definita
-come in fig.~\ref{fig:sys_statfs}, ed i campi che sono indefiniti per il
-filesystem in esame sono impostati a zero. I valori del campo \var{f\_type}
-sono definiti per i vari filesystem nei relativi file di header dei sorgenti
-del kernel da costanti del tipo \var{XXX\_SUPER\_MAGIC}, dove \var{XXX} in
-genere è il nome del filesystem stesso.
-
-\begin{figure}[!htb]
- \footnotesize \centering
- \begin{minipage}[c]{\textwidth}
- \includestruct{listati/statfs.h}
- \end{minipage}
- \normalsize
- \caption{La struttura \structd{statfs}.}
- \label{fig:sys_statfs}
-\end{figure}
-
-
-Le \acr{glibc} provvedono infine una serie di funzioni per la gestione dei due
-file \conffile{/etc/fstab} ed \conffile{/etc/mtab}, che convenzionalmente sono
-usati in quasi tutti i sistemi unix-like per mantenere rispettivamente le
-informazioni riguardo ai filesystem da montare e a quelli correntemente
-montati. Le funzioni servono a leggere il contenuto di questi file in
-opportune strutture \struct{fstab} e \struct{mntent}, e, per
-\conffile{/etc/mtab} per inserire e rimuovere le voci presenti nel file.
-
-In generale si dovrebbero usare queste funzioni (in particolare quelle
-relative a \conffile{/etc/mtab}), quando si debba scrivere un programma che
-effettua il montaggio di un filesystem; in realtà in questi casi è molto più
-semplice invocare direttamente il programma \cmd{mount}, per cui ne
-tralasceremo la trattazione, rimandando al manuale delle \acr{glibc}
-\cite{glibc} per la documentazione completa.
-
-% TODO scrivere relativamente alle varie funzioni (getfsent e getmntent &C)
-% TODO documentare swapon e swapoff (man 2 ...)
-
-
% TODO documentare keyctl ????
% (fare sezione dedicata ????)
%\subsection{La gestione delle chiavi crittografiche}
\texttt{AcctCtrl.c} dei sorgenti allegati alla guida.
Quando si attiva la contabilità, il file che si indica deve esistere; esso
-verrà aperto in sola scrittura;\footnote{si applicano al pathname indicato da
- \param{filename} tutte le restrizioni viste in cap.~\ref{cha:file_intro}.}
-le informazioni verranno registrate in \itindex{append~mode} \textit{append}
-in coda al file tutte le volte che un processo termina. Le informazioni
-vengono salvate in formato binario, e corrispondono al contenuto della
-apposita struttura dati definita all'interno del kernel.
+verrà aperto in sola scrittura; le informazioni verranno registrate in
+\itindex{append~mode} \textit{append} in coda al file tutte le volte che un
+processo termina. Le informazioni vengono salvate in formato binario, e
+corrispondono al contenuto della apposita struttura dati definita all'interno
+del kernel.
Il funzionamento di \func{acct} viene inoltre modificato da uno specifico
parametro di sistema, modificabile attraverso \procfile{/proc/sys/kernel/acct}