From 6408f44e3fcb3a4931ce5faf9706faf86fc22caa Mon Sep 17 00:00:00 2001 From: Simone Piccardi Date: Fri, 18 Oct 2002 21:55:51 +0000 Subject: [PATCH] Aggiunta figura sullo schema del kernel per il file locking --- fileadv.tex | 102 ++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 84 insertions(+), 18 deletions(-) diff --git a/fileadv.tex b/fileadv.tex index 8ec9dc3..c269d6a 100644 --- a/fileadv.tex +++ b/fileadv.tex @@ -1250,13 +1250,6 @@ eventuale blocco, e che sta ai vari processi controllare esplicitamente lo stato dei file condivisi prima di accedervi, implementando un opportuno protocollo. -In Linux sono disponibili due interfacce per utilizzare l'\textit{advisory - locking}, la prima è quella derivata da BSD, che è basata sulla funzione -\func{flock}, la seconda è quella standardizzata da POSIX.1 (derivata da -System V), che è basata sulla funzione \func{fcntl}. I \textit{file lock} -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 @@ -1271,16 +1264,32 @@ scrivendo. Si parla di \textsl{blocco esclusivo} appunto perch processo alla volta può richiedere un \textit{exclusive lock} su un file per proteggere il suo 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} attivo, o un \textit{exclusive lock} su un file con un qualunque -blocco attivo) la funzione blocca il processo fintanto che \textit{file lock} -preesistente non viene rimosso. +In Linux sono disponibili due interfacce per utilizzare l'\textit{advisory + locking}, la prima è quella derivata da BSD, che è basata sulla funzione +\func{flock}, la seconda è quella standardizzata da POSIX.1 (derivata da +System V), che è basata sulla funzione \func{fcntl}. I \textit{file lock} +sono implementati in maniera completamente indipendente nelle due interfacce, +che pertanto possono coesistere senza interferenze. + +Entrambe le interfacce prevedono la stessa procedura di funzionamento: si +inizia sempre con il richiere l'opportuno \textit{file lock} (un +\textit{exclusive lock} per una scrittura, uno \textit{shared lock} per una +lettura) prima di eseguire l'accesso ad un file. Se il lock viene acquisito +il processo prosegue l'esecuzione, altrimenti (a meno di non aver richiesto un +comportamento non bloccante) viene posto in stato di sleep. Una volta finite +le operazioni sul file si deve provvedere a rimuovere il lock. Si ricordi che +la condizione per acquisire uno \textit{shared lock} è che il file non abbia +già un \textit{exclusive lock} attivo, mentre per acquisire un +\textit{exclusive lock} non deve essere presente nessun tipo di blocco. + -La prima interfaccia, quella derivata da BSD, permette di eseguire il blocco -solo su di un intero file; funzione usata per richiedere e rimuovere un -\textit{file lock} è \func{flock}, ed il suo prototipo è: +\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 è: \begin{prototype}{sys/file.h}{int flock(int fd, int operation)} Applica o rimuove un \textit{file lock} sul file \param{fd}. @@ -1296,8 +1305,8 @@ solo su di un intero file; funzione usata per richiedere e rimuovere un La funzione può essere usata per acquisire o rilasciare un blocco a seconda di quanto specificato tramite il valore dell'argomento \param{operation}, questo -deve essere passato come maschera binaria dei valori riportati in -\tabref{tab:file_flock_operation}. +viene interpretato come maschera binaria, e deve essere passato utilizzando le +costanti riportate in \tabref{tab:file_flock_operation}. \begin{table}[htb] \centering @@ -1318,6 +1327,57 @@ deve essere passato come maschera binaria dei valori riportati in \label{tab:file_flock_operation} \end{table} +I primi due valori, \macro{LOCK\_SH} e \macro{LOCK\_EX} permettono di +richiedere un \textit{file lock}, ed ovviamente devono essere usati in maniera +esclusiva. Se si specifica anche \macro{LOCK\_NB} la funzione non si bloccherà +qualora il lock non possa essere aqcuisito, ma ritornerà subito con un errore +di \macro{EWOULDBLOCK}. Per rilasciare un lock si dovrà invece usare +\macro{LOCK\_NB}. + +La semantica del file locking di BSD è diversa da quella del file locking +POSIX, in particolare per quanto riguarda il comportamento dei lock nei +confronti delle due funzioni \func{dup} e \func{fork}. Per capire cosa +succede in questi casi, occorre tenere presente che il file locking (qualunque +sia l'interfaccia che si usa), anche se richiesto attraverso un file +descriptor, agisce sempre su un file, secondo lo schema di +\figref{fig:file_lock_struct}. Questo significa che le informazioni relative +agli eventuali lock sono mantenute a livello di inode,\footnote{come mostrato + in \figref{fig:file_flock_struct} i \textit{file lock} sono mantenuti un una + \textit{linked list}\index{linked list} di strutture \var{file\_lock}, il + cui indirizzo iniziale è mantenuto dal campo \var{i\_flock} della struttura + \var{inode} (il tutto è definito nei sorgenti del kernel in \file{fs.h}). Un + bit del campo \var{fl\_flags} di specifica se si tratta di un lock in + semantica BSD (\macro{FL\_FLOCK}) o POSIX (\macro{FL\_POSIX}).} come è +naturale dato che l'inode è l'unica cosa in comune cui possono accedere due +processi diversi che aprono lo stesso file. + + +\begin{figure}[htb] + \centering + \includegraphics[width=13cm]{img/file_flock} + \caption{Schema dell'architettura del file locking, nel caso particolare + del suo utilizzo da parte dalla funzione \func{flock}.} + \label{fig:file_flock_struct} +\end{figure} + + + +Nel caso dei lock creati con \func{flock} la semantica prevede che sia +\func{dup} che \func{fork} non creano ulteriori istanze di un \textit{file + lock} quanto piuttosto degli ulteriori riferimenti allo stesso. Questo viene +realizzato dal kernel mantenendo per ciascun \textit{file lock} un +puntatore\footnote{nel campo \var{fl\_file} di \var{file\_lock}.} al file +nella \textit{file table} cui esso fa riferimento. + + +che il kernel mantiene per ciascuno di +essi\footnote{nel campo \var{fl\_file}.} anche un riferimento + +essi fanno riferimento al + + + + Si tenga presente che la funzione blocca direttamente un file (cioè, rispetto allo schema di \secref{fig:file_stat_struct}, il blocco è mantenuto in riferimento alla struttura \var{file}, e non al file descriptor). Pertanto sia @@ -1329,6 +1389,12 @@ blocco in un processo figlio o su un file descriptor duplicato, questo sar cancellato rispettivamente anche nel processo padre e sul file descriptor originario. + + + +\subsection{Il file locking POSIX} +\label{sec:file_posix_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 -- 2.30.2