Messe fsync, sync.
authorSimone Piccardi <piccardi@gnulinux.it>
Tue, 27 Nov 2001 00:20:20 +0000 (00:20 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Tue, 27 Nov 2001 00:20:20 +0000 (00:20 +0000)
filestd.tex
fileunix.tex

index 0ea99952c1e5c8d92b012badc22243e5463123ce..e5ea8fdd48b7baf8618a18fc9f4c91fa75dfdd45 100644 (file)
@@ -126,19 +126,19 @@ riguarda l'aspetto della scrittura dei dati sul file.
 
 I caratteri che vengono scritti su uno stream normalmente vengono accumulati
 in un buffer e poi trasmessi in blocco in maniera asincrona rispetto alla
-scrittura (quello che viene chiamato il \textit{flush} dei dati) tutte le
-volte che il buffer viene riempito. Un comportamento analogo avviene anche in
-lettura (cioè dal file viene letto un blocco di dati, anche se se ne sono
-richiesti una quantità inferiore), ma la cosa ovviamente ha rilevanza
-inferiore, dato che i dati letti sono sempre gli stessi; in caso di scrittura
-invece, quando si ha un accesso contemporaneo allo stesso file (ad esempio da
-parte di un altro processo) si potranno vedere solo le parti effettivamente
-scritte, e non quelle ancora presenti nel buffer. 
+scrittura (quello che viene chiamato lo \textsl{scarico}, dall'ingelese 
+\textit{flush}, dei dati) tutte le volte che il buffer viene riempito. Un
+comportamento analogo avviene anche in lettura (cioè dal file viene letto un
+blocco di dati, anche se se ne sono richiesti una quantità inferiore), ma la
+cosa ovviamente ha rilevanza inferiore, dato che i dati letti sono sempre gli
+stessi; in caso di scrittura invece, quando si ha un accesso contemporaneo
+allo stesso file (ad esempio da parte di un altro processo) si potranno vedere
+solo le parti effettivamente scritte, e non quelle ancora presenti nel buffer.
 
 Allo stesso modo, se si sta facendo dell'input/output interattivo bisognerà
-tenere presente le caratteristiche delle operazioni di \textit{flush} dei
-dati, poiché non è detto che ad una scrittura sullo stream corrisponda una
-immediata scrittura sul dispositivo.
+tenere presente le caratteristiche delle operazioni di scarico dei dati,
+poiché non è detto che ad una scrittura sullo stream corrisponda una immediata
+scrittura sul dispositivo.
 
 Per rispondere ad esigenze diverse, lo standard definisce tre distinte modalità
 in cui può essere eseguita la bufferizzazione, delle quali occorre essere ben
@@ -177,18 +177,18 @@ chiarimenti e attenzioni per quel che concerne il suo funzionamento. Come gi
 accennato nella descrizione, \emph{di norma} i dati vengono inviati al kernel
 alla ricezione di un carattere di a capo; questo non è vero in tutti i casi,
 infatti, dato che le dimensioni del buffer usato dalle librerie sono fisse, se
-le si eccedono si può avere un \textit{flush} dei dati anche prima che sia
-stato inviato un carattere di \textit{newline}.
+le si eccedono si può avere uno scarico dei dati anche prima che sia stato
+inviato un carattere di \textit{newline}.
 
 Un secondo punto da tenere presente, particolarmente quando si ha a che fare
 con I/O interattivo, è che quando si effettua una lettura su uno stream che
 comporta l'accesso al kernel\footnote{questo vuol dire sempre se lo stream da
-  cui si legge è in modalità \textit{unbuffered}} viene anche eseguito il
-\textit{flush} di tutti i buffer degli stream in scrittura. 
+  cui si legge è in modalità \textit{unbuffered}} viene anche eseguito lo
+scarico di tutti i buffer degli stream in scrittura.
 
 In \secref{sec:file_buffering_ctrl} vedremo come la libreria definisca delle
-opportune funzioni per controllare le modalità di bufferizzazione ed il
-\textit{flush} dei dati.
+opportune funzioni per controllare le modalità di bufferizzazione e lo scarico
+dei dati.
 
 
 
@@ -308,6 +308,10 @@ usare una delle funzioni \func{fseek}, \func{fsetpos} o \func{rewind}. Anche
 una operazione nominalmente nulla come \func{fseek(file, 0, SEEK\_CUR)} è
 sufficiente a garantire la sincronizzazione.
 
+Una volta aperto lo stream, si può cambiare la modalità di bufferizzazione
+fintanto che non si è effettuat
+
+
 Uno stream viene chiuso con la funzione \func{fclose} il cui prototipo è:
 \begin{prototype}{stdio.h}{int fclose(FILE * stream)}
   Chiude lo stream \param{stream}. 
@@ -318,6 +322,11 @@ Uno stream viene chiuso con la funzione \func{fclose} il cui prototipo 
   funzione che è fallita (\func{close}, \func{write} o \func{fflush}).
 \end{prototype}
 
+La funzione effettua uno scarico di tutti i dati presenti nei buffer di uscita
+e scarta tutti i dati in ingresso, se era stato allocato un buffer per lo
+stream questo verrà rilasciato. La funzione effettua lo scarico solo per i
+dati presenti nei buffer in user space usati dalle \acr{glibc}; se si essere
+sicuri che il kernel forzi la scrittura su disco occorrà effettuare . 
 
 
 \subsection{Lettura e scrittura su uno stream}
@@ -363,11 +372,3 @@ stream; se non si 
 \subsection{Efficienza}
 \label{sec:file_stream_efficiency}
 
-
-
-
-
-
-
-
-
index b9d72195ec213c26ea4f5ca78bc3e4151e1b4f0d..ebba51b2a918c0ece94593ea2cba298eba4f67d6 100644 (file)
@@ -353,7 +353,9 @@ secondo le tre modalit
 ciascuno di questi bit, dette costanti possono essere combinate fra di loro
 con un OR aritmetico per costruire il valore (in forma di maschera binaria)
 del parametro \var{flags} da passare alla \func{open} per specificarne il
-comportamento.
+comportamento. I due flag \macro{O\_NOFOLLOW} e \macro{O\_DIRECTORY} sono
+estensioni specifiche di Linux, e deve essere usata definita la macro
+\macro{\_GNU\_SOURCE} per poterli usare.
 
 Nelle prime versioni di unix i flag specificabili per \func{open} erano solo
 quelli relativi alle modalità di accesso del file.  Per questo motivo per
@@ -392,7 +394,7 @@ aperto, tutte le risorse nella file table vengono rilasciate. Infine se il
 file descriptor era l'ultimo riferimento ad un file su disco quest'ultimo
 viene cancellato.
 
-Si ricordi che quando un processo termina anche tutti i sui file descriptor
+Si ricordi che quando un processo termina anche tutti i suoi file descriptor
 vengono chiusi, molti programmi sfruttano questa caratteristica e non usano
 esplicitamente \func{close}. In genere comunque chiudere un file senza
 controllarne lo stato di uscita è errore; infatti molti filesystem
@@ -406,9 +408,10 @@ quote su disco.
 In ogni caso una \func{close} andata a buon fine non garantisce che i dati
 siano stati effettivamente scritti su disco, perché il kernel può decidere di
 ottimizzare l'accesso a disco ritardandone la scrittura. L'uso della funzione
-\func{sync} effettua esplicitamente il \emph{flush} dei dati, ma anche in
-questo caso resta l'incertezza dovuta al comportamento dell'hardware (che a
-sua volta può introdurre ottimizzazioni dell'accesso al disco).
+\func{sync} (vedi \secref{sec:file_sync}) effettua esplicitamente il
+\emph{flush} dei dati, ma anche in questo caso resta l'incertezza dovuta al
+comportamento dell'hardware (che a sua volta può introdurre ottimizzazioni
+dell'accesso al disco).
 
 
 \subsection{La funzione \func{lseek}}
@@ -771,6 +774,71 @@ assenza, diventa atomica essendo svolta tutta all'interno di una singola
 \func{open}.
 
 
+\subsection{La funzioni \func{sync} e \func{fsync}}
+\label{sec:file_sync}
+
+Come accennato in \secref{sec:file_close} tutte le operazioni di scrittura
+sono in genere bufferizzate dal kernel, che provvede ad effettuarle in maniera
+asincrona (ad esempio accorpando gli accessi alla stessa zona del disco) in un
+secondo tempo rispetto al momento della esecuzione della \func{write}.
+
+Per questo motivo, quando è necessaria una sincronizzazione dei dati, il
+sistema mette a disposizione delle funzioni che provvedono a forzare lo
+scarico dei dati dai buffer del kernel\footnote{come già accennato neanche
+  questo da la garanzia assoluta che i dati siano integri dopo la chiamata,
+  l'hardware dei dischi è in genere dotato di un suo meccanismo interno che
+  può ritardare ulteriormente la scrittura effettiva.}. La prima di queste
+funzioni è \func{sync} il cui prototipo è:
+\begin{prototype}{unistd.h}{int sync(void)}
+  
+  La funzione sincronizza buffer della cache dei file col disco.
+  
+  La funzione ritorna sempre zero.
+\end{prototype}
+\noindent  i vari standard prevedono che la funzione si limiti a far partire
+le operazioni, ritornando immediatamente; in Linux (dal kernel 1.3.20) invece
+la funzione aspetta la conclusione delle operazioni di sincronizzazione del
+kernel.
+
+La funzione viene usata dal comando \cmd{sync} quando si vuole forzare
+esplicitamente lo scarico dei dati su disco, o dal demone di sistema
+\cmd{update} che esegue lo scarico dei dati ad intervalli di tempo fissi: il
+valore tradizionale per l'update dei dati è ogni 30 secondi, ma in Linux era
+di 5 secondi; con le nuove versioni poi, è il kernel che si occupa
+direttamente di tutto quanto.
+
+Quando si vogliono scaricare soltanto i dati di un file (ad esempio essere
+sicuri che i dati di un database sono stati registrati su disco) si possono
+usare le due funzioni \func{fsync} e \func{fdatasync}, i cui prototipi sono:
+\begin{functions}
+  \headdecl{unistd.h}
+  \funcdecl{int fsync(int fd)}
+  Sincronizza dati e metadati del file \param{fd}
+  \funcdecl{int fdatasync(int fd)}
+  Sincronizza i dati del file \param{fd}.
+  
+  La funzione ritorna 0 in caso di successo e -1 in caso di errore, nel qual
+  caso i codici restituiti in \var{errno} sono:
+  \begin{errlist}
+  \item \macro{EINVAL} \param{fd} è un file speciale che non supporta la
+    sincronizzazione.
+  \end{errlist}
+  ed inoltre \macro{EBADF}, \macro{EROFS} e \macro{EIO}.
+\end{functions}
+
+Entrambe le funzioni forzano la sincronizzazione col disco di tutti i dati del
+file specificato, ed attendono fino alla conclusione delle operazioni;
+\func{fsync} forza anche la sincronizzazione dei metadata dell'inode (i dati
+di \var{fstat} come i tempi del file). 
+
+
+Si tenga presente che questo non comporta la sincronizzazione della directory
+che contiene il file (e scrittura della relativa voce su disco) che deve
+essere effettuata esplicitamente\footnote{in realtà con il filesystem
+  \acr{ext2}, quando questo viene montato con l'opzione \cmd{sync}, il kernel
+  provvede anche alla sincronizzazione automatica delle voci delle
+  directory.}.
+
 
 \subsection{La funzioni \func{dup} e \func{dup2}}
 \label{sec:file_dup}
@@ -940,7 +1008,15 @@ La maggior parte delle funzionalit
 poter essere affrontate in dettaglio a questo punto; saranno riprese più
 avanti quando affronteremo le problematiche ad esse relative.
 
-Per determinare le modalità di accesso inoltre può essere necessario usare la 
+Per determinare le modalità di accesso inoltre è necessario estrarre i bit di
+accesso (ottenuti con il comando \macro{F\_GETFL}); infatti la definizione
+corrente non assegna bit separati a \macro{O\_RDONLY}, \macro{O\_WRONLY} e
+\macro{O\_RDWR}\footnote{posti rispettivamente ai valori 0, 1 e 2}, per cui il
+valore si ottiene eseguendo un AND binario del valore di ritorno di
+\func{fcntl} con la maschera \macro{O\_ACCMODE} anch'essa definita in
+\file{fcntl.h}.
+
+
 
 \subsection{La funzione \func{ioctl}}
 \label{sec:file_ioctl}