sistemate varie figure, finita prima stesura file locking POSIX
authorSimone Piccardi <piccardi@gnulinux.it>
Sun, 20 Oct 2002 11:00:23 +0000 (11:00 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Sun, 20 Oct 2002 11:00:23 +0000 (11:00 +0000)
fileadv.tex
fileunix.tex
img/file_flock.dia
img/filedup.dia
img/filemultacc.dia
img/fileshar.dia
img/procfile.dia

index 349d157..084f783 100644 (file)
@@ -1286,7 +1286,6 @@ gi
 \subsection{La funzione \func{flock}}
 \label{sec:file_flock}
 
-
 La prima interfaccia per il file locking, quella derivata da BSD, permette di
 eseguire un blocco solo su un intero file; la funzione usata per richiedere e
 rimuovere un \textit{file lock} è \func{flock}, ed il suo prototipo è:
@@ -1397,16 +1396,21 @@ condividono la stessa voce nella file table, e quindi, nel caso di file
 descriptor ereditati attraverso una \func{fork}, anche su processi diversi.
 
 Infine, per evitare che la terminazione imprevista di un processo lasci attivi
-dei file lock, è previsto che quando un file viene chiuso il kernel provveda
-anche a rimuovere tutti i lock ad esso associati. Anche in questo caso occorre
-tenere presente cosa succede quando si hanno file descriptor duplicati; in tal
-caso infatti il file non verrà effettivamente chiuso (ed il lock rimosso)
-fintanto che non viene rilasciata la relativa voce nella file table; la
-rimozione cioè avverrà solo quando tutti i file descriptor che fanno
-riferimento alla stessa voce sono stati chiusi, quindi, nel caso ci siano
-processi figli che mantengono ancora aperto un file descriptor, il lock non
-sarà rilasciato.
+dei file lock, quando un file viene chiuso il kernel provveda anche a
+rimuovere tutti i lock ad esso associati. Anche in questo caso occorre tenere
+presente cosa succede quando si hanno file descriptor duplicati; in tal caso
+infatti il file non verrà effettivamente chiuso (ed il lock rimosso) fintanto
+che non viene rilasciata la relativa voce nella file table; la rimozione cioè
+avverrà solo quando tutti i file descriptor che fanno riferimento alla stessa
+voce sono stati chiusi, quindi, nel caso ci siano processi figli che
+mantengono ancora aperto un file descriptor, il lock non sarà rilasciato.
 
+Si tenga presente che \func{flock} non è in grado di funzionare per i file
+mantenuti su NFS, in questo caso, se si ha la necessità di eseguire il
+\textit{file locking}, occorre usare l'interfaccia basata su \func{fcntl} che
+può funzionare anche attraverso NFS, a condizione che sia il client che il
+server supportino questa funzionalità.
 
 \subsection{Il file locking POSIX}
 \label{sec:file_posix_lock}
@@ -1414,8 +1418,8 @@ sar
 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 funzionalità in
-\secref{sec:file_fcntl}, quando la si impiega per il \textit{file locking}
-però essa viene usata secondo il prototipo:
+\secref{sec:file_fcntl}; quando la si impiega per il \textit{file locking}
+però essa viene usata solo secondo il 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}.
@@ -1440,21 +1444,13 @@ per
   }
 \end{prototype}
 
-Si tenga presente che \func{flock} non è in grado di funzionare per i file
-manetenuti su NFS, in questo caso, se si ha la necessità di eseguire il
-\textit{file locking}, occorre usare l'interfaccia basata su \func{fcntl} che
-può funzionare anche attraverso NFS, a condizione che sia il client che il
-server supportino questa funzionalità.
-La standardizzatione operata con POSIX.1 ha adottato le API per il
-\textit{file locking} originarie di System V, basate sulla funzione 
-
-
-
-Al contrario di \func{flock} con \func{fcntl} è possibile bloccare anche solo
-delle sezioni di un file. La funzione prende come argomento una struttura
-\var{flock} la cui definizione è riportata in \figref{fig:struct_flock}.
-
+Al contrario di quanto avviene con l'interfaccia basata su \func{flock} con
+\func{fcntl} è possibile bloccare anche delle singole sezioni di un file;
+inoltre la funzione permette di leggere le informazioni relative ai blocchi
+esistenti.  Per poter fare tutto questo la funzione utilizza come terzo
+argomento una apposita struttura \var{flock} (la cui definizione è riportata
+in \figref{fig:struct_flock}) che contiene tutte le specifiche di un dato file
+lock.
 
 \begin{figure}[!htb]
   \footnotesize \centering
@@ -1475,7 +1471,139 @@ struct flock {
   \label{fig:struct_flock}
 \end{figure}
 
+L'operazione effettivamente svolta dalla funzione è stabilita dal valore
+dall'argomento \param{cmd} che, come già riportato in \secref{sec:file_fcntl},
+specifica l'azione da compiere; i valori relativi al file loking sono tre:
+\begin{basedescript}{\desclabelwidth{2.0cm}}
+\item[\macro{F\_GETLK}] verifica se il file lock specificato dalla struttura
+  puntata da \param{lock} non è bloccato da qualche altro lock: in caso
+  affermativo sovrascrive la struttura con i valori relativi a quest'ultimo,
+  altrimenti si limita a impostarne il campo \var{l\_type} con
+  \macro{F\_UNLCK}.
+\item[\macro{F\_SETLK}] se il campo \var{l\_type} della struttura puntata da
+  \param{lock} è \macro{F\_RDLCK} o \macro{F\_WRLCK} richiede il
+  corrispondente file lock, se è \macro{F\_UNLCK} lo rilascia. Nel caso la
+  richiesta non possa essere soddisfatta a causa di un lock preesistente la
+  funzione ritorna immediatamente con un errore di \macro{EACCES} o di
+  \macro{EAGAIN}.
+\item[\macro{F\_SETLKW}] è identica a \macro{F\_SETLK}, ma se la richiesta di
+  un lock non può essere soddisfatta per la presenza di un altro blocco, mette
+  il processo in stato di attesa fintanto che il lock precedente non viene
+  rilasciato. Se l'attesa viene interrotta da un segnale la funzione ritorna
+  con un errore di \macro{EINTR}.
+\end{basedescript}
+
+Come accennato nell'interfaccia POSIX ogni file lock viene associato ad una
+struttura \func{flock}; i tre campi \var{l\_whence}, \var{l\_start} e
+\var{l\_len}, servono a specificare la sezione del file a cui fa riferimento
+il lock, \var{l\_start} specifica il byte di partenza, e \var{l\_len} la
+lunghezza della sezione; \var{l\_whence} infine imposta il riferimento da cui
+contare \var{l\_start} e segue la stessa semantica dell'omonimo argomento di
+\func{lseek}, coi tre possibili valori \macro{SEEK\_SET}, \macro{SEEK\_CUR} e
+\macro{SEEK\_END} (si vedano le relative descrizioni in
+\secref{sec:file_lseek}).
+
+Si tenga presente che un lock può essere richiesto anche per una regione al di
+là della corrente fine del file, così che una eventuale estensione dello
+stesso resti coperta dal blocco. Se si specifica un valore nullo per
+\var{l\_len} il blocco si considera esteso fino alla dimensione massima del
+file; in questo modo è possibile bloccare una qualunque regione a partire da
+un certo punto fino alla fine del file, coprendo automaticamente quanto
+eventualmente aggiunto in coda allo stesso.
+
+\begin{table}[htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|l|}
+    \hline
+    \textbf{Valore} & \textbf{Significato} \\
+    \hline
+    \hline
+    \macro{F\_RDLCK} & Richiede un blocco condiviso (\textit{read lock}).\\
+    \macro{F\_WRLCK} & Richiede un blocco esclusivo (\textit{write lock}).\\
+    \macro{F\_UNLCK} & Richiede l'eliminazione di un lock.\\
+    \hline    
+  \end{tabular}
+  \caption{Valori possibili per il campo \var{l\_type} di \func{flock}.}
+  \label{tab:file_flock_type}
+\end{table}
+
+Il tipo di file lock richiesto viene specificato dal campo \var{l\_type}, esso
+può assumere i tre valori riportati in \tabref{tab:file_flock_type}, che
+permettono di richiedere rispettivamente uno \textit{shared lock}, un
+\textit{esclusive lock}, e la rimozione di un lock precedentemente acquisito.
+
+\begin{figure}[htb]
+  \centering
+  \includegraphics[width=13cm]{img/file_posix_lock}
+  \caption{Schema dell'architettura del file locking, nel caso particolare  
+    del suo utilizzo secondo l'interfaccia standard POSIX.}
+  \label{fig:file_posix_lock}
+\end{figure}
+
+Infine il campo \var{l\_pid} riporta (viene usato solo in lettura, quando si
+chiama \func{fcntl} con \macro{F\_GETLK}) qual'è il processo cui appartiene il
+file lock. Nella semantica POSIX infatti il comportamento dei lock è diverso
+rispetto a quanto visto in precedenza per \func{flock}. Lo schema della
+struttura usata in questo caso è riportato in \figref{fig:file_posix_lock};
+come si vede essa è molto simile a quanto visto in
+\figref{fig:file_flock_struct} per \func{flock}:\footnote{in questo caso si
+  sono evidenziati nella figura i campi di \var{file\_lock} significativi per
+  la semantica POSIX, in particolare adesso ciascun lock contiene, oltre al
+  \acr{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 è
+  comunque la stessa, solo che in questo caso nel campo \var{fl\_flags} è
+  impostato il bit \macro{FL\_POSIX} ed il campo \var{fl\_file} non viene
+  usato.} il lock è sempre associato all'inode, solo che in questo caso la
+titolarità non viene identificata con il riferimento ad una voce nella file
+table, ma con il valore del \acr{pid} del processo.
+
+Tutto ciò significa che la rimozione di un blocco viene effettuata
+controllando che il \acr{pid} del processo richiedente corrisponda a quello
+contenuto nel lock. Questa diversa modalità ha delle conseguenze precise
+riguardo il comportamento dei lock POSIX. La prima conseguenza è che un lock
+POSIX non viene mai ereditato attraverso una \func{fork}, dato che il processo
+figlio avrà un \acr{pid} diverso, mentre passa indenne attraverso una
+\func{exec} in quanto il \acr{pid} resta lo stesso.  Questo comporta che, al
+contrario di quanto avveniva con la semantica BSD, quando processo termina
+tutti i file lock da esso detenuti vengono immediatamente rilasciati.
+
+La seconda conseguenza è che qualunque file descriptor che faccia riferimento
+allo stesso file (che sia stato ottenuto con una \func{dup} o con una
+\func{open} non fa differenza) può essere usato per rimuovere un lock, dato
+che quello che conta è solo il \acr{pid} del processo. Da questo deriva una
+ulteriore sottile differenza di comportamento: dato che alla chiusura di un
+file i lock ad esso associati vengono rimossi, nella semantica POSIX basterà
+chiudere un file descriptor per cancellare tutti i lock realtivi al file cui
+esso faceva riferimento, anche se questi fossero stati creati usando altri
+file descriptor che restano aperti.
+
+Come abbiamo visto come l'interfaccia POSIX per il file locking sia molto più
+potente e flessibile di quella di BSD, ma è anche molto più complicata da
+usare, specie in tutti quei casi in cui non si vogliono bloccare sezioni
+separate di file. Per questo, seguendo System V, è disponibile una interfaccia
+semplificata grazie alla funzione \func{lockf}, il cui prototipo è:
+\begin{prototype}{sys/file.h}{int lockf(int fd, int cmd, off\_t len)}
+  
+  Applica, controlla o rimuove un \textit{file lock} sul file \param{fd}.
+  
+  \bodydesc{La funzione restituisce 0 in caso di successo, e -1 in caso di
+    errore, nel qual caso \var{errno} assumerà uno dei valori:
+    \begin{errlist}
+    \item[\macro{EAGAIN}] Non è possibile acquisire il lock, e si è
+      selezionato \macro{LOCK\_NB}, oppure l'operazione è proibita perché il
+      file è mappato in memoria.
+    \item[\macro{ENOLCK}] Il sistema non ha le risorse per il locking: ci sono
+      troppi segmenti di lock aperti, si è esaurita la tabella dei lock.
+    \item[\macro{EDEADLK}] Si è riconosciuta una situazione di
+      \textit{deadlock}.
+    \end{errlist}
+    ed inoltre \macro{EBADF}, \macro{EINVAL}.
+  }
+\end{prototype}
 
+Il comportamento della funzione dipende dal valore dell'argomento \param{cmd}
+che specifica quale azione eseguire; i valori possibili sono riportati in 
 
 \subsection{Il \textit{mandatory locking}}
 \label{sec:file_mand_locking}
index bd3ed09..a36652d 100644 (file)
@@ -487,11 +487,12 @@ essersi spostata, ma noi scriveremo alla posizione impostata in precedenza.
 Non tutti i file supportano la capacità di eseguire una \func{lseek}, in
 questo caso la funzione ritorna l'errore \macro{EPIPE}. Questo, oltre che per
 i tre casi citati nel prototipo, vale anche per tutti quei dispositivi che non
-supportano questa funzione, come ad esempio per le \acr{tty}.\footnote{altri
-  sistemi, usando \macro{SEEK\_SET}, in questo caso ritornano il numero di
-  caratteri che vi sono stati scritti.} Lo standard POSIX però non specifica
-niente al proposito. Infine alcuni device, ad esempio \file{/dev/null}, non
-causano un errore ma restituiscono un valore indefinito.
+supportano questa funzione, come ad esempio per i file di
+terminale.\footnote{altri sistemi, usando \macro{SEEK\_SET}, in questo caso
+  ritornano il numero di caratteri che vi sono stati scritti.} Lo standard
+POSIX però non specifica niente al proposito. Infine alcuni file speciali, ad
+esempio \file{/dev/null}, non causano un errore ma restituiscono un valore
+indefinito.
 
 
 \subsection{La funzione \func{read}}
@@ -1004,21 +1005,20 @@ valori 
   nella terza sezione di \tabref{tab:file_open_flags}.\footnote{la pagina di
     manuale riporta come impostabili solo \macro{O\_APPEND},
     \macro{O\_NONBLOCK} e \macro{O\_ASYNC}.}
-\item[\macro{F\_GETLK}] se un file lock è attivo restituisce nella struttura
-  \param{lock} la struttura \type{flock} che impedisce l'acquisizione del
-  blocco, altrimenti imposta il campo \var{l\_type} a \macro{F\_UNLCK} (per i
-  dettagli sul \textit{file locking} vedi \secref{sec:file_locking}).
-\item[\macro{F\_SETLK}] richiede il file lock specificato da \param{lock} se
-  \var{l\_type} è \macro{F\_RDLCK} o \macro{F\_WRLLCK} o lo rilascia se
-  \var{l\_type} è \macro{F\_UNLCK}. Se il lock è tenuto da qualcun'altro
-  ritorna immediatamente restituendo -1 e imposta \var{errno} a \macro{EACCES}
-  o \macro{EAGAIN} (per i dettagli sul \textit{file locking} vedi
-  \secref{sec:file_locking}).
+\item[\macro{F\_GETLK}] richiede un controllo sul file lock specificato da
+  \param{lock}, sovrascrivendo la struttura da esso puntata con il risultato
+  (questa funzionalità è trattata in dettaglio in
+  \secref{sec:file_posix_lock}).
+\item[\macro{F\_SETLK}] richiede o rilascia un file lock a seconda di quanto
+  specificato nella struttura puntata da \param{lock}. Se il lock è tenuto da
+  qualcun'altro ritorna immediatamente restituendo -1 e imposta \var{errno} a
+  \macro{EACCES} o \macro{EAGAIN} (questa funzionalità è trattata in dettaglio
+  in \secref{sec:file_posix_lock}).
 \item[\macro{F\_SETLKW}] identica a \macro{F\_SETLK} eccetto per il fatto che
   la funzione non ritorna subito ma attende che il blocco sia rilasciato. Se
   l'attesa viene interrotta da un segnale la funzione restituisce -1 e imposta
-  \var{errno} a \macro{EINTR} (per i dettagli sul \textit{file locking} vedi
-  \secref{sec:file_locking}).
+  \var{errno} a \macro{EINTR} (questa funzionalità è trattata in dettaglio in
+  \secref{sec:file_posix_lock}).
 \item[\macro{F\_GETOWN}] restituisce il \acr{pid} del processo o il process
   group che è preposto alla ricezione dei segnali \macro{SIGIO} e
   \macro{SIGURG} per gli eventi associati al file descriptor \var{fd}. Il
index b5df9a4..7c30fd8 100644 (file)
Binary files a/img/file_flock.dia and b/img/file_flock.dia differ
index 076627f..fdb6361 100644 (file)
Binary files a/img/filedup.dia and b/img/filedup.dia differ
index 88ee2a6..587c3c2 100644 (file)
Binary files a/img/filemultacc.dia and b/img/filemultacc.dia differ
index cdc2a66..97eb289 100644 (file)
Binary files a/img/fileshar.dia and b/img/fileshar.dia differ
index 2a8948f..adff9e7 100644 (file)
Binary files a/img/procfile.dia and b/img/procfile.dia differ