From 5d0b6835069ab7fe7190de89969834fece6f79bf Mon Sep 17 00:00:00 2001 From: Simone Piccardi Date: Tue, 31 Jan 2012 20:20:56 +0000 Subject: [PATCH] Modifiche per open --- fileio.tex | 287 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 177 insertions(+), 110 deletions(-) diff --git a/fileio.tex b/fileio.tex index 9dfa301..be7fa76 100644 --- a/fileio.tex +++ b/fileio.tex @@ -92,7 +92,8 @@ a ciascuna di queste strutture, che, come illustrato in fig.~\ref{fig:kstruct_file}, contengono le informazioni necessarie per la gestione dei file, ed in particolare: \begin{itemize*} -\item lo stato del file nel campo \var{f\_flags}. +\item il flag di stato \itindex{file~status~flag} del file nel campo + \var{f\_flags}. \item la posizione corrente nel file, il cosiddetto \textit{offset}, nel campo \var{f\_pos}. \item un puntatore alla struttura \kstruct{inode} che identifica @@ -284,8 +285,8 @@ sez.~\ref{sec:file_perm_management}) del processo. La funzione restituisce sempre il primo file descriptor libero, e questa caratteristica permette di prevedere qual è il valore del file descriptor che -si otterrà al ritorno di \func{open}, e viene talvolta usata da alcune -applicazioni per sostituire i file corrispondenti ai file standard visti in +si otterrà al ritorno di \func{open}, e viene spesso usata dalle applicazioni +per sostituire i file corrispondenti ai file standard visti in tab.~\ref{tab:file_std_files}. Se ad esempio si chiude lo \itindex{standard~input} \textit{standard input} e si apre subito dopo un nuovo file questo diventerà il nuovo \itindex{standard~input} \textit{standard @@ -304,93 +305,157 @@ esso direttamente tramite il file descriptor, e quanto avviene al Il comportamento della funzione e le diverse modalità con cui può essere aperto il file vengono controllati dall'argomento \param{flags} il cui valore deve essere indicato come maschera binaria in cui ciascun bit ha un -significato specifico. Alcuni di questi bit vanno anche a costituire il -cosiddetto flag di stato del file (o \textit{file status flag}), che è il -valore mantenuto nel campo \var{f\_flags} della struttura \kstruct{file} che -abbiamo riportato anche in fig.~\ref{fig:file_proc_file}). +significato specifico. Alcuni di questi bit vanno anche a costituire i +cosiddetti \textsl{flag di stato} del file (o \itindex{file~status~flag} +\textit{file status flags}), che vengono mantenuti nel campo \var{f\_flags} +della struttura \kstruct{file} che abbiamo riportato anche in +fig.~\ref{fig:file_proc_file}). -Ciascun bit viene identificato da una apposita costante, ed il valore +Ciascun flag viene identificato da una apposita costante, ed il valore di \param{flags} deve essere specificato come OR aritmetico di queste costanti. I vari bit che si possono usare come componenti di \param{flags} -sono divisi in tre categorie principali. La prima categoria è quella dei -cosiddetti \textsl{i bit delle modalità di accesso}, che specificano con quale -modalità si accederà al file: i valori possibili sono lettura, scrittura o -lettura/scrittura. Uno di questi bit deve essere sempre specificato quando si -apre un file. Vengono impostati alla chiamata da \func{open}, e possono -essere riletti con \func{fcntl} (fanno parte del \textit{file status flag}), -ma non possono essere modificati, le costanti che li identificano sono le -seguenti: +sono divisi in tre gruppi principali. Il primo gruppo è quello dei cosiddetti +flag delle \textsl{modalità di accesso} (o \textit{access mode flags}), che +specificano che tipo di accesso si effettuerà sul file, fra lettura, scrittura +e lettura/scrittura. Questa modalità deve essere indicata usando una delle +costanti di tab.~\ref{tab:open_access_mode_flag}. -\begin{basedescript}{\desclabelwidth{2.cm}\desclabelstyle{\nextlinelabel}} - \item[\const{O\_RDONLY}] Apre il file in sola lettura, le \acr{glibc} - definiscono anche \const{O\_READ} come sinonimo. - \item[\const{O\_WRONLY}] Apre il file in sola scrittura, le \acr{glibc} - definiscono anche \const{O\_WRITE} come sinonimo. - \item[\const{O\_RDWR}] Apre il file sia in lettura che in scrittura. -\end{basedescript} +\begin{table}[htb] + \centering + \footnotesize + \begin{tabular}[c]{|l|l|} + \hline + \textbf{Flag} & \textbf{Significato} \\ + \hline + \hline + \const{O\_RDONLY} & Apre il file in sola lettura.\\ + \const{O\_WRONLY} & Apre il file in sola scrittura.\\ + \const{O\_RDWR} & Apre il file sia in lettura che in scrittura.\\ + \hline + \end{tabular} + \caption{Le tre costanti che identificano le modalità di accesso + nell'apertura di un file.} + \label{tab:open_access_mode_flag} +\end{table} -La seconda categoria è quella dei \textsl{ bit delle modalità di operazione}, -che permettono di specificare alcune caratteristiche del comportamento delle -future operazioni sul file (come \func{read} o \func{write}). Anch'essi fan -parte del \textit{file status flag}. Il loro valore è impostato alla chiamata -di \func{open}, ma possono essere riletti e modificati (insieme alle -caratteristiche operative che controllano) con una \func{fcntl}. +A differenza di tutti gli altri flag che vedremo in seguito, in questo caso +non si ha a che fare con singoli bit separati, ma con un numero composto da +due bit, e che può essere ottenuto dal valore dei \itindex{file~status~flag} +\textit{file status flags} con un AND aritmetico con la maschera binaria +\const{O\_ACCMODE}. Questo significa ad esempio che la combinazione +\code{\const{O\_RDONLY}|\const{O\_WRONLY}} non è affatto equivalente a +\const{O\_WRONLY}, e non deve essere usata.\footnote{in realtà su Linux, dove + i valori per le tre costanti di tab.~\ref{tab:open_access_mode_flag} sono + rispettivamente $0$, $1$ e $2$, il valore $3$ viene usato con un significato + speciale ed assolutamente fuori standard, disponibile solo per i file di + dispositivo e solo per alcuni driver, in cui si richiede la verifica della + capacità di accesso in lettura e scrittura ma viene restituito in file + descriptor che non può essere letto o scritto ma solo usato con una + \func{ioctl} (vedi sez.~\ref{sec:file_ioctl}).} + +Una modalità di accesso al file deve sempre essere specificata quando si apre +un file, il valore indicato in \param{flags} viene salvato nei +\itindex{file~status~flag} \textit{file status flags}, e può essere riletto +con \func{fcntl}, ma non può essere modificato. Nella \acr{glibc} sono +definite \const{O\_READ} come sinonimo di \const{O\_RDONLY}, \const{O\_WRITE} +come sinonimo di \const{O\_WRONLY} ed una \const{O\_EXEC} che non esiste su +Linux per l'apertura per l'esecuzione.\footnote{si tratta di definizioni + completamente fuori standard, che suppongono anche l'uso di bit distinti, ed + non è il caso di utilizzarle anche quando coincidenti con quelle di Linux.} + +Il secondo gruppo di flag è quello delle \textsl{modalità di + apertura},\footnote{la pagina di manuale di \func{open} parla di + \textit{file creation flags}, ma alcuni di questi non hanno nulla a che fare + con la creazione dei file, mentre il manuale dalla \acr{glibc} parla di più + correttamente di \textit{open-time flags}, dato che si tratta di flag il cui + significato ha senso solo al momento dell'apertura del file.} che permettono +di specificare alcune delle caratteristiche del comportamento di \func{open} +quando viene eseguita. Hanno effetto solo al momento della chiamata della +funzione e non sono memorizzati \itindex{file~status~flag} \textit{file status + flags} né possono essere riletti. + +\begin{table}[htb] + \centering + \footnotesize + \begin{tabular}[c]{|l|p{8 cm}|} + \hline + \textbf{Flag} & \textbf{Significato} \\ + \hline + \hline + \const{O\_CREAT} & Se il file non esiste verrà creato, con le regole + di titolarità del file viste in + sez.~\ref{sec:file_ownership_management}. Con + questa opzione l'argomento \param{mode} deve + essere specificato.\\ + \const{O\_DIRECTORY}& Se \param{pathname} non è una directory la + chiamata fallisce (dal kernel 2.1.126). Questo + flag è specifico di Linux ed è stato introdotto + per evitare dei \itindex{Denial~of~Service~(DoS)} + \textit{DoS}\footnotemark\\ quando \func{opendir} + viene chiamata su una fifo o su un dispositivo + associato ad una unità a nastri. Non viene + utilizzato al di fuori dell'implementazione di + \func{opendir}.\\ + \const{O\_EXCL} & Se usato in congiunzione con \const{O\_CREAT} fa + richiede che il file indicato da \param{pathname} + non esista (altrimenti causa un errore di + \errcode{EEXIST}).\\ + \const{O\_LARGEFILE}& Nel caso di sistemi a 32 bit che supportano file + di grandi dimensioni consente di aprire file le + cui dimensioni non possono essere rappresentate da + numeri a 31 bit.\\ + \const{O\_NOCTTY} & Se \param{pathname} si riferisce ad un dispositivo + di terminale, questo non diventerà il terminale di + controllo, anche se il processo non ne ha ancora + uno (si veda sez.~\ref{sec:sess_ctrl_term}).\\ + \const{O\_NOFOLLOW} & Se \param{pathname} è un collegamento simbolico + la chiamata fallisce. Questa è un'estensione BSD + aggiunta in Linux dal kernel 2.1.126. Nelle + versioni precedenti i collegamenti simbolici sono + sempre seguiti, e questa opzione è ignorata.\\ + \const{O\_TRUNC} & Se usato su un file di dati aperto in scrittura, + ne tronca la lunghezza a zero; con un terminale o + una fifo viene ignorato, negli altri casi il + comportamento di \func{open} non è specificato.\\ + \hline + \end{tabular} + \caption{Le costanti che identificano le \textit{modalità di apertura} di + un file.} + \label{tab:open_time_flag} +\end{table} + +\footnotetext{acronimo di \itindex{Denial~of~Service~(DoS)} \textit{Denial of + Service}, si chiamano così attacchi miranti ad impedire un servizio + causando una qualche forma di carico eccessivo per il sistema, che resta + bloccato nelle risposte all'attacco.} -\begin{basedescript}{\desclabelwidth{2.cm}\desclabelstyle{\nextlinelabel}} - \item[\const{O\_CREAT}] Se il file non esiste verrà creato, con le regole di - titolarità del file viste in sez.~\ref{sec:file_ownership_management}. Con - questa opzione l'argomento \param{mode} deve essere specificato. - \item[\const{O\_EXCL}] Usato in congiunzione con \const{O\_CREAT} fa sì che - la precedente esistenza del file diventi un errore\footnote{la pagina di + + +\footnote{la pagina di manuale di \func{open} segnala che questa opzione è difettosa su NFS, e che i programmi che la usano per stabilire un \index{file!di lock} \textsl{file di lock} possono incorrere in una \itindex{race~condition} \textit{race condition}. Si consiglia come alternativa di usare un file con un nome univoco e la funzione \func{link} per verificarne - l'esistenza (vedi sez.~\ref{sec:ipc_file_lock}).} che fa fallire - \func{open} con \errcode{EEXIST}. + l'esistenza (vedi sez.~\ref{sec:ipc_file_lock}).} - \item[\const{O\_NOCTTY}] Se \param{pathname} si riferisce ad un dispositivo - di terminale, questo non diventerà il terminale di controllo, anche se il - processo non ne ha ancora uno (si veda sez.~\ref{sec:sess_ctrl_term}). - \item[\const{O\_SHLOCK}] Apre il file con uno shared lock (vedi +\const{O\_SHLOCK} Apre il file con uno shared lock (vedi sez.~\ref{sec:file_locking}). Specifica di BSD, assente in Linux. - \item[\const{O\_EXLOCK}] Apre il file con un lock esclusivo (vedi +\const{O\_EXLOCK} Apre il file con un lock esclusivo (vedi sez.~\ref{sec:file_locking}). Specifica di BSD, assente in Linux. - \item[\const{O\_TRUNC}] Se usato su un file di dati aperto in scrittura, ne - tronca la lunghezza a zero; con un terminale o una fifo viene ignorato, - negli altri casi il comportamento non è specificato. - - \item[\const{O\_NOFOLLOW}] Se \param{pathname} è un collegamento simbolico - la chiamata fallisce. Questa è un'estensione BSD aggiunta in Linux dal - kernel 2.1.126. Nelle versioni precedenti i collegamenti simbolici sono - sempre seguiti, e questa opzione è ignorata. - - \item[\const{O\_DIRECTORY}] Se \param{pathname} non è una directory la - chiamata fallisce. Questo flag è specifico di Linux ed è stato introdotto - con il kernel 2.1.126 per evitare dei \itindex{Denial~of~Service~(DoS)} - \textit{DoS}\footnote{acronimo di \itindex{Denial~of~Service~(DoS)} - \textit{Denial of Service}, si chiamano così attacchi miranti ad - impedire un servizio causando una qualche forma di carico eccessivo per - il sistema, che resta bloccato nelle risposte all'attacco.} quando - \func{opendir} viene chiamata su una fifo o su un dispositivo associato ad - una unità a nastri, non deve dispositivo a nastri; non deve essere - utilizzato al di fuori dell'implementazione di \func{opendir}. - - \item[\const{O\_LARGEFILE}] Nel caso di sistemi a 32 bit che supportano file - di grandi dimensioni consente di aprire file le cui dimensioni non possono - essere rappresentate da numeri a 31 bit. -\end{basedescript} -La terza categoria è quella dei \textsl{i bit delle modalità di apertura} -che permettono di specificare alcune delle caratteristiche del comportamento -di \func{open} quando viene eseguita. Hanno effetto solo al momento della -chiamata della funzione e non sono memorizzati né possono essere riletti. +Il terzo gruppo è quello dei flag delle \textsl{modalità di operazione} che +permettono di specificare alcune caratteristiche del comportamento delle +future operazioni sul file (come \func{read} o \func{write}). Anch'essi fan +parte del \textit{file status flag}. Il loro valore è impostato alla chiamata +di \func{open}, ma possono essere riletti e modificati (insieme alle +caratteristiche operative che controllano) con una \func{fcntl}. + \begin{basedescript}{\desclabelwidth{2.cm}\desclabelstyle{\nextlinelabel}} @@ -403,6 +468,37 @@ chiamata della funzione e non sono memorizzati né possono essere riletti. questo comporta la possibilità di una \itindex{race~condition} \textit{race condition}, vedi sez.~\ref{sec:file_atomic}.} + \item[\const{O\_ASYNC}] Apre il file per l'I/O in modalità asincrona (vedi + sez.~\ref{sec:file_asyncronous_io}). Quando è impostato viene generato il + segnale \signal{SIGIO} tutte le volte che sono disponibili dati in input + sul file. + + \item[\const{O\_CLOEXEC}] Attiva la modalità di \itindex{close-on-exec} + \textit{close-on-exec} (vedi sez.~\ref{sec:proc_exec}). Introdotto con il + kernel 2.6.23, per evitare una \itindex{race~condition} \textit{race + condition} che si può verificare con i \itindex{thread} \textit{thread}, + fra l'apertura del file e l'impostazione della suddetta modalità con + \func{fcntl} (vedi sez.~\ref{sec:file_fcntl}). + + \item[\const{O\_DIRECT}] Esegue l'I/O direttamente dai buffer in user space + in maniera sincrona, in modo da scavalcare i meccanismi di caching del + kernel. In genere questo peggiora le prestazioni tranne quando le + applicazioni ottimizzano il proprio caching.\footnote{l'opzione è stata + introdotta dalla SGI in IRIX, e serve sostanzialmente a permettere ad + alcuni programmi (in genere database) la gestione diretta della + bufferizzazione dell'I/O in quanto essi sono in grado di ottimizzarla al + meglio per le loro prestazioni; l'opzione è presente anche in FreeBSD, + senza limiti di allineamento dei buffer. In Linux è stata introdotta con + il kernel 2.4.10, le versioni precedenti la ignorano.} Per i kernel + della serie 2.4 si deve garantire che i buffer in user space siano + allineati alle dimensioni dei blocchi del filesystem; per il kernel 2.6 + basta che siano allineati a multipli di 512 byte. + + \item[\const{O\_NOATIME}] Blocca l'aggiornamento dei tempi di accesso dei + file (vedi sez.~\ref{sec:file_file_times}). Per molti filesystem questa + funzionalità non è disponibile per il singolo file ma come opzione + generale da specificare in fase di montaggio. + \item[\const{O\_NONBLOCK}] Il file viene aperto in modalità non bloccante per le operazioni di I/O (che tratteremo in sez.~\ref{sec:file_noblocking}): questo significa il fallimento di @@ -422,11 +518,6 @@ chiamata della funzione e non sono memorizzati né possono essere riletti. sez.~\ref{sec:file_read} il ritorno di zero da parte di \func{read} ha il significato di una \textit{end-of-file}.} - \item[\const{O\_ASYNC}] Apre il file per l'I/O in modalità asincrona (vedi - sez.~\ref{sec:file_asyncronous_io}). Quando è impostato viene generato il - segnale \signal{SIGIO} tutte le volte che sono disponibili dati in input - sul file. - \item[\const{O\_SYNC}] Apre il file per l'input/output sincrono: ogni \func{write} bloccherà fino al completamento della scrittura di tutti i dati sull'hardware sottostante. @@ -439,32 +530,7 @@ chiamata della funzione e non sono memorizzati né possono essere riletti. \item[\const{O\_RSYNC}] Variante analoga alla precedente, trattata allo stesso modo. - \item[\const{O\_NOATIME}] Blocca l'aggiornamento dei tempi di accesso dei - file (vedi sez.~\ref{sec:file_file_times}). Per molti filesystem questa - funzionalità non è disponibile per il singolo file ma come opzione - generale da specificare in fase di montaggio. - - \item[\const{O\_DIRECT}] Esegue l'I/O direttamente dai buffer in user space - in maniera sincrona, in modo da scavalcare i meccanismi di caching del - kernel. In genere questo peggiora le prestazioni tranne quando le - applicazioni ottimizzano il proprio caching.\footnote{l'opzione è stata - introdotta dalla SGI in IRIX, e serve sostanzialmente a permettere ad - alcuni programmi (in genere database) la gestione diretta della - bufferizzazione dell'I/O in quanto essi sono in grado di ottimizzarla al - meglio per le loro prestazioni; l'opzione è presente anche in FreeBSD, - senza limiti di allineamento dei buffer. In Linux è stata introdotta con - il kernel 2.4.10, le versioni precedenti la ignorano.} Per i kernel - della serie 2.4 si deve garantire che i buffer in user space siano - allineati alle dimensioni dei blocchi del filesystem; per il kernel 2.6 - basta che siano allineati a multipli di 512 byte. - - \item[\const{O\_CLOEXEC}] Attiva la modalità di \itindex{close-on-exec} - \textit{close-on-exec} (vedi sez.~\ref{sec:file_sharing} e - \ref{sec:file_fcntl}).\footnote{introdotto con il kernel 2.6.23, per - evitare una \itindex{race~condition} \textit{race condition} che si può - verificare con i \itindex{thread} \textit{thread}, fra l'apertura del - file e l'impostazione della suddetta modalità con \func{fcntl}.} - \end{basedescript} +\end{basedescript} %TODO trattare le differenze fra O_DSYNC, O_SYNC e O_RSYNC introdotte nella @@ -938,15 +1004,16 @@ sez.~\ref{sec:proc_fork}: in caso di scrittura contemporanea la posizione corrente nel file varierà per entrambi i processi (in quanto verrà modificato \var{f\_pos} che è lo stesso per entrambi). -Si noti inoltre che anche i flag di stato del file (quelli impostati -dall'argomento \param{flag} di \func{open}) essendo tenuti nella voce della -\textit{file table}\footnote{per la precisione nel campo \var{f\_flags} di - \kstruct{file}.}, vengono in questo caso condivisi. Ai file però sono -associati anche altri flag, dei quali l'unico usato al momento è -\const{FD\_CLOEXEC}, detti \textit{file descriptor flags}. Questi ultimi sono -tenuti invece in \kstruct{file\_struct}, e perciò sono specifici di ciascun -processo e non vengono modificati dalle azioni degli altri anche in caso di -condivisione della stessa voce della \textit{file table}. +Si noti inoltre che anche i \itindex{file~status~flag} flag di stato del file +(quelli impostati dall'argomento \param{flag} di \func{open}) essendo tenuti +nella voce della \textit{file table}\footnote{per la precisione nel campo + \var{f\_flags} di \kstruct{file}, vedi fig.~\ref{fig:kstruct_file}.}, +vengono in questo caso condivisi. Ai file però sono associati anche altri +flag, dei quali l'unico usato al momento è \const{FD\_CLOEXEC}, detti +\index{file~descriptor~flags} \textit{file descriptor flags}. Questi ultimi +sono tenuti invece in \kstruct{file\_struct}, e perciò sono specifici di +ciascun processo e non vengono modificati dalle azioni degli altri anche in +caso di condivisione della stessa voce della \textit{file table}. -- 2.30.2