X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=fileadv.tex;h=b4c7d0012595d51cd65f87f041d978b6a19b3875;hp=58c7ee6bed6825316e9765751e1cd1ca6512a516;hb=ff76d56c6a2c280cbe4f153173488871d7b12336;hpb=cba678a2d4cdb82e16477812b1bef3e89cc1a7dd diff --git a/fileadv.tex b/fileadv.tex index 58c7ee6..b4c7d00 100644 --- a/fileadv.tex +++ b/fileadv.tex @@ -1,6 +1,6 @@ %% fileadv.tex %% -%% Copyright (C) 2000-2006 Simone Piccardi. Permission is granted to +%% Copyright (C) 2000-2007 Simone Piccardi. Permission is granted to %% copy, distribute and/or modify this document under the terms of the GNU Free %% Documentation License, Version 1.1 or any later version published by the %% Free Software Foundation; with the Invariant Sections being "Un preambolo", @@ -50,12 +50,12 @@ pi possibile prevedere quando questo può avvenire (il caso più classico è quello 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 +descriptor che non è ``\textsl{pronto}'', quando ce ne potrebbe essere 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 -potrebbe addirittura arrivare ad un \textit{deadlock}\itindex{deadlock}. +potrebbe addirittura arrivare ad un \itindex{deadlock} \textit{deadlock}. Abbiamo già accennato in sez.~\ref{sec:file_open} che è possibile prevenire questo tipo di comportamento delle funzioni di I/O aprendo un file in @@ -65,7 +65,7 @@ eseguite sul file che si sarebbero bloccate, ritornano immediatamente, restituendo l'errore \errcode{EAGAIN}. L'utilizzo di questa modalità di I/O permette di risolvere il problema controllando a turno i vari file descriptor, in un ciclo in cui si ripete l'accesso fintanto che esso non viene garantito. -Ovviamente questa tecnica, detta \textit{polling}\itindex{polling}, è +Ovviamente questa tecnica, detta \itindex{polling} \textit{polling}, è estremamente inefficiente: si tiene costantemente impiegata la CPU solo per eseguire in continuazione delle system call che nella gran parte dei casi falliranno. @@ -127,10 +127,10 @@ degli insiemi specificati (\param{readfds}, \param{writefds} e Per specificare quali file descriptor si intende \textsl{selezionare}, la funzione usa un particolare oggetto, il \textit{file descriptor set}, identificato dal tipo \type{fd\_set}, che serve ad identificare un insieme di -file descriptor, in maniera analoga a come un -\itindex{signal~set}\textit{signal set} (vedi sez.~\ref{sec:sig_sigset}) -identifica un insieme di segnali. Per la manipolazione di questi \textit{file - descriptor set} si possono usare delle opportune macro di preprocessore: +file descriptor, in maniera analoga a come un \itindex{signal~set} +\textit{signal set} (vedi sez.~\ref{sec:sig_sigset}) identifica un insieme di +segnali. Per la manipolazione di questi \textit{file descriptor set} si +possono usare delle opportune macro di preprocessore: \begin{functions} \headdecl{sys/time.h} \headdecl{sys/types.h} @@ -185,7 +185,6 @@ ritorni; se impostato a \val{NULL} la funzione attende indefinitamente. Si pu specificare anche un tempo nullo (cioè una struttura \struct{timeval} con i campi impostati a zero), qualora si voglia semplicemente controllare lo stato corrente dei file descriptor. -\itindend{file~descriptor~set} La funzione restituisce il numero di file descriptor pronti,\footnote{questo è il comportamento previsto dallo standard, ma la standardizzazione della @@ -198,6 +197,8 @@ modificati. In caso di errore la funzione restituisce -1, ed i valori dei tre insiemi sono indefiniti e non si può fare nessun affidamento sul loro contenuto. +\itindend{file~descriptor~set} + In Linux \func{select} modifica anche il valore di \param{timeout}, impostandolo al tempo restante in caso di interruzione prematura; questo è utile quando la funzione viene interrotta da un segnale, in tal caso infatti @@ -291,25 +292,26 @@ interrotta, e la ricezione del segnale non sar Per questo è stata introdotta \func{pselect} che attraverso l'argomento \param{sigmask} permette di riabilitare la ricezione il segnale -contestualmente all'esecuzione della funzione,\footnote{in Linux però non è - presente la relativa system call, e la funzione è implementata nelle - \acr{glibc} attraverso \func{select} (vedi \texttt{man select\_tut}) per cui - la possibilità di \itindex{race~condition}\textit{race condition} permane; - esiste però una soluzione, chiamata \itindex{self-pipe trick} - \textit{self-pipe trick}, che consiste nell'aprire una pipe (vedi - sez.~\ref{sec:ipc_pipes}) ed usare \func{select} sul capo in lettura della - stessa, e indicare l'arrivo di un segnale scrivendo sul capo in scrittura - all'interno del manipolatore; in questo modo anche se il segnale va perso - prima della chiamata di \func{select} questa lo riconoscerà comunque dalla - presenza di dati sulla pipe.} ribloccandolo non appena essa ritorna, così -che il precedente codice potrebbe essere riscritto nel seguente modo: +contestualmente all'esecuzione della funzione,\footnote{in Linux però, fino al + kernel 2.6.16, non è presente la relativa system call, e la funzione è + implementata nelle \acr{glibc} attraverso \func{select} (vedi \texttt{man + select\_tut}) per cui la possibilità di \itindex{race~condition} + \textit{race condition} permane; esiste però una soluzione, chiamata + \itindex{self-pipe trick} \textit{self-pipe trick}, che consiste nell'aprire + una pipe (vedi sez.~\ref{sec:ipc_pipes}) ed usare \func{select} sul capo in + lettura della stessa, e indicare l'arrivo di un segnale scrivendo sul capo + in scrittura all'interno del gestore dello stesso; in questo modo anche se + il segnale va perso prima della chiamata di \func{select} questa lo + riconoscerà comunque dalla presenza di dati sulla pipe.} ribloccandolo non +appena essa ritorna, così che il precedente codice potrebbe essere riscritto +nel seguente modo: \includecodesnip{listati/pselect_norace.c} in questo caso utilizzando \var{oldmask} durante l'esecuzione di \func{pselect} la ricezione del segnale sarà abilitata, ed in caso di interruzione si potranno eseguire le relative operazioni. % TODO pselect è stata introdotta nel kernel 2.6.16 (o 15 o 17?) insieme a -% ppoll mettere e verificare +% ppoll mettere e verificare, vedi articolo LWN http://lwn.net/Articles/176750/ \subsection{La funzione \func{poll}} @@ -570,7 +572,7 @@ 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}. +\itindex{polling} \textit{polling}. Queste nuove funzionalità sono delle estensioni specifiche, non standardizzate, che sono disponibili soltanto su Linux (anche se altri kernel @@ -595,11 +597,10 @@ il segnale \const{SIGIO}, ma questo segnale pu 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}. + real-time.} e si è installato il gestore 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 @@ -688,7 +689,7 @@ kernel \textit{lease breaker} rimaste bloccate proseguono automaticamente. -\index{file!notify|(} +\index{file!dnotify|(} 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 @@ -696,12 +697,13 @@ 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}. +Per risolvere questo problema è stata allora creata un'altra interfaccia, +chiamata \textit{dnotify}, 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 +gestore il file descriptor che è stato modificato dal contenuto della +struttura \struct{siginfo\_t}. \index{file!lease|)} @@ -758,18 +760,13 @@ ultimi si \textsl{accumulano}; cio 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|)} - - - - - +\index{file!dnotify|)} - -% TODO inserire anche inotify +\index{file!inotify|)} +% TODO inserire anche inotify, vedi http://www.linuxjournal.com/article/8478 +\index{file!inotify|(} @@ -786,7 +783,7 @@ effettuare in contemporanea le operazioni di calcolo e quelle di I/O. Benché la modalità di apertura asincrona di un file possa risultare utile in varie occasioni (in particolar modo con i socket e gli altri file per i quali -le funzioni di I/O sono \index{system~call~lente}system call lente), essa è +le funzioni di I/O sono \index{system~call~lente} system call lente), essa è comunque limitata alla notifica della disponibilità del file descriptor per le operazioni di I/O, e non ad uno svolgimento asincrono delle medesime. Lo standard POSIX.1b definisce una interfaccia apposita per l'I/O asincrono vero @@ -1224,7 +1221,7 @@ si sono specificati nel vettore \param{vector}. Una modalità alternativa di I/O, che usa una interfaccia completamente diversa rispetto a quella classica vista in cap.~\ref{cha:file_unix_interface}, è il cosiddetto \textit{memory-mapped I/O}, che, attraverso il meccanismo della -\textsl{paginazione}\index{paginazione} usato dalla memoria virtuale (vedi +\textsl{paginazione} \index{paginazione} usato dalla memoria virtuale (vedi sez.~\ref{sec:proc_mem_gen}), permette di \textsl{mappare} il contenuto di un file in una sezione dello spazio di indirizzi del processo. @@ -1232,7 +1229,7 @@ Il meccanismo file viene \textsl{mappata} direttamente nello spazio degli indirizzi del programma. Tutte le operazioni di lettura e scrittura su variabili contenute in questa zona di memoria verranno eseguite leggendo e scrivendo dal contenuto -del file attraverso il sistema della memoria virtuale\index{memoria~virtuale} +del file attraverso il sistema della memoria virtuale \index{memoria~virtuale} che in maniera analoga a quanto avviene per le pagine che vengono salvate e rilette nella swap, si incaricherà di sincronizzare il contenuto di quel segmento di memoria con quello del file mappato su di esso. Per questo motivo @@ -1255,10 +1252,10 @@ interfaccia di caricare in memoria solo le parti del file che sono effettivamente usate ad un dato istante. -Infatti, dato che l'accesso è fatto direttamente attraverso la memoria -virtuale,\index{memoria~virtuale} la sezione di memoria mappata su cui si -opera sarà a sua volta letta o scritta sul file una pagina alla volta e solo -per le parti effettivamente usate, il tutto in maniera completamente +Infatti, dato che l'accesso è fatto direttamente attraverso la +\index{memoria~virtuale} memoria virtuale, la sezione di memoria mappata su +cui si opera sarà a sua volta letta o scritta sul file una pagina alla volta e +solo per le parti effettivamente usate, il tutto in maniera completamente trasparente al processo; l'accesso alle pagine non ancora caricate avverrà allo stesso modo con cui vengono caricate in memoria le pagine che sono state salvate sullo swap. @@ -1344,7 +1341,7 @@ multiplo della dimensione di una pagina di memoria. Il valore dell'argomento \param{prot} indica la protezione\footnote{in Linux la memoria reale è divisa in pagine: ogni processo vede la sua memoria attraverso uno o più segmenti lineari di memoria virtuale. Per ciascuno di - questi segmenti il kernel mantiene nella \itindex{page~table}\textit{page + questi segmenti il kernel mantiene nella \itindex{page~table} \textit{page table} la mappatura sulle pagine di memoria reale, ed le modalità di accesso (lettura, esecuzione, scrittura); una loro violazione causa quella che si chiama una \textit{segment violation}, e la relativa emissione del @@ -1386,20 +1383,20 @@ tab.~\ref{tab:file_mmap_flag}. privata cui solo il processo chiamante ha accesso. Le modifiche sono mantenute attraverso il meccanismo del \textit{copy on - write}\itindex{copy~on~write} e + write} \itindex{copy~on~write} e salvate su swap in caso di necessità. Non è specificato se i cambiamenti sul file originale vengano riportati sulla regione mappata. Incompatibile con \const{MAP\_SHARED}. \\ \const{MAP\_DENYWRITE} & In Linux viene ignorato per evitare - \textit{DoS}\itindex{Denial~of~Service~(DoS)} + \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 - \textit{copy on write}\itindex{copy~on~write} + \textit{copy on write} \itindex{copy~on~write} per mantenere le modifiche fatte alla regione mappata, in questo caso dopo una scrittura, se non c'è più @@ -1437,21 +1434,21 @@ 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 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 -(\const{SIGSEGV}), dato che i permessi sul segmento di memoria relativo non -consentono questo tipo di accesso. +tutto quanto è comunque basato sul meccanismo della \index{memoria~virtuale} +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 (\const{SIGSEGV}), +dato che i permessi sul segmento di memoria relativo non consentono questo +tipo di accesso. È invece assai diversa la questione relativa agli accessi al di fuori della regione di cui si è richiesta la mappatura. A prima vista infatti si potrebbe ritenere che anch'essi debbano generare un segnale di violazione di accesso; questo però non tiene conto del fatto che, essendo basata sul meccanismo della -paginazione\index{paginazione}, la mappatura in memoria non può che essere +paginazione \index{paginazione}, la mappatura in memoria non può che essere eseguita su un segmento di dimensioni rigorosamente multiple di quelle di una pagina, ed in generale queste potranno non corrispondere alle dimensioni -effettive del file o della sezione che si vuole mappare. +effettive del file o della sezione che si vuole mappare. \footnotetext[20]{Dato che tutti faranno riferimento alle stesse pagine di memoria.} @@ -1838,6 +1835,19 @@ mappatura che gi \itindend{memory~mapping} +\subsection{L'I/O diretto fra file descriptor con \func{sendfile}} +\label{sec:file_sendfile} + +Uno dei problemi + +NdA è da finire, sul perché non è abilitata fra file vedi: + +\href{http://www.cs.helsinki.fi/linux/linux-kernel/2001-03/0200.html} +{\texttt{http://www.cs.helsinki.fi/linux/linux-kernel/2001-03/0200.html}} +% TODO documentare la funzione sendfile + + + % i raw device %\subsection{I \textit{raw} device} %\label{sec:file_raw_device} @@ -1851,11 +1861,6 @@ mappatura che gi % TODO l'I/O sulle porte di I/O % consultare le manpage di ioperm, iopl e outb -%\subsection{L'I/O diretto fra file descriptor con \func{sendfile}} -%\label{sec:file_sendfile} -% -% TODO documentare la funzione sendfile -% consultare la manpage di sendfile @@ -1879,7 +1884,7 @@ in cui diversi processi scrivono, mescolando in maniera imprevedibile il loro output sul file. In tutti questi casi il \textit{file locking} è la tecnica che permette di -evitare le \textit{race condition}\itindex{race~condition}, attraverso una +evitare le \textit{race condition} \itindex{race~condition}, attraverso una serie di funzioni che permettono di bloccare l'accesso al file da parte di altri processi, così da evitare le sovrapposizioni, e garantire la atomicità delle operazioni di scrittura. @@ -2067,38 +2072,42 @@ piuttosto degli ulteriori riferimenti allo stesso. Questo viene realizzato dal kernel secondo lo schema di fig.~\ref{fig:file_flock_struct}, associando ad ogni nuovo \textit{file lock} un puntatore\footnote{il puntatore è mantenuto nel campo \var{fl\_file} di \struct{file\_lock}, e viene utilizzato solo per - i lock creati con la semantica BSD.} alla voce nella \textit{file table} da -cui si è richiesto il lock, che così ne identifica il titolare. + i lock creati con la semantica BSD.} alla voce nella \itindex{file~table} +\textit{file table} da cui si è richiesto il lock, che così ne identifica il +titolare. Questa struttura prevede che, quando si richiede la rimozione di un file lock, il kernel acconsenta solo se la richiesta proviene da un file descriptor che -fa riferimento ad una voce nella file table corrispondente a quella registrata -nel lock. Allora se ricordiamo quanto visto in sez.~\ref{sec:file_dup} e -sez.~\ref{sec:file_sharing}, e cioè che i file descriptor duplicati e quelli -ereditati in un processo figlio puntano sempre alla stessa voce nella file -table, si può capire immediatamente quali sono le conseguenze nei confronti -delle funzioni \func{dup} e \func{fork}. +fa riferimento ad una voce nella \itindex{file~table} \textit{file table} +corrispondente a quella registrata nel lock. Allora se ricordiamo quanto +visto in sez.~\ref{sec:file_dup} e sez.~\ref{sec:file_sharing}, e cioè che i +file descriptor duplicati e quelli ereditati in un processo figlio puntano +sempre alla stessa voce nella \itindex{file~table} \textit{file table}, si può +capire immediatamente quali sono le conseguenze nei confronti delle funzioni +\func{dup} e \func{fork}. Sarà così possibile rimuovere un file lock attraverso uno qualunque dei file -descriptor che fanno riferimento alla stessa voce nella file table, anche se -questo è diverso da quello con cui lo si è creato,\footnote{attenzione, questo - non vale se il file descriptor fa riferimento allo stesso file, ma - attraverso una voce diversa della file table, come accade tutte le volte che - si apre più volte lo stesso file.} o se si esegue la rimozione in un -processo figlio; inoltre una volta tolto un file lock, la rimozione avrà -effetto su tutti i file descriptor che condividono la stessa voce nella file -table, e quindi, nel caso di file descriptor ereditati attraverso una -\func{fork}, anche su processi diversi. +descriptor che fanno riferimento alla stessa voce nella \itindex{file~table} +\textit{file table}, anche se questo è diverso da quello con cui lo si è +creato,\footnote{attenzione, questo non vale se il file descriptor fa + riferimento allo stesso file, ma attraverso una voce diversa della + \itindex{file~table} \textit{file table}, come accade tutte le volte che si + apre più volte lo stesso file.} o se si esegue la rimozione in un processo +figlio; inoltre una volta tolto un file lock, la rimozione avrà effetto su +tutti i file descriptor che condividono la stessa voce nella +\itindex{file~table} \textit{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, 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; e questo avverrà -solo quando tutti i file descriptor che fanno riferimento alla stessa voce -sono stati chiusi. Quindi, nel caso ci siano duplicati o processi figli che -mantengono ancora aperto un file descriptor, il lock non viene rilasciato. +che non viene rilasciata la relativa voce nella \itindex{file~table} +\textit{file table}; e questo avverrà solo quando tutti i file descriptor che +fanno riferimento alla stessa voce sono stati chiusi. Quindi, nel caso ci +siano duplicati o processi figli che mantengono ancora aperto un file +descriptor, il lock non viene rilasciato. Si tenga presente infine 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 @@ -2130,7 +2139,7 @@ essa viene usata solo secondo il prototipo: \item[\errcode{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}\itindex{deadlock}. Non è garantito che il sistema + \itindex{deadlock} \textit{deadlock}. Non è garantito che il sistema riconosca sempre questa situazione. \item[\errcode{EINTR}] La funzione è stata interrotta da un segnale prima di poter acquisire un lock. @@ -2250,7 +2259,7 @@ stato effettivamente acquisito. \begin{figure}[htb] \centering \includegraphics[width=9cm]{img/file_lock_dead} - \caption{Schema di una situazione di \textit{deadlock}\itindex{deadlock}.} + \caption{Schema di una situazione di \itindex{deadlock} \textit{deadlock}.} \label{fig:file_flock_dead} \end{figure} @@ -2262,11 +2271,12 @@ un lock sulla regione 2 che non pu del processo 2; il processo 1 si bloccherà fintanto che il processo 2 non rilasci il blocco. Ma cosa accade se il processo 2 nel frattempo tenta a sua volta di ottenere un lock sulla regione A? Questa è una tipica situazione che -porta ad un \textit{deadlock}\itindex{deadlock}, dato che a quel punto anche +porta ad un \itindex{deadlock} \textit{deadlock}, dato che a quel punto anche il processo 2 si bloccherebbe, e niente potrebbe sbloccare l'altro processo. Per questo motivo il kernel si incarica di rilevare situazioni di questo tipo, ed impedirle restituendo un errore di \errcode{EDEADLK} alla funzione che -cerca di acquisire un lock che porterebbe ad un \textit{deadlock}. +cerca di acquisire un lock che porterebbe ad un \itindex{deadlock} +\textit{deadlock}. \begin{figure}[!bht] \centering \includegraphics[width=13cm]{img/file_posix_lock} @@ -2288,9 +2298,10 @@ di fig.~\ref{fig:file_flock_struct}:\footnote{in questo caso nella figura si 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 \const{FL\_POSIX} ed il campo \var{fl\_file} non viene - usato.} il lock è sempre associato all'inode\index{inode}, solo che in + usato.} il lock è sempre associato \index{inode} 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. +voce nella \itindex{file~table} \textit{file table}, ma con il valore del +\acr{pid} del processo. Quando si richiede un lock il kernel effettua una scansione di tutti i lock presenti sul file\footnote{scandisce cioè la \itindex{linked~list} @@ -2620,7 +2631,7 @@ opportune verifiche nei processi, questo verrebbe comunque rispettato. Per poter utilizzare il \textit{mandatory locking} è stato introdotto un 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 +quanto esposto in sez.~\ref{sec:file_special_perm}), 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 @@ -2629,9 +2640,10 @@ 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_perm_management} 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 l'amministratore può passare sopra ad un lock; pertanto un processo @@ -2696,17 +2708,12 @@ implementativa\footnote{per i dettagli si possono leggere le note relative soltanto quando si chiama \func{mmap} con l'opzione \const{MAP\_SHARED} (nel qual caso la funzione fallisce con il solito \errcode{EAGAIN}) che comporta la possibilità di modificare il file. -\index{file!locking|)} -\itindend{mandatory~locking|(} +\index{file!locking|)} +\itindend{mandatory~locking|(} -%%% Local Variables: -%%% mode: latex -%%% TeX-master: "gapil" -%%% End: - % LocalWords: dell'I locking multiplexing cap dell' sez system call socket BSD % LocalWords: descriptor client deadlock NONBLOCK EAGAIN polling select kernel % LocalWords: pselect like sys unistd int fd readfds writefds exceptfds struct @@ -2741,4 +2748,10 @@ possibilit % LocalWords: flock shared exclusive operation dup inode linked NFS cmd ENOLCK % LocalWords: EDEADLK whence SEEK CUR type pid GETLK SETLK SETLKW all'inode HP % LocalWords: switch bsd lockf mandatory SVr sgid group root mount mand TRUNC -% LocalWords: SVID UX Documentation +% LocalWords: SVID UX Documentation sendfile + + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "gapil" +%%% End: