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
 \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
 
 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.
 
 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
 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}.
 \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
     \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}.\\
     \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}
 
   \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}
 
 \subsection{Il \textit{mandatory locking}}
 \label{sec:file_mand_locking}