Inizio revisione capitolo 6.
[gapil.git] / fileadv.tex
index dc31814100e1fba5967fdef867c0c60ce7245b50..9d2626adfa8e663fb3b08b185ef3954eeab92622 100644 (file)
@@ -26,12 +26,12 @@ controllo più dettagliato delle modalità di I/O.
 
 \itindbeg{file~locking}
 
-In sez.~\ref{sec:file_sharing} abbiamo preso in esame le modalità in cui un
-sistema unix-like gestisce la condivisione dei file da parte di processi
-diversi. In quell'occasione si è visto come, con l'eccezione dei file aperti
-in \itindex{append~mode} \textit{append mode}, quando più processi scrivono
-contemporaneamente sullo stesso file non è possibile determinare la sequenza
-in cui essi opereranno.
+In sez.~\ref{sec:file_shared_access} abbiamo preso in esame le modalità in cui
+un sistema unix-like gestisce l'accesso concorrente ai file da parte di
+processi diversi. In quell'occasione si è visto come, con l'eccezione dei file
+aperti in \itindex{append~mode} \textit{append mode}, quando più processi
+scrivono contemporaneamente sullo stesso file non è possibile determinare la
+sequenza in cui essi opereranno.
 
 Questo causa la possibilità di una \itindex{race~condition} \textit{race
   condition}; in generale le situazioni più comuni sono due: l'interazione fra
@@ -260,8 +260,8 @@ Questa struttura prevede che, quando si richiede la rimozione di un
 file descriptor che fa riferimento ad una voce nella \itindex{file~table}
 \textit{file table} corrispondente a quella registrata nel blocco.  Allora se
 ricordiamo quanto visto in sez.~\ref{sec:file_dup} e
-sez.~\ref{sec:file_sharing}, e cioè che i file descriptor duplicati e quelli
-ereditati in un processo figlio puntano sempre alla stessa voce nella
+sez.~\ref{sec:file_shared_access}, e cioè che i file descriptor duplicati e
+quelli ereditati in un processo figlio puntano sempre alla stessa voce nella
 \itindex{file~table} \textit{file table}, si può capire immediatamente quali
 sono le conseguenze nei confronti delle funzioni \func{dup} e \func{fork}.
 
@@ -296,8 +296,8 @@ descriptor, il \textit{file lock} non viene rilasciato.
 La seconda interfaccia per l'\textit{advisory locking} disponibile in Linux è
 quella standardizzata da POSIX, basata sulla funzione \func{fcntl}. Abbiamo
 già trattato questa funzione nelle sue molteplici possibilità di utilizzo in
-sez.~\ref{sec:file_fcntl}. Quando la si impiega per il \textit{file locking}
-essa viene usata solo secondo il seguente prototipo:
+sez.~\ref{sec:file_fcntl_ioctl}. Quando la si impiega per il \textit{file
+  locking} essa viene usata solo secondo il seguente prototipo:
 \begin{prototype}{fcntl.h}{int fcntl(int fd, int cmd, struct flock *lock)}
   
   Applica o rimuove un \textit{file lock} sul file \param{fd}.
@@ -390,8 +390,9 @@ viene usato solo in caso di lettura, quando si chiama \func{fcntl} con
 
 Oltre a quanto richiesto tramite i campi di \struct{flock}, l'operazione
 effettivamente svolta dalla funzione è stabilita dal valore dall'argomento
-\param{cmd} che, come già riportato in sez.~\ref{sec:file_fcntl}, specifica
-l'azione da compiere; i valori relativi al \textit{file locking} sono tre:
+\param{cmd} che, come già riportato in sez.~\ref{sec:file_fcntl_ioctl},
+specifica l'azione da compiere; i valori relativi al \textit{file locking}
+sono tre:
 \begin{basedescript}{\desclabelwidth{2.0cm}}
 \item[\const{F\_GETLK}] verifica se il \textit{file lock} specificato dalla
   struttura puntata da \param{lock} può essere acquisito: in caso negativo
@@ -835,7 +836,7 @@ bloccare completamente un server NFS richiedendo una lettura su un file su cui
 è attivo un blocco. Per questo motivo l'abilitazione del \textit{mandatory
   locking} è di norma disabilitata, e deve essere attivata filesystem per
 filesystem in fase di montaggio (specificando l'apposita opzione di
-\func{mount} riportata in sez.~\ref{sec:sys_file_config}), o con l'opzione
+\func{mount} riportata in sez.~\ref{sec:filesystem_mounting}), o con l'opzione
 \code{-o mand} per il comando omonimo).
 
 Si tenga presente inoltre che il \textit{mandatory locking} funziona solo
@@ -901,7 +902,7 @@ possibilità di modificare il file.
 
 Uno dei problemi che si presentano quando si deve operare contemporaneamente
 su molti file usando le funzioni illustrate in
-cap.~\ref{cha:file_unix_interface} e cap.~\ref{cha:files_std_interface} è che
+sez.~\ref{sec:file_unix_interface} e sez.~\ref{sec:files_std_interface} è che
 si può essere bloccati nelle operazioni su un file mentre un altro potrebbe
 essere disponibile. L'\textit{I/O multiplexing} nasce risposta a questo
 problema. In questa sezione forniremo una introduzione a questa problematica
@@ -934,18 +935,18 @@ nel peggiore dei casi (quando la conclusione della operazione bloccata dipende
 da quanto si otterrebbe dal file descriptor ``\textsl{disponibile}'') si
 potrebbe addirittura arrivare ad un \itindex{deadlock} \textit{deadlock}.
 
-Abbiamo già accennato in sez.~\ref{sec:file_open} che è possibile prevenire
-questo tipo di comportamento delle funzioni di I/O aprendo un file in
-\textsl{modalità non-bloccante}, attraverso l'uso del flag \const{O\_NONBLOCK}
-nella chiamata di \func{open}. In questo caso le funzioni di input/output
-eseguite sul file che si sarebbero bloccate, ritornano immediatamente,
-restituendo l'errore \errcode{EAGAIN}.  L'utilizzo di questa modalità di I/O
-permette di risolvere il problema controllando a turno i vari file descriptor,
-in un ciclo in cui si ripete l'accesso fintanto che esso non viene garantito.
-Ovviamente questa tecnica, detta \itindex{polling} \textit{polling}, è
-estremamente inefficiente: si tiene costantemente impiegata la CPU solo per
-eseguire in continuazione delle system call che nella gran parte dei casi
-falliranno.
+Abbiamo già accennato in sez.~\ref{sec:file_open_close} che è possibile
+prevenire questo tipo di comportamento delle funzioni di I/O aprendo un file
+in \textsl{modalità non-bloccante}, attraverso l'uso del flag
+\const{O\_NONBLOCK} nella chiamata di \func{open}. In questo caso le funzioni
+di input/output eseguite sul file che si sarebbero bloccate, ritornano
+immediatamente, restituendo l'errore \errcode{EAGAIN}.  L'utilizzo di questa
+modalità di I/O permette di risolvere il problema controllando a turno i vari
+file descriptor, in un ciclo in cui si ripete l'accesso fintanto che esso non
+viene garantito.  Ovviamente questa tecnica, detta \itindex{polling}
+\textit{polling}, è estremamente inefficiente: si tiene costantemente
+impiegata la CPU solo per eseguire in continuazione delle system call che
+nella gran parte dei casi falliranno.
 
 Per superare questo problema è stato introdotto il concetto di \textit{I/O
   multiplexing}, una nuova modalità di operazioni che consente di tenere sotto
@@ -1547,7 +1548,7 @@ maschera binaria in fase di creazione del file descriptor. Al momento l'unico
 valore legale per \param{flags} (a parte lo zero) è \const{EPOLL\_CLOEXEC},
 che consente di impostare in maniera atomica sul file descriptor il flag di
 \itindex{close-on-exec} \textit{close-on-exec} (si veda il significato di
-\const{O\_CLOEXEC} in tab.~\ref{tab:file_open_flags}), senza che sia
+\const{O\_CLOEXEC} in sez.~\ref{sec:file_open_close}), senza che sia
 necessaria una successiva chiamata a \func{fcntl}.
 
 Una volta ottenuto un file descriptor per \textit{epoll} il passo successivo è
@@ -2458,7 +2459,7 @@ ottenute leggendo in maniera ordinaria il file descriptor con una \func{read},
 
 
 \section{L'accesso \textsl{asincrono} ai file}
-\label{sec:file_asyncronous_access}
+\label{sec:file_asyncronous_operation}
 
 Benché l'\textit{I/O multiplexing} sia stata la prima, e sia tutt'ora una fra
 le più diffuse modalità di gestire l'I/O in situazioni complesse in cui si
@@ -2474,23 +2475,23 @@ operazioni di I/O volute.
 
 
 \subsection{Il \textit{Signal driven I/O}}
-\label{sec:file_asyncronous_operation}
+\label{sec:file_signal_driven_io}
 
 \itindbeg{signal~driven~I/O}
 
-Abbiamo accennato in sez.~\ref{sec:file_open} che è possibile, attraverso
-l'uso del flag \const{O\_ASYNC},\footnote{l'uso del flag di \const{O\_ASYNC} e
-  dei comandi \const{F\_SETOWN} e \const{F\_GETOWN} per \func{fcntl} è
-  specifico di Linux e BSD.} aprire un file in modalità asincrona, così come è
-possibile attivare in un secondo tempo questa modalità impostando questo flag
-attraverso l'uso di \func{fcntl} con il comando \const{F\_SETFL} (vedi
-sez.~\ref{sec:file_fcntl}). In realtà parlare di apertura in modalità
-asincrona non significa che le operazioni di lettura o scrittura del file
-vengono eseguite in modo asincrono (tratteremo questo, che è ciò che più
-propriamente viene chiamato \textsl{I/O asincrono}, in
+Abbiamo accennato in sez.~\ref{sec:file_open_close} che è definito un flag
+\const{O\_ASYNC}, che consentirebbe di aprire un file in modalità asincrona,
+anche se in realtà è opportuno attivare in un secondo tempo questa modalità
+impostando questo flag attraverso l'uso di \func{fcntl} con il comando
+\const{F\_SETFL} (vedi sez.~\ref{sec:file_fcntl_ioctl}).\footnote{l'uso del
+  flag di \const{O\_ASYNC} e dei comandi \const{F\_SETOWN} e \const{F\_GETOWN}
+  per \func{fcntl} è specifico di Linux e BSD.}  In realtà parlare di apertura
+in modalità asincrona non significa che le operazioni di lettura o scrittura
+del file vengono eseguite in modo asincrono (tratteremo questo, che è ciò che
+più propriamente viene chiamato \textsl{I/O asincrono}, in
 sez.~\ref{sec:file_asyncronous_io}), quanto dell'attivazione un meccanismo di
 notifica asincrona delle variazione dello stato del file descriptor aperto in
-questo modo.  
+questo modo.
 
 Quello che succede è che per tutti i file posti in questa modalità\footnote{si
   tenga presente però che essa non è utilizzabile con i file ordinari ma solo
@@ -2498,7 +2499,7 @@ Quello che succede è che per tutti i file posti in questa modalità\footnote{si
   kernel 2.6, anche per fifo e pipe.} il sistema genera un apposito segnale,
 \signal{SIGIO}, tutte le volte che diventa possibile leggere o scrivere dal
 file descriptor che si è posto in questa modalità. Inoltre è possibile, come
-illustrato in sez.~\ref{sec:file_fcntl}, selezionare con il comando
+illustrato in sez.~\ref{sec:file_fcntl_ioctl}, selezionare con il comando
 \const{F\_SETOWN} di \func{fcntl} quale processo o quale gruppo di processi
 dovrà ricevere il segnale. In questo modo diventa possibile effettuare le
 operazioni di I/O in risposta alla ricezione del segnale, e non ci sarà più la
@@ -2612,7 +2613,7 @@ standardizzate, che sono disponibili soltanto su Linux (anche se altri kernel
 supportano meccanismi simili). Alcune di esse sono realizzate, e solo a
 partire dalla versione 2.4 del kernel, attraverso l'uso di alcuni
 \textsl{comandi} aggiuntivi per la funzione \func{fcntl} (vedi
-sez.~\ref{sec:file_fcntl}), che divengono disponibili soltanto se si è
+sez.~\ref{sec:file_fcntl_ioctl}), che divengono disponibili soltanto se si è
 definita la macro \macro{\_GNU\_SOURCE} prima di includere \headfile{fcntl.h}.
 
 \itindbeg{file~lease} 
@@ -2641,13 +2642,14 @@ un altro processo esegue l'apertura del file in scrittura o usa
 il file viene aperto in lettura; in quest'ultimo caso però il \textit{lease}
 può essere ottenuto solo se nessun altro processo ha aperto lo stesso file.
 
-Come accennato in sez.~\ref{sec:file_fcntl} il comando di \func{fcntl} che
-consente di acquisire un \textit{file lease} è \const{F\_SETLEASE}, che viene
-utilizzato anche per rilasciarlo. In tal caso il file descriptor \param{fd}
-passato a \func{fcntl} servirà come riferimento per il file su cui si vuole
-operare, mentre per indicare il tipo di operazione (acquisizione o rilascio)
-occorrerà specificare come valore dell'argomento \param{arg} di \func{fcntl}
-uno dei tre valori di tab.~\ref{tab:file_lease_fctnl}.
+Come accennato in sez.~\ref{sec:file_fcntl_ioctl} il comando di \func{fcntl}
+che consente di acquisire un \textit{file lease} è \const{F\_SETLEASE}, che
+viene utilizzato anche per rilasciarlo. In tal caso il file
+descriptor \param{fd} passato a \func{fcntl} servirà come riferimento per il
+file su cui si vuole operare, mentre per indicare il tipo di operazione
+(acquisizione o rilascio) occorrerà specificare come valore
+dell'argomento \param{arg} di \func{fcntl} uno dei tre valori di
+tab.~\ref{tab:file_lease_fctnl}.
 
 \begin{table}[htb]
   \centering
@@ -2873,16 +2875,15 @@ Inoltre trattandosi di un file descriptor a tutti gli effetti, esso potrà
 essere utilizzato come argomento per le funzioni \func{select} e \func{poll} e
 con l'interfaccia di \textit{epoll};\footnote{ed a partire dal kernel 2.6.25 è
   stato introdotto anche il supporto per il \itindex{signal~driven~I/O}
-  \texttt{signal-driven I/O} trattato in
-  sez.~\ref{sec:file_asyncronous_operation}.} siccome gli eventi vengono
-notificati come dati disponibili in lettura, dette funzioni ritorneranno tutte
-le volte che si avrà un evento di notifica. Così, invece di dover utilizzare i
-segnali,\footnote{considerati una pessima scelta dal punto di vista
-  dell'interfaccia utente.} si potrà gestire l'osservazione degli eventi con
-una qualunque delle modalità di \textit{I/O multiplexing} illustrate in
-sez.~\ref{sec:file_multiplexing}. Qualora si voglia cessare l'osservazione,
-sarà sufficiente chiudere il file descriptor e tutte le risorse allocate
-saranno automaticamente rilasciate.
+  \texttt{signal-driven I/O} trattato in sez.~\ref{sec:signal_driven_io}.}
+siccome gli eventi vengono notificati come dati disponibili in lettura, dette
+funzioni ritorneranno tutte le volte che si avrà un evento di notifica. Così,
+invece di dover utilizzare i segnali,\footnote{considerati una pessima scelta
+  dal punto di vista dell'interfaccia utente.} si potrà gestire l'osservazione
+degli eventi con una qualunque delle modalità di \textit{I/O multiplexing}
+illustrate in sez.~\ref{sec:file_multiplexing}. Qualora si voglia cessare
+l'osservazione, sarà sufficiente chiudere il file descriptor e tutte le
+risorse allocate saranno automaticamente rilasciate.
 
 Infine l'interfaccia di \textit{inotify} consente di mettere sotto
 osservazione, oltre che una directory, anche singoli file.  Una volta creata
@@ -3105,11 +3106,11 @@ permette di ottenere con \func{ioctl}, come per i file descriptor associati ai
 socket (si veda sez.~\ref{sec:sock_ioctl_IP}) il numero di byte disponibili in
 lettura sul file descriptor, utilizzando su di esso l'operazione
 \const{FIONREAD}.\footnote{questa è una delle operazioni speciali per i file
-  (vedi sez.~\ref{sec:file_ioctl}), che è disponibile solo per i socket e per
-  i file descriptor creati con \func{inotify\_init}.} Si può così utilizzare
-questa operazione, oltre che per predisporre una operazione di lettura con un
-buffer di dimensioni adeguate, anche per ottenere rapidamente il numero di
-file che sono cambiati.
+  (vedi sez.~\ref{sec:file_fcntl_ioctl}), che è disponibile solo per i socket
+  e per i file descriptor creati con \func{inotify\_init}.} Si può così
+utilizzare questa operazione, oltre che per predisporre una operazione di
+lettura con un buffer di dimensioni adeguate, anche per ottenere rapidamente
+il numero di file che sono cambiati.
 
 Una volta effettuata la lettura con \func{read} a ciascun evento sarà
 associata una struttura \struct{inotify\_event} contenente i rispettivi dati.
@@ -3314,7 +3315,9 @@ raggruppati in un solo evento.
 \subsection{L'interfaccia POSIX per l'I/O asincrono}
 \label{sec:file_asyncronous_io}
 
-% vedere anche http://davmac.org/davpage/linux/async-io.html
+% vedere anche http://davmac.org/davpage/linux/async-io.html  e
+% http://www.ibm.com/developerworks/linux/library/l-async/ 
+
 
 Una modalità alternativa all'uso dell'\textit{I/O multiplexing} per gestione
 dell'I/O simultaneo su molti file è costituita dal cosiddetto \textsl{I/O
@@ -3425,8 +3428,9 @@ richiesta, o in caso di errore. Non è detto che gli errori \errcode{EBADF} ed
 potrebbero anche emergere nelle fasi successive delle operazioni. Lettura e
 scrittura avvengono alla posizione indicata da \var{aio\_offset}, a meno che
 il file non sia stato aperto in \itindex{append~mode} \textit{append mode}
-(vedi sez.~\ref{sec:file_open}), nel qual caso le scritture vengono effettuate
-comunque alla fine de file, nell'ordine delle chiamate a \func{aio\_write}.
+(vedi sez.~\ref{sec:file_open_close}), nel qual caso le scritture vengono
+effettuate comunque alla fine de file, nell'ordine delle chiamate a
+\func{aio\_write}.
 
 Si tenga inoltre presente che deallocare la memoria indirizzata da
 \param{aiocbp} o modificarne i valori prima della conclusione di una
@@ -3653,9 +3657,10 @@ per il campo \var{aio\_sigevent} di \struct{aiocb}.
 Oltre alle precedenti modalità di \textit{I/O multiplexing} e \textsl{I/O
   asincrono}, esistono altre funzioni che implementano delle modalità di
 accesso ai file più evolute rispetto alle normali funzioni di lettura e
-scrittura che abbiamo esaminato in sez.~\ref{sec:file_base_func}. In questa
-sezione allora prenderemo in esame le interfacce per l'\textsl{I/O mappato in
-  memoria}, per l'\textsl{I/O vettorizzato} e altre funzioni di I/O avanzato.
+scrittura che abbiamo esaminato in sez.~\ref{sec:file_unix_interface}. In
+questa sezione allora prenderemo in esame le interfacce per l'\textsl{I/O
+  mappato in memoria}, per l'\textsl{I/O vettorizzato} e altre funzioni di I/O
+avanzato.
 
 
 \subsection{File mappati in memoria}
@@ -3663,7 +3668,7 @@ sezione allora prenderemo in esame le interfacce per l'\textsl{I/O mappato in
 
 \itindbeg{memory~mapping}
 Una modalità alternativa di I/O, che usa una interfaccia completamente diversa
-rispetto a quella classica vista in cap.~\ref{cha:file_unix_interface}, è il
+rispetto a quella classica vista in sez.~\ref{sec:file_unix_interface}, è il
 cosiddetto \textit{memory-mapped I/O}, che, attraverso il meccanismo della
 \textsl{paginazione} \index{paginazione} usato dalla memoria virtuale (vedi
 sez.~\ref{sec:proc_mem_gen}), permette di \textsl{mappare} il contenuto di un
@@ -3975,12 +3980,12 @@ consentita la scrittura sul file (cioè per un file mappato con
 o in corrispondenza di una eventuale \func{msync}.
 
 Dato per i file mappati in memoria le operazioni di I/O sono gestite
-direttamente dalla \index{memoria~virtuale}memoria virtuale, occorre essere
+direttamente dalla \index{memoria~virtuale} memoria virtuale, occorre essere
 consapevoli delle interazioni che possono esserci con operazioni effettuate
-con l'interfaccia standard dei file di cap.~\ref{cha:file_unix_interface}. Il
-problema è che una volta che si è mappato un file, le operazioni di lettura e
-scrittura saranno eseguite sulla memoria, e riportate su disco in maniera
-autonoma dal sistema della memoria virtuale.
+con l'interfaccia dei file di sez.~\ref{sec:file_unix_interface}. Il problema
+è che una volta che si è mappato un file, le operazioni di lettura e scrittura
+saranno eseguite sulla memoria, e riportate su disco in maniera autonoma dal
+sistema della memoria virtuale.
 
 Pertanto se si modifica un file con l'interfaccia standard queste modifiche
 potranno essere visibili o meno a seconda del momento in cui la memoria
@@ -4493,7 +4498,7 @@ indicato dal valore dalla costante \const{IOV\_MAX}, definita come le altre
 costanti analoghe (vedi sez.~\ref{sec:sys_limits}) in \headfile{limits.h}; lo
 stesso valore deve essere ottenibile in esecuzione tramite la funzione
 \func{sysconf} richiedendo l'argomento \const{\_SC\_IOV\_MAX} (vedi
-sez.~\ref{sec:sys_sysconf}).
+sez.~\ref{sec:sys_limits}).
 
 Nel caso di Linux il limite di sistema è di 1024, però se si usano le
 \acr{glibc} queste forniscono un \textit{wrapper} per le system call che si
@@ -4506,7 +4511,7 @@ ma si perderà l'atomicità del trasferimento da e verso la destinazione finale.
 Si tenga presente infine che queste funzioni operano sui file con
 l'interfaccia dei file descriptor, e non è consigliabile mescolarle con
 l'interfaccia classica dei \textit{file stream} di
-cap.~\ref{cha:files_std_interface}; a causa delle bufferizzazioni interne di
+sez.~\ref{sec:files_std_interface}; a causa delle bufferizzazioni interne di
 quest'ultima infatti si potrebbero avere risultati indefiniti e non
 corrispondenti a quanto aspettato.
 
@@ -5407,10 +5412,6 @@ livello di kernel.
 % vedi http://lwn.net/Articles/226710/ e http://lwn.net/Articles/240571/
 % http://kernelnewbies.org/Linux_2_6_23
 
-
-
-
-
 % TODO non so dove trattarli, ma dal 2.6.39 ci sono i file handle, vedi
 % http://lwn.net/Articles/432757/