X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=fileadv.tex;h=9d2626adfa8e663fb3b08b185ef3954eeab92622;hp=b35d14c1e4a5be77613082b59797b32fe8793ee4;hb=8e2e77dff8f3cffb28ddf982280dff6fc015eb19;hpb=ffb12837c5ed8ccc095bc9c88349cd19b5e6b472 diff --git a/fileadv.tex b/fileadv.tex index b35d14c..9d2626a 100644 --- a/fileadv.tex +++ b/fileadv.tex @@ -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 @@ -244,14 +244,14 @@ possono avere due processi diversi che aprono lo stesso file. La richiesta di un \textit{file lock} prevede una scansione della lista per determinare se l'acquisizione è possibile, ed in caso positivo l'aggiunta di -un nuovo elemento.\footnote{cioè una nuova struttura \struct{file\_lock}.} +un nuovo elemento.\footnote{cioè una nuova struttura \kstruct{file\_lock}.} Nel caso dei blocchi creati con \func{flock} la semantica della funzione prevede che sia \func{dup} che \func{fork} non creino ulteriori istanze di un \textit{file lock} quanto piuttosto degli ulteriori riferimenti allo stesso. Questo viene realizzato dal kernel secondo lo schema di fig.~\ref{fig:file_flock_struct}, associando ad ogni nuovo \textit{file lock} un puntatore\footnote{il puntatore è mantenuto nel campo \var{fl\_file} di - \struct{file\_lock}, e viene utilizzato solo per i \textit{file lock} creati + \kstruct{file\_lock}, e viene utilizzato solo per i \textit{file lock} creati con la semantica BSD.} alla voce nella \itindex{file~table} \textit{file table} da cui si è richiesto il blocco, che così ne identifica il titolare. @@ -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 @@ -460,7 +461,7 @@ sez.~\ref{sec:file_flock}) esaminiamo più in dettaglio come viene gestito dal kernel. Lo schema delle strutture utilizzate è riportato in fig.~\ref{fig:file_posix_lock}; come si vede esso è molto simile all'analogo di fig.~\ref{fig:file_flock_struct}:\footnote{in questo caso nella figura si - sono evidenziati solo i campi di \struct{file\_lock} significativi per la + sono evidenziati solo i campi di \kstruct{file\_lock} significativi per la semantica POSIX, in particolare adesso ciascuna struttura contiene, oltre al \ids{PID} del processo in \var{fl\_pid}, la sezione di file che viene bloccata grazie ai campi \var{fl\_start} e \var{fl\_end}. La struttura è @@ -481,7 +482,7 @@ voce nella \itindex{file~table} \textit{file table}, ma con il valore del Quando si richiede un \textit{file lock} il kernel effettua una scansione di tutti i blocchi presenti sul file\footnote{scandisce cioè la \itindex{linked~list} \textit{linked list} delle strutture - \struct{file\_lock}, scartando automaticamente quelle per cui + \kstruct{file\_lock}, scartando automaticamente quelle per cui \var{fl\_flags} non è \const{FL\_POSIX}, così che le due interfacce restano ben separate.} per verificare se la regione richiesta non si sovrappone ad una già bloccata, in caso affermativo decide in base al tipo di blocco, in @@ -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 è @@ -1714,12 +1715,14 @@ l'insieme dei file descriptor da tenere sotto controllo tramite un certo chiamate devono essere ripetute per ciascun file descriptor, incorrendo in una perdita di prestazioni qualora il numero di file descriptor sia molto grande; per questo è stato proposto di introdurre come estensione una - funzione \func{epoll\_ctlv} che consenta di effettuare con una sola chiamata + funzione \code{epoll\_ctlv} che consenta di effettuare con una sola chiamata le impostazioni per un blocco di file descriptor.} L'uso di \const{EPOLL\_CTL\_MOD} consente in seguito di modificare le modalità di osservazione di un file descriptor che sia già stato aggiunto alla lista di osservazione. +% TODO verificare se prima o poi epoll_ctlv verrà introdotta + Le impostazioni di default prevedono che la notifica degli eventi richiesti sia effettuata in modalità \textit{level triggered}, a meno che sul file descriptor non si sia impostata la modalità \textit{edge triggered}, @@ -1933,7 +1936,7 @@ descriptor è \funcd{signalfd},\footnote{in realtà quella riportata è versioni diverse della \textit{system call}; una prima versione, \func{signalfd}, introdotta nel kernel 2.6.22 e disponibile con le \acr{glibc} 2.8 che non supporta l'argomento \texttt{flags}, ed una seconda - versione, \func{signalfd4}, introdotta con il kernel 2.6.27 e che è quella + versione, \funcm{signalfd4}, introdotta con il kernel 2.6.27 e che è quella che viene sempre usata a partire dalle \acr{glibc} 2.9, che prende un argomento aggiuntivo \code{size\_t sizemask} che indica la dimensione della maschera dei segnali, il cui valore viene impostato automaticamente dalle @@ -2205,7 +2208,7 @@ ritorno della funzione \func{read} è negativo, uscendo dal programma In presenza di dati invece il programma proseguirà l'esecuzione stampando (\texttt{\small 19--20}) il nome del segnale ottenuto all'interno della -struttura \const{signalfd\_siginfo} letta in \var{siginf}\footnote{per la +struttura \struct{signalfd\_siginfo} letta in \var{siginf}\footnote{per la stampa si è usato il vettore \var{sig\_names} a ciascun elemento del quale corrisponde il nome del segnale avente il numero corrispondente, la cui definizione si è omessa dal codice di fig.~\ref{fig:fiforeporter_code_init} @@ -2456,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 @@ -2472,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 @@ -2496,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 @@ -2610,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} @@ -2639,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 @@ -2871,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 @@ -3103,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. @@ -3167,15 +3170,15 @@ così all'applicazione di collegare la corrispondente coppia di eventi Infine due campi \var{name} e \var{len} sono utilizzati soltanto quando l'evento è relativo ad un file presente in una directory posta sotto osservazione, in tal caso essi contengono rispettivamente il nome del file -(come pathname relativo alla directory osservata) e la relativa dimensione in -byte. Il campo \var{name} viene sempre restituito come stringa terminata da -NUL, con uno o più zeri di terminazione, a seconda di eventuali necessità di -allineamento del risultato, ed il valore di \var{len} corrisponde al totale -della dimensione di \var{name}, zeri aggiuntivi compresi. La stringa con il -nome del file viene restituita nella lettura subito dopo la struttura -\struct{inotify\_event}; questo significa che le dimensioni di ciascun evento -di \textit{inotify} saranno pari a \code{sizeof(\struct{inotify\_event}) + - len}. +(come \itindsub{pathname}{relativo} \textit{pathname} relativo alla directory +osservata) e la relativa dimensione in byte. Il campo \var{name} viene sempre +restituito come stringa terminata da NUL, con uno o più zeri di terminazione, +a seconda di eventuali necessità di allineamento del risultato, ed il valore +di \var{len} corrisponde al totale della dimensione di \var{name}, zeri +aggiuntivi compresi. La stringa con il nome del file viene restituita nella +lettura subito dopo la struttura \struct{inotify\_event}; questo significa che +le dimensioni di ciascun evento di \textit{inotify} saranno pari a +\code{sizeof(\struct{inotify\_event}) + len}. Vediamo allora un esempio dell'uso dell'interfaccia di \textit{inotify} con un semplice programma che permette di mettere sotto osservazione uno o più file e @@ -3312,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 @@ -3423,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 @@ -3651,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} @@ -3661,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 @@ -3973,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 @@ -4491,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 @@ -4504,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. @@ -4514,7 +4521,7 @@ maniera atomica a partire da un certa posizione sul file. Per questo motivo a partire dal kernel 2.6.30 sono state introdotte anche per l'\textsl{I/O vettorizzato} le analoghe delle funzioni \func{pread} e \func{pwrite} (vedi sez.~\ref{sec:file_read} e \ref{sec:file_write}); le due funzioni sono -\funcd{preadv} e \func{pwritev} ed i rispettivi prototipi sono:\footnote{le +\funcd{preadv} e \funcd{pwritev} ed i rispettivi prototipi sono:\footnote{le due funzioni sono analoghe alle omonime presenti in BSD; le \textit{system call} usate da Linux (introdotte a partire dalla versione 2.6.30) utilizzano degli argomenti diversi per problemi collegati al formato a 64 @@ -4737,7 +4744,7 @@ definito la macro \macro{\_GNU\_SOURCE},\footnote{si ricordi che questa \func{splice}, oppure nessuno dei file descriptor è una pipe, oppure si è dato un valore a \param{off\_in} o \param{off\_out} ma il corrispondente file è un dispositivo che non supporta la funzione - \func{seek}. + \func{lseek}. \item[\errcode{ENOMEM}] non c'è memoria sufficiente per l'operazione richiesta. \item[\errcode{ESPIPE}] o \param{off\_in} o \param{off\_out} non sono @@ -5026,7 +5033,7 @@ La funzione copia \param{len} byte del contenuto di una \textit{pipe} su di un'altra; \param{fd\_in} deve essere il capo in lettura della \textit{pipe} sorgente e \param{fd\_out} il capo in scrittura della \textit{pipe} destinazione; a differenza di quanto avviene con \func{read} i dati letti con -\func{tee} da \func{fd\_in} non vengono \textsl{consumati} e restano +\func{tee} da \param{fd\_in} non vengono \textsl{consumati} e restano disponibili sulla \textit{pipe} per una successiva lettura (di nuovo per il comportamento delle \textit{pipe} si veda sez.~\ref{sec:ipc_unix}). Al momento\footnote{quello della stesura di questo paragrafo, avvenuta il Gennaio @@ -5405,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/