Aggiunte e correzioni
authorSimone Piccardi <piccardi@gnulinux.it>
Tue, 15 Oct 2002 22:21:33 +0000 (22:21 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Tue, 15 Oct 2002 22:21:33 +0000 (22:21 +0000)
fileadv.tex

index 7ff5ff72f9ac965bb3682fa455e3d4d8e73b30aa..0d6e2f08d1f3160ce34f94cd4b847d0ebc9526dd 100644 (file)
@@ -1232,13 +1232,22 @@ sovrapposizioni, e garantire la atomicit
 \label{sec:file_record_locking}
 
 La prima modalità di file locking che è stata implementata nei sistemi
-unix-like è quella che viene usualmente chiamata \textit{advisory locking}, in
-quanto sono i singoli processi, e non il sistema, che si incaricano di
-asserire e verificare se esistono delle condizioni di blocco per l'accesso ai
-file. Questo significa che le funzioni \func{read} o \func{write} non
-risentono affatto della presenza di un eventuale blocco, e che sta ai vari
-processi controllare esplicitamente lo stato dei file condivisi prima di
-accedervi ed implementare opportunamente un protocollo di accesso.
+unix-like è quella che viene usualmente chiamata \textit{advisory
+  locking},\footnote{Stevens in APUE fa riferimento a questo argomento come al
+  \textit{record locking}, dizione utilizzata anche dal manuale delle
+  \acr{glibc}; nelle pagine di manuale si parla di \textit{discretionary file
+    lock} per \func{fcntl} e di \textit{advisory locking} per \func{flock},
+  mentre questo nome viene usato anche da Stevens per riferirsi al
+  \textit{file locking} di POSIX. Dato che la dizione \textit{record locking}
+  è quantomeno ambigua in quanto non esiste niente che possa fare riferimento
+  al concetto di \textit{record}, alla fine si è scelto di mantenere il nome
+  \textit{advisory locking}.} in quanto sono i singoli processi, e non il
+sistema, che si incaricano di asserire e verificare se esistono delle
+condizioni di blocco per l'accesso ai file.  Questo significa che le funzioni
+\func{read} o \func{write} non risentono affatto della presenza di un
+eventuale blocco, e che sta ai vari processi controllare esplicitamente lo
+stato dei file condivisi prima di accedervi ed implementare opportunamente un
+protocollo di accesso.
 
 In Linux sono disponibili due interfacce per utilizzare l'\textit{advisory
   locking}, la prima è quella derivata da BSD, che è basata sulla funzione
@@ -1247,9 +1256,29 @@ System V), che 
 sono implementati in maniera completamente indipendente nelle due interfacce,
 che pertanto possono coesistere senza interferenze.
 
+In generale si distinguono due tipologie di blocco per un file: la prima è il
+cosiddetto \textit{shared lock}, detto anche \textit{read lock} in quanto
+serve a bloccare l'accesso in scrittura su un file affinché non venga
+modificato mentre lo si legge. Si parla di \textsl{blocco condiviso} in quanto
+più processi possono richiedere contemporaneamente uno \textit{shared lock}
+per proteggere un accesso in lettura.
+
+La seconda è il cosiddetto \textit{exclusive lock}, detto anche \textit{write
+  lock} in quanto serve a bloccare l'accesso su un file da parte di altri (sia
+in lettura che in scrittura) mentre lo si sta scrivendo. Si parla di
+\textsl{blocco esclusivo} appunto perché un solo processo alla volta può
+richiedere un \textit{exclusive lock} per proteggere un accesso in scrittura.
+
+Entrambe le interfacce garantiscono che quando si richiede un \textit{file
+  lock} su un file su cui ne sia già presente un altro che non ne consente
+l'acquisizione (uno \textit{shared lock} su un file con un \textit{exclusive
+  lock}, o un \textit{exclusive lock} su un file con altro \textit{file lock})
+la funzione blocca il processo fintanto che \textit{file lock} preesistente
+non viene rimosso.
+
 L'interfaccia classica usata da BSD permette di eseguire il blocco solo su un
-intero file, come accennato essa è basata sulla funzione \func{flock}, il cui
-prototipo è:
+intero file, funzione usata per richiedere e rimuovere un \textit{file lock} è
+\func{flock}, il cui prototipo è:
 \begin{prototype}{sys/file.h}{int flock(int fd, int operation)}
   
   Applica o rimuove un \textit{file lock} sul file \param{fd}.
@@ -1275,12 +1304,8 @@ Il comportamento della funzione 
     \textbf{Valore} & \textbf{Significato} \\
     \hline
     \hline
-    \macro{LOCK\_SH} & Asserisce uno \textit{shared lock} (blocco
-                       condiviso) sul file. Un blocco condiviso può essere
-                       mantenuto da più processi contemporaneamente.\\ 
-    \macro{LOCK\_EX} & Asserisce un \textit{esclusive lock} (blocco
-                       esclusivo) sul file. Un blocco esclusivo può essere
-                       mantenuto da un solo processo alla volta.\\
+    \macro{LOCK\_SH} & Asserisce uno \textit{shared lock} sul file.\\ 
+    \macro{LOCK\_EX} & Asserisce un \textit{esclusive lock} sul file.\\
     \macro{LOCK\_UN} & Sblocca il file.\\
     \macro{LOCK\_NB} & Impedisce che la funzione si blocchi nella
                        richiesta di un \textit{file lock}.\\
@@ -1290,12 +1315,70 @@ Il comportamento della funzione 
   \label{tab:file_flock_operation}
 \end{table}
 
+La funzione blocca direttamente il file (cioè rispetto allo schema di
+\secref{fig:file_stat_struct} fa riferimento all'inode, non al file
+descriptor). Pertanto sia \func{dup} che \func{fork} non creano altre istanze
+di un \textit{file lock}.
+
+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:
+\begin{prototype}{fcntl.h}{int fcntl(int fd, int cmd, struct flock *lock)}
+  
+  Applica 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{EACCES}] L'operazione è proibita per la presenza di
+      \textit{file lock} da parte di altri processi.
+    \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, o il
+      protocollo per il locking remoto è fallito.
+    \item[\macro{EDEADLK}] Si è richiesto un lock su una regione bloccata da
+      un altro processo che è a sua volta in attesa dello sblocco di un lock
+      mantenuto dal processo corrente; si avrebbe pertanto un
+      \textit{deadlock}. Non è garantito che il sistema riconosca sempre
+      questa situazione.
+    \item[\macro{EINTR}] La funzione è stata interrotta da un segnale prima di
+      poter acquisire un lock.
+    \end{errlist}
+    ed inoltre \macro{EBADF}, \macro{EFAULT}.
+  }
+\end{prototype}
 
-Si tenga conto che la funzione non è in grado di eseguire un blocco su NFS, in
-tal caso occorre usare \func{fcntl} che funziona anche attraverso NFS, posto
-che il server supporti il \textit{file locking}. 
+Al contrario di \func{flock} con \func{fcntl} è possibile bloccare anche solo
+delle sezioni di un file. La funzione prende come argomento 
 
 
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
+struct struct {
+    short int l_type;   /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK.  */
+    short int l_whence; /* Where `l_start' is relative to (like `lseek').  */
+    off_t l_start;      /* Offset where the lock begins.  */
+    off_t l_len;        /* Size of the locked area; zero means until EOF.  */
+    pid_t l_pid;        /* Process holding the lock.  */
+};
+    \end{lstlisting}
+  \end{minipage} 
+  \normalsize 
+  \caption{La struttura \type{flock}, usata da \func{fcntl} per il file
+    locking.} 
+  \label{fig:struct_flock}
+\end{figure}
+
+
+
+
+Si tenga conto che \func{flock} non è in grado di eseguire il \textit{file
+  locking} su NFS, se si ha questa necessità occorre usare \func{fcntl} che
+funziona anche attraverso NFS, posto che il server supporti il \textit{file
+  locking}.
 
 \subsection{Il \textit{mandatory locking}}
 \label{sec:file_mand_locking}