Lavoro fatto a casa senza ADSL, correzioni multiple agli indici, documentato
[gapil.git] / fileadv.tex
index 67d6795a113785b3eb8ff1e9c00e73d4a833304c..b49bcf84ad8ccd7fe3c295251d2ab32f95614ae2 100644 (file)
@@ -52,7 +52,7 @@ possibile prevedere quando questo pu
 di un server in attesa di dati in ingresso da vari client). Quello che può
 accadere è di restare bloccati nell'eseguire una operazione su un file
 descriptor che non è ``\textsl{pronto}'', quando ce ne potrebbe essere
-un'altro disponibile. Questo comporta nel migliore dei casi una operazione
+un altro disponibile. Questo comporta nel migliore dei casi una operazione
 ritardata inutilmente nell'attesa del completamento di quella bloccata, mentre
 nel peggiore dei casi (quando la conclusione della operazione bloccata dipende
 da quanto si otterrebbe dal file descriptor ``\textsl{disponibile}'') si
@@ -222,7 +222,7 @@ ha ovviamente delle conseguenze ampiamente negative per le prestazioni.
 Inoltre c'è anche il problema che il numero massimo dei file che si possono
 tenere sotto controllo, la funzione è nata quando il kernel consentiva un
 numero massimo di 1024 file descriptor per processo, adesso che il numero può
-essere arbitario si viene a creare una dipendenza del tutto artificiale dalle
+essere arbitrario si viene a creare una dipendenza del tutto artificiale dalle
 dimensioni della struttura \type{fd\_set}, che può necessitare di essere
 estesa, con ulteriori perdite di prestazioni. 
 
@@ -439,7 +439,7 @@ tramite \var{errno}.
 %\label{sec:file_epoll}
 % placeholder ...
 
-%da fare
+% TODO epoll
 
 \section{L'accesso \textsl{asincrono} ai file}
 \label{sec:file_asyncronous_access}
@@ -504,7 +504,8 @@ POSIX.1b dei segnali real-time, che vengono accodati e che permettono di
 riconoscere il file descriptor che li ha emessi. In questo caso infatti si può
 fare ricorso alle informazioni aggiuntive restituite attraverso la struttura
 \struct{siginfo\_t}, utilizzando la forma estesa \var{sa\_sigaction} del
-gestore (si riveda quanto illustrato in sez.~\ref{sec:sig_sigaction}).
+gestore installata con il flag \const{SA\_SIGINFO} (si riveda quanto
+illustrato in sez.~\ref{sec:sig_sigaction}).
 
 Per far questo però occorre utilizzare le funzionalità dei segnali real-time
 (vedi sez.~\ref{sec:sig_real_time}) impostando esplicitamente con il comando
@@ -530,6 +531,243 @@ invier
 i segnali in eccesso, e si dovrà allora determinare con un ciclo quali sono i
 file diventati attivi.
 
+% TODO fare esempio che usa O_ASYNC
+
+
+\subsection{I meccanismi di notifica asincrona.}
+\label{sec:file_asyncronous_lease}
+
+Una delle domande più frequenti nella programmazione in ambiente unix-like è
+quella di come fare a sapere quando un file viene modificato. La
+risposta\footnote{o meglio la non risposta, tanto che questa nelle Unix FAQ
+  \cite{UnixFAQ} viene anche chiamata una \textit{Frequently Unanswered
+    Question}.} è che nell'architettura classica di Unix questo non è
+possibile. Al contrario di altri sistemi operativi infatti un kernel unix-like
+non prevede alcun meccanismo per cui un processo possa essere
+\textsl{notificato} di eventuali modifiche avvenute su un file. Questo è il
+motivo per cui i demoni devono essere \textsl{avvisati} in qualche
+modo\footnote{in genere questo vien fatto inviandogli un segnale di
+  \const{SIGHUP} che, per convenzione adottata dalla gran parte di detti
+  programmi, causa la rilettura della configurazione.} se il loro file di
+configurazione è stato modificato, perché possano rileggerlo e riconoscere le
+modifiche.
+
+Questa scelta è stata fatta perché provvedere un simile meccanismo a livello
+generale comporterebbe un notevole aumento di complessità dell'architettura
+della gestione dei file, per fornire una funzionalità necessaria soltanto in
+casi particolari. Dato che all'origine di Unix i soli programmi che potevano
+avere una tale esigenza erano i demoni, attenendosi a uno dei criteri base
+della progettazione, che era di far fare al kernel solo le operazioni
+strettamente necessarie e lasciare tutto il resto a processi in user space,
+non era stata prevista nessuna funzionalità di notifica.
+
+Visto però il crescente interesse nei confronti di una funzionalità di questo
+tipo (molto richiesta specialmente nello sviluppo dei programmi ad interfaccia
+grafica) sono state successivamente introdotte delle estensioni che
+permettessero la creazione di meccanismi di notifica più efficienti dell'unica
+soluzione disponibile con l'interfaccia tradizionale, che è quella del
+\itindex{polling}\textit{polling}.
+
+Queste nuove funzionalità sono delle estensioni specifiche, non
+standardizzate, che sono disponibili soltanto su Linux (anche se altri kernel
+supportano meccanismi simili). Esse sono realizzate, e solo a partire dalla
+versione 2.4 del kernel, attraverso l'uso di alcuni \textsl{comandi}
+aggiuntivi per la funzione \func{fcntl} (vedi sez.~\ref{sec:file_fcntl}), che
+divengono disponibili soltanto se si è definita la macro \macro{\_GNU\_SOURCE}
+prima di includere \file{fcntl.h}.
+
+\index{file!lease|(} 
+
+La prima di queste funzionalità è quella del cosiddetto \textit{file lease};
+questo è un meccanismo che consente ad un processo, detto \textit{lease
+  holder}, di essere notificato quando un altro processo, chiamato a sua volta
+\textit{lease breaker}, cerca di eseguire una \func{open} o una
+\func{truncate} sul file del quale l'\textit{holder} detiene il
+\textit{lease}.
+
+La notifica avviene in maniera analoga a come illustrato in precedenza per
+l'uso di \const{O\_ASYNC}: di default viene inviato al \textit{lease holder}
+il segnale \const{SIGIO}, ma questo segnale può essere modificato usando il
+comando \const{F\_SETSIG} di \func{fcntl}.\footnote{anche in questo caso si
+  può rispecificare lo stesso \const{SIGIO}.} Se si è fatto questo\footnote{è
+  in genere è opportuno farlo, come in precedenza, per utilizzare segnali
+  real-time.} e si è installato il manipolatore del segnale con
+\const{SA\_SIGINFO} si riceverà nel campo \var{si\_fd} della struttura
+\struct{siginfo\_t} il valore del file descriptor del file sul quale è stato
+compiuto l'accesso; in questo modo un processo può mantenere anche più di un
+\textit{file lease}.
+
+Esistono due tipi di \textit{file lease}: di lettura (\textit{read lease}) e
+di scrittura (\textit{write lease}). Nel primo caso la notifica avviene quando
+un altro processo esegue l'apertura del file in scrittura o usa
+\func{truncate} per troncarlo. Nel secondo caso la notifica avviene anche se
+il file viene aperto il lettura; in quest'ultimo caso però il \textit{lease}
+può essere ottenuto solo se nessun altro processo ha aperto lo stesso file.
+
+Come accennato in sez.~\ref{sec:file_fcntl} il comando di \func{fcntl} che
+consente di acquisire un \textit{file lease} è \const{F\_SETLEASE}, che viene
+utilizzato anche per rilasciarlo. In tal caso il file descriptor \param{fd}
+passato a \func{fcntl} servirà come riferimento per il file su cui si vuole
+operare, mentre per indicare il tipo di operazione (acquisizione o rilascio)
+occorrerà specificare come valore dell'argomento \param{arg} di \func{fcntl}
+uno dei tre valori di tab.~\ref{tab:file_lease_fctnl}.
+
+\begin{table}[htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|l|}
+    \hline
+    \textbf{Valore}  & \textbf{Significato} \\
+    \hline
+    \hline
+    \const{F\_RDLCK} & Richiede un \textit{read lease}.\\
+    \const{F\_WRLCK} & Richiede un \textit{write lease}.\\
+    \const{F\_UNLCK} & Rilascia un \textit{file lease}.\\
+    \hline    
+  \end{tabular}
+  \caption{Costanti per i tre possibili valori dell'argomento \param{arg} di
+    \func{fcntl} quando usata con i comandi \const{F\_SETLEASE} e
+    \const{F\_GETLEASE}.} 
+  \label{tab:file_lease_fctnl}
+\end{table}
+
+Se invece si vuole conoscere lo stato di eventuali \textit{file lease}
+occorrerà chiamare \func{fcntl} sul relativo file descriptor \param{fd} con il
+comando \const{F\_GETLEASE}, e si otterrà indietro nell'argomento \param{arg}
+uno dei valori di tab.~\ref{tab:file_lease_fctnl}, che indicheranno la
+presenza del rispettivo tipo di \textit{lease}, o, nel caso di
+\const{F\_UNLCK}, l'assenza di qualunque \textit{file lease}.
+
+Si tenga presente che un processo può mantenere solo un tipo di \textit{lease}
+su un file, e che un \textit{lease} può essere ottenuto solo su file di dati
+(pipe e dispositivi sono quindi esclusi). Inoltre un processo non privilegiato
+può ottenere un \textit{lease} soltanto per un file appartenente ad un
+\acr{uid} corrispondente a quello del processo. Soltanto un processo con
+privilegi di amministratore (cioè con la \itindex{capabilities} capability
+\const{CAP\_LEASE}) può acquisire \textit{lease} su qualunque file.
+
+Se su un file è presente un \textit{lease} quando il \textit{lease breaker}
+esegue una \func{truncate} o una \func{open} che confligge con
+esso,\footnote{in realtà \func{truncate} confligge sempre, mentre \func{open},
+  se eseguita in sola lettura, non confligge se si tratta di un \textit{read
+    lease}.} la funzione si blocca\footnote{a meno di non avere aperto il file
+  con \const{O\_NONBLOCK}, nel qual caso \func{open} fallirebbe con un errore
+  di \errcode{EWOULDBLOCK}.} e viene eseguita la notifica al \textit{lease
+  holder}, così che questo possa completare le sue operazioni sul file e
+rilasciare il \textit{lease}.  In sostanza con un \textit{read lease} si
+rilevano i tentativi di accedere al file per modificarne i dati da parte di un
+altro processo, mentre con un \textit{write lease} si rilevano anche i
+tentativi di accesso in lettura.  Si noti comunque che le operazioni di
+notifica avvengono solo in fase di apertura del file e non sulle singole
+operazioni di lettura e scrittura.
+
+L'utilizzo dei \textit{file lease} consente al \textit{lease holder} di
+assicurare la consistenza di un file, a seconda dei due casi, prima che un
+altro processo inizi con le sue operazioni di scrittura o di lettura su di
+esso. In genere un \textit{lease holder} che riceve una notifica deve
+provvedere a completare le necessarie operazioni (ad esempio scaricare
+eventuali buffer), per poi rilasciare il \textit{lease} così che il
+\textit{lease breaker} possa eseguire le sue operazioni. Questo si fa con il
+comando \const{F\_SETLEASE}, o rimuovendo il \textit{lease} con
+\const{F\_UNLCK}, o, nel caso di \textit{write lease} che confligge con una
+operazione di lettura, declassando il \textit{lease} a lettura con
+\const{F\_RDLCK}.
+
+Se il \textit{lease holder} non provvede a rilasciare il \textit{lease} entro
+il numero di secondi specificato dal parametro di sistema mantenuto in
+\file{/proc/sys/fs/lease-break-time} sarà il kernel stesso a rimuoverlo (o
+declassarlo) automaticamente.\footnote{questa è una misura di sicurezza per
+  evitare che un processo blocchi indefinitamente l'accesso ad un file
+  acquisendo un \textit{lease}.} Una volta che un \textit{lease} è stato
+rilasciato o declassato (che questo sia fatto dal \textit{lease holder} o dal
+kernel è lo stesso) le chiamate a \func{open} o \func{truncate} eseguite dal
+\textit{lease breaker} rimaste bloccate proseguono automaticamente.
+
+
+\index{file!notify|(}
+
+Benché possa risultare utile per sincronizzare l'accesso ad uno stesso file da
+parte di più processi, l'uso dei \textit{file lease} non consente comunque di
+risolvere il problema di rilevare automaticamente quando un file viene
+modificato, che è quanto necessario ad esempio ai programma di gestione dei
+file dei vari desktop grafici.  
+
+Per risolvere questo problema è stata allora creata un'altra interfaccia che
+consente di richiedere una notifica quando una directory, o di uno qualunque
+dei file in essa contenuti, viene modificato. Come per i \textit{file lease}
+la notifica avviene di default attraverso il segnale \const{SIGIO}, ma questo
+può essere modificato e si può ottenere nel manipolatore il file descriptor
+che è stato modificato dal contenuto della struttura \struct{siginfo\_t}.
+
+\index{file!lease|)}
+
+Ci si può registrare per le notifiche dei cambiamenti al contenuto di una
+certa directory eseguendo \func{fcntl} su un file descriptor \param{fd}
+associato alla stessa con il comando \const{F\_NOTIFY}. In questo caso
+l'argomento \param{arg} serve ad indicare per quali classi eventi si vuole
+ricevere la notifica, e prende come valore una maschera binaria composta
+dall'OR aritmetico di una o più delle costanti riportate in
+tab.~\ref{tab:file_notify}.
+
+\begin{table}[htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|p{8cm}|}
+    \hline
+    \textbf{Valore}  & \textbf{Significato} \\
+    \hline
+    \hline
+    \const{DN\_ACCESS} & Un file è stato acceduto, con l'esecuzione di una fra
+                         \func{read}, \func{pread}, \func{readv}.\\ 
+    \const{DN\_MODIFY} & Un file è stato modificato, con l'esecuzione di una
+                         fra \func{write}, \func{pwrite}, \func{writev}, 
+                         \func{truncate}, \func{ftruncate}.\\ 
+    \const{DN\_CREATE} & È stato creato un file nella directory, con
+                         l'esecuzione di una fra \func{open}, \func{creat},
+                         \func{mknod}, \func{mkdir}, \func{link},
+                         \func{symlink}, \func{rename} (da un'altra
+                         directory).\\
+    \const{DN\_DELETE} & È stato cancellato un file dalla directory con
+                         l'esecuzione di una fra \func{unlink}, \func{rename}
+                         (su un'altra directory), \func{rmdir}.\\
+    \const{DN\_RENAME} & È stato rinominato un file all'interno della
+                         directory (con \func{rename}).\\
+    \const{DN\_ATTRIB} & È stato modificato un attributo di un file con
+                         l'esecuzione di una fra \func{chown}, \func{chmod},
+                         \func{utime}.\\ 
+    \const{DN\_MULTISHOT}& richiede una notifica permanente di tutti gli
+                         eventi.\\ 
+    \hline    
+  \end{tabular}
+  \caption{Le costanti che identificano le varie classi di eventi per i quali
+    si richiede la notifica con il comando \const{F\_NOTIFY} di \func{fcntl}.} 
+  \label{tab:file_notify}
+\end{table}
+
+A meno di non impostare in maniera esplicita una notifica permanente usando
+\const{DN\_MULTISHOT}, la notifica è singola: viene cioè inviata una sola
+volta quando si verifica uno qualunque fra gli eventi per i quali la si è
+richiesta. Questo significa che un programma deve registrarsi un'altra volta se
+desidera essere notificato di ulteriori cambiamenti. Se si eseguono diverse
+chiamate con \const{F\_NOTIFY} e con valori diversi per \param{arg} questi
+ultimi si \textsl{accumulano}; cioè eventuali nuovi classi di eventi
+specificate in chiamate successive vengono aggiunte a quelle già impostate
+nelle precedenti.  Se si vuole rimuovere la notifica si deve invece
+specificare un valore nullo.
+
+\index{file!notify|)}
+
+
+
+
+
+
+
+
+
+% TODO inserire anche inotify
+
+
 
 \subsection{L'interfaccia POSIX per l'I/O asincrono}
 \label{sec:file_asyncronous_io}
@@ -554,11 +792,11 @@ usate normalmente.
 
 In generale questa interfaccia è completamente astratta e può essere
 implementata sia direttamente nel kernel, che in user space attraverso l'uso
-di thread. Al momento esiste una sola versione stabile di questa interfaccia,
-quella delle \acr{glibc}, che è realizzata completamente in user space, ed
-accessibile linkando i programmi con la libreria \file{librt}. Nei kernel
-della nuova serie è stato anche introdotta (a partire dal 2.5.32) un nuovo
-layer per l'I/O asincrono.
+di thread. Per le versioni del kernel meno recenti esiste una implementazione
+di questa interfaccia fornita delle \acr{glibc}, che è realizzata
+completamente in user space, ed è accessibile linkando i programmi con la
+libreria \file{librt}. Nelle versioni più recenti (a partire dalla 2.5.32) è
+stato introdotto direttamente nel kernel un nuovo layer per l'I/O asincrono.
 
 Lo standard prevede che tutte le operazioni di I/O asincrono siano controllate
 attraverso l'uso di una apposita struttura \struct{aiocb} (il cui nome sta per
@@ -1149,9 +1387,10 @@ tab.~\ref{tab:file_mmap_flag}.
                              vengano riportati sulla regione
                              mappata. Incompatibile con \const{MAP\_SHARED}. \\
     \const{MAP\_DENYWRITE} & In Linux viene ignorato per evitare
-                             \textit{DoS}\index{DoS} (veniva usato per
-                             segnalare che tentativi di scrittura sul file
-                             dovevano fallire con \errcode{ETXTBSY}).\\
+                             \textit{DoS}\itindex{Denial~of~Service~(DoS)}
+                             (veniva usato per segnalare che tentativi di
+                             scrittura sul file dovevano fallire con
+                             \errcode{ETXTBSY}).\\ 
     \const{MAP\_EXECUTABLE}& Ignorato. \\
     \const{MAP\_NORESERVE} & Si usa con \const{MAP\_PRIVATE}. Non riserva
                              delle pagine di swap ad uso del meccanismo del
@@ -1193,7 +1432,7 @@ tab.~\ref{tab:file_mmap_flag}.
 
 Gli effetti dell'accesso ad una zona di memoria mappata su file possono essere
 piuttosto complessi, essi si possono comprendere solo tenendo presente che
-tutto quanto è comunque basato sul basato sul meccanismo della memoria
+tutto quanto è comunque basato sul meccanismo della memoria
 virtuale.\index{memoria~virtuale} Questo comporta allora una serie di
 conseguenze. La più ovvia è che se si cerca di scrivere su una zona mappata in
 sola lettura si avrà l'emissione di un segnale di violazione di accesso
@@ -1507,7 +1746,7 @@ fig.~\ref{fig:file_mmap_layout}.
 
 Quando un processo esegue un gran numero di mappature diverse\footnote{si può
   arrivare anche a centinaia di migliaia.} per realizzare a mano una mappatura
-non-linare si avrà un accrescimento eccessivo della sua \itindex{page~table}
+non-lineare si avrà un accrescimento eccessivo della sua \itindex{page~table}
 \textit{page table}, e lo stesso accadrà per tutti gli altri processi che
 utilizzano questa tecnica. In situazioni in cui le applicazioni hanno queste
 esigenze si avranno delle prestazioni ridotte, dato che il kernel dovrà
@@ -1584,7 +1823,7 @@ mappatura vengono ``\textsl{popolate}'' in una sola volta, questo
 comportamento viene abilitato quando si usa con \func{mmap} il flag
 \const{MAP\_POPULATE}.
 
-Dato che l'uso di \const{MAP\_POPULATE} comporta dell'l'I/O su disco che può
+Dato che l'uso di \const{MAP\_POPULATE} comporta dell'I/O su disco che può
 rallentare l'esecuzione di \func{mmap} è stato introdotto anche un secondo
 flag, \const{MAP\_NONBLOCK}, che esegue un \itindex{prefaulting}
 \textit{prefaulting} più limitato in cui vengono popolate solo le pagine della
@@ -1598,8 +1837,15 @@ mappatura che gi
 % i raw device 
 %\subsection{I \textit{raw} device}
 %\label{sec:file_raw_device}
+%
+% TODO i raw device
 
 
+%\subsection{L'utilizzo delle porte di I/O}
+%\label{sec:file_io_port}
+%
+% TODO l'I/O sulle porte di I/O 
+% consultare le manpage di ioperm, iopl e outb
 
 
 \section{Il file locking}
@@ -1634,7 +1880,7 @@ La prima modalit
 sistemi unix-like è quella che viene usualmente chiamata \textit{advisory
   locking},\footnote{Stevens in \cite{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
+  \acr{glibc}; nelle pagine di manuale si parla di \textit{discrectionary file
     lock} per \func{fcntl} e di \textit{advisory locking} per \func{flock},
   mentre questo nome viene usato da Stevens per riferirsi al \textit{file
     locking} POSIX. Dato che la dizione \textit{record locking} è quantomeno
@@ -1782,13 +2028,13 @@ anche se richiesto attraverso un file descriptor, agisce sempre su un file;
 perciò le informazioni relative agli eventuali \textit{file lock} sono
 mantenute a livello di inode\index{inode},\footnote{in particolare, come
   accennato in fig.~\ref{fig:file_flock_struct}, i \textit{file lock} sono
-  mantenuti un una \textit{linked~list} di strutture \struct{file\_lock}. La
-  lista è referenziata dall'indirizzo di partenza mantenuto dal campo
-  \var{i\_flock} della struttura \struct{inode} (per le definizioni esatte si
-  faccia riferimento al file \file{fs.h} nei sorgenti del kernel).  Un bit del
-  campo \var{fl\_flags} di specifica se si tratta di un lock in semantica BSD
-  (\const{FL\_FLOCK}) o POSIX (\const{FL\_POSIX}).} \itindex{linked~list} dato
-che questo è l'unico riferimento in comune che possono avere due processi
+  mantenuti in una \itindex{linked~list} \textit{linked list} di strutture
+  \struct{file\_lock}. La lista è referenziata dall'indirizzo di partenza
+  mantenuto dal campo \var{i\_flock} della struttura \struct{inode} (per le
+  definizioni esatte si faccia riferimento al file \file{fs.h} nei sorgenti
+  del kernel).  Un bit del campo \var{fl\_flags} di specifica se si tratta di
+  un lock in semantica BSD (\const{FL\_FLOCK}) o POSIX (\const{FL\_POSIX}).}
+dato che questo è l'unico riferimento in comune che possono avere due processi
 diversi che aprono lo stesso file.
 
 \begin{figure}[htb]
@@ -2063,7 +2309,7 @@ lock relativi al file cui esso faceva riferimento, anche se questi fossero
 stati creati usando altri file descriptor che restano aperti.
 
 Dato che il controllo sull'accesso ai lock viene eseguito sulla base del
-\acr{pid} del processo, possiamo anche prendere in considerazione un'altro
+\acr{pid} del processo, possiamo anche prendere in considerazione un altro
 degli aspetti meno chiari di questa interfaccia e cioè cosa succede quando si
 richiedono dei lock su regioni che si sovrappongono fra loro all'interno
 stesso processo. Siccome il controllo, come nel caso della rimozione, si basa
@@ -2358,32 +2604,33 @@ direttamente al sistema, cos
 opportune verifiche nei processi, questo verrebbe comunque rispettato.
 
 Per poter utilizzare il \textit{mandatory locking} è stato introdotto un
-utilizzo particolare del bit \acr{sgid}. Se si ricorda quanto esposto in
-sez.~\ref{sec:file_suid_sgid}), esso viene di norma utilizzato per cambiare il
-group-ID effettivo con cui viene eseguito un programma, ed è pertanto sempre
-associato alla presenza del permesso di esecuzione per il gruppo. Impostando
-questo bit su un file senza permesso di esecuzione in un sistema che supporta
-il \textit{mandatory locking}, fa sì che quest'ultimo venga attivato per il
-file in questione. In questo modo una combinazione dei permessi
-originariamente non contemplata, in quanto senza significato, diventa
-l'indicazione della presenza o meno del \textit{mandatory
+utilizzo particolare del bit \itindex{sgid~bit} \acr{sgid}. Se si ricorda
+quanto esposto in sez.~\ref{sec:file_suid_sgid}), esso viene di norma
+utilizzato per cambiare il group-ID effettivo con cui viene eseguito un
+programma, ed è pertanto sempre associato alla presenza del permesso di
+esecuzione per il gruppo. Impostando questo bit su un file senza permesso di
+esecuzione in un sistema che supporta il \textit{mandatory locking}, fa sì che
+quest'ultimo venga attivato per il file in questione. In questo modo una
+combinazione dei permessi originariamente non contemplata, in quanto senza
+significato, diventa l'indicazione della presenza o meno del \textit{mandatory
   locking}.\footnote{un lettore attento potrebbe ricordare quanto detto in
-  sez.~\ref{sec:file_chmod} e cioè che il bit \acr{sgid} viene cancellato (come
-  misura di sicurezza) quando di scrive su un file, questo non vale quando
-  esso viene utilizzato per attivare il \textit{mandatory locking}.}
+  sez.~\ref{sec:file_chmod} e cioè che il bit \acr{sgid} viene cancellato
+  (come misura di sicurezza) quando di scrive su un file, questo non vale
+  quando esso viene utilizzato per attivare il \textit{mandatory locking}.}
 
 L'uso del \textit{mandatory locking} presenta vari aspetti delicati, dato che
 neanche root può passare sopra ad un lock; pertanto un processo che blocchi un
 file cruciale può renderlo completamente inaccessibile, rendendo completamente
 inutilizzabile il sistema\footnote{il problema si potrebbe risolvere
-  rimuovendo il bit \acr{sgid}, ma non è detto che sia così facile fare questa
-  operazione con un sistema bloccato.} inoltre con il \textit{mandatory
-  locking} si può bloccare completamente un server NFS richiedendo una lettura
-su un file su cui è attivo un lock. Per questo motivo l'abilitazione del
-mandatory locking è di norma disabilitata, e deve essere attivata filesystem
-per filesystem in fase di montaggio (specificando l'apposita opzione di
-\func{mount} riportata in tab.~\ref{tab:sys_mount_flags}, o con l'opzione
-\cmd{mand} per il comando).
+  rimuovendo il bit \itindex{sgid~bit} \acr{sgid}, ma non è detto che sia così
+  facile fare questa operazione con un sistema bloccato.} inoltre con il
+\textit{mandatory locking} si può bloccare completamente un server NFS
+richiedendo una lettura su un file su cui è attivo un lock. Per questo motivo
+l'abilitazione del mandatory locking è di norma disabilitata, e deve essere
+attivata filesystem per filesystem in fase di montaggio (specificando
+l'apposita opzione di \func{mount} riportata in
+tab.~\ref{tab:sys_mount_flags}, o con l'opzione \code{-o mand} per il comando
+omonimo).
 
 Si tenga presente inoltre che il \textit{mandatory locking} funziona solo
 sull'interfaccia POSIX di \func{fcntl}. Questo ha due conseguenze: che non si