X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=fileunix.tex;h=ebba51b2a918c0ece94593ea2cba298eba4f67d6;hp=b9d72195ec213c26ea4f5ca78bc3e4151e1b4f0d;hb=4200529d613212e34c8cd8afd1628aedc20d74f2;hpb=8dfaa54e50227b65462713264775d4831705bc1a diff --git a/fileunix.tex b/fileunix.tex index b9d7219..ebba51b 100644 --- a/fileunix.tex +++ b/fileunix.tex @@ -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}