X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=fileadv.tex;h=6c2bfccc4cb177bc1309572285b2c380b871e32b;hp=2f9e795232e9c9d9489dcabb63887cd080f3b3cb;hb=eb9d45f3cc5cfc16b8c478d232080873a202af1c;hpb=7c1960b6884660ec0eeae24dc0f31a8283ac89aa diff --git a/fileadv.tex b/fileadv.tex index 2f9e795..6c2bfcc 100644 --- a/fileadv.tex +++ b/fileadv.tex @@ -1309,10 +1309,10 @@ modifiche con una qualunque delle modalit illustrate in sez.~\ref{sec:file_multiplexing}. Infine l'interfaccia di \textit{inotify} consente di mettere sotto -osservazione, oltre che una directory anche singoli file. Una volta creata la -coda di notifica si devono definire gli eventi da tenere sotto osservazione; -questo viene fatto attraverso una \textsl{lista di osservazione} (o -\textit{watch list}) che è associata alla coda. Per gestire la lista di +osservazione, oltre che una directory, anche singoli file. Una volta creata +la coda di notifica si devono definire gli eventi da tenere sotto +osservazione; questo viene fatto attraverso una \textsl{lista di osservazione} +(o \textit{watch list}) che è associata alla coda. Per gestire la lista di osservazione l'interfaccia fornisce due funzioni, la prima di queste è \funcd{inotify\_add\_watch}, il cui prototipo è: \begin{prototype}{sys/inotify.h} @@ -1325,7 +1325,7 @@ osservazione l'interfaccia fornisce due funzioni, la prima di queste \begin{errlist} \item[\errcode{EACCESS}] non si ha accesso in lettura al file indicato. \item[\errcode{EINVAL}] \param{mask} non contiene eventi legali o \param{fd} - non è un filesystem di \textit{inotify}. + non è un file descriptor di \textit{inotify}. \item[\errcode{ENOSPC}] si è raggiunto il numero massimo di voci di osservazione o il kernel non ha potuto allocare una risorsa necessaria. \end{errlist} @@ -1383,7 +1383,7 @@ flag della prima parte. \const{IN\_DELETE\_SELF} & & È stato cancellato il file (o la directory) sotto osservazione.\\ \const{IN\_MODIFY} &$\bullet$& È stato modificato il file.\\ - \const{IN\_MOVE\_SELF} & & è stato rinominato il file (o la + \const{IN\_MOVE\_SELF} & & È stato rinominato il file (o la directory) sotto osservazione.\\ \const{IN\_MOVED\_FROM} &$\bullet$& Un file è stato spostato fuori dalla directory sotto osservazione.\\ @@ -1468,12 +1468,14 @@ automaticamente rimosso dalla lista di osservazione e nessun ulteriore evento sarà più notificato. In caso di successo \func{inotify\_add\_watch} ritorna un intero positivo, -detto \textit{watch descriptor}; è tramite questo valore che si identifica -univocamente un \textsl{osservatore} su una coda di notifica, sia per quanto -riguarda i risultati restituiti da \textit{inotify}, che per quanto riguarda -la eventuale rimozione dello stesso; la seconda funzione per la gestione delle -liste di osservazione è infatti \funcd{inotify\_rm\_watch}, che permette di -rimuovere un \textsl{osservatore}; il suo prototipo è: +detto \textit{watch descriptor}, che identifica univocamente un +\textsl{osservatore} su una coda di notifica; esso viene usato per farvi +riferimento sia riguardo i risultati restituiti da \textit{inotify}, che per +la eventuale rimozione dello stesso. + +La seconda funzione per la gestione delle code di notifica, che permette di +rimuovere un \textsl{osservatore}, è \funcd{inotify\_rm\_watch}, ed il suo +prototipo è: \begin{prototype}{sys/inotify.h} {int inotify\_rm\_watch(int fd, uint32\_t wd)} @@ -1494,17 +1496,23 @@ La funzione rimuove dalla coda di notifica identificata dall'argomento \param{fd} l'osservatore identificato dal \textit{watch descriptor} \param{wd};\footnote{ovviamente deve essere usato per questo argomento un valore ritornato da \func{inotify\_add\_watch}, altrimenti si avrà un errore - di \errval{EINVAL}.} inoltre, contemporaneamente alla rimozione -dell'osservatore, sulla coda di notifica verrà generato un evento di tipo -\const{IN\_IGNORED} (vedi tab.~\ref{tab:inotify_read_event_flag}). - - -Oltre che per la rimozione, il \textit{watch descriptor} viene usato anche per -identificare l'evento a cui si fa riferimento nella lista dei risultati -restituiti da \textit{inotify}; questi ultimi infatti vengono notificati alle -applicazioni che usano l'interfaccia di \textit{inotify} come dati presenti in -lettura su file descriptor creato con \func{inotify\_init}. - + di \errval{EINVAL}.} in caso di successo della rimozione, contemporaneamente +alla cancellazione dell'osservatore, sulla coda di notifica verrà generato un +evento di tipo \const{IN\_IGNORED} (vedi +tab.~\ref{tab:inotify_read_event_flag}). Si tenga presente che se un file +viene cancellato o un filesystem viene smontato i relativi osservatori vengono +rimossi automaticamente e non è necessario utilizzare +\func{inotify\_rm\_watch}. + + +Come accennato l'interfaccia di \textit{inotify} prevede che gli eventi siano +notificati come dati presenti in lettura sul file descriptor associato alla +coda di notifica. Una applicazione pertanto dovrà leggere i dati da detto file +con una \func{read}, che ritornerà sul buffer i dati presenti nella forma di +una o più strutture di tipo \struct{inotify\_event} (la cui definizione è +riportata in fig.~\ref{fig:inotify_event}). Qualora non siano presenti dati la +\func{read} si bloccherà (a meno di non aver impostato il file descriptor in +modalità non bloccante) fino all'arrivo di almeno un evento. \begin{figure}[!htb] \footnotesize \centering @@ -1512,24 +1520,33 @@ lettura su file descriptor creato con \func{inotify\_init}. \includestruct{listati/inotify_event.h} \end{minipage} \normalsize - \caption{La struttura \structd{inotify\_event}.} + \caption{La struttura \structd{inotify\_event} usata dall'interfaccia di + \textit{inotify} per riportare gli eventi.} \label{fig:inotify_event} \end{figure} - -Inoltre l'interfaccia di \textit{inotify} permette di conoscere, come avviene -per i file descriptor associati ai socket (si veda al proposito quanto -trattato in sez.~\ref{sec:sock_ioctl_IP}) il numero di byte disponibili in -lettura sul nostro file descriptor, utilizzando su di esso l'operazione -\const{FIONREAD} con \func{ioctl}.\footnote{questa è una delle operazioni - speciali (che abbiamo visto in sez.~\ref{sec:file_ioctl}) che nel caso è - disponibile solo per i socket e per i file descriptor creati con - \func{inotify\_init}.} Questo consente anche di ottenere rapidamente il -numero di file che sono cambiati. - - - - +Una ulteriore caratteristica dell'interfaccia di \textit{inotify} è che essa +permette di ottenere con \func{ioctl}, come per i file descriptor associati ai +socket (si veda sez.~\ref{sec:sock_ioctl_IP}) il numero di byte disponibili in +lettura sul file descriptor, utilizzando su di esso l'operazione +\const{FIONREAD}.\footnote{questa è una delle operazioni speciali per i file + (vedi sez.~\ref{sec:file_ioctl}), che è disponibile solo per i socket e per + i file descriptor creati con \func{inotify\_init}.} Si può così utilizzare +questa operazione, oltre che per predisporre una operazione di lettura con un +buffer di dimensioni adeguate, anche per ottenere rapidamente il numero di +file che sono cambiati. + +Una volta effettuata la lettura con \func{read} a ciascun evento sarà +associata una struttura \struct{inotify\_event} contenente i rispettivi dati. +Per identificare a quale file o directory l'evento corrisponde viene +restituito nel campo \var{wd} il \textit{watch descriptor} con cui il relativo +osservatore è stato registrato. Il campo \var{mask} contiene invece una +maschera di bit che identifica il tipo di evento verificatosi; in essa +compariranno sia i bit elencati nella prima parte di +tab.~\ref{tab:inotify_event_watch}, che gli eventuali valori +aggiuntivi\footnote{questi compaiono solo nel campo \var{maks} di + \struct{inotify\_event}, e non utilizzabili in fase di registrazione + dell'osservatore.} di tab.~\ref{tab:inotify_read_event_flag}. \begin{table}[htb] \centering @@ -1539,17 +1556,56 @@ numero di file che sono cambiati. \textbf{Flag} & \textbf{Significato} \\ \hline \hline - \const{IN\_IGNORED} & .\\ - \const{IN\_ISDIR} & .\\ - \const{IN\_Q\_OVERFLOW}& .\\ - \const{IN\_UNMOUNT} & .\\ + \const{IN\_IGNORED} & L'osservatore è stato rimosso, sia in maniera + esplicita con l'uso di \func{inotify\_rm\_watch}, + che in maniera implicita per la rimozione + dell'oggetto osservato o per lo smontaggio del + filesystem su cui questo si trova.\\ + \const{IN\_ISDIR} & L'evento avvenuto fa riferimento ad una directory + (consente così di distinguere, quando si pone + sotto osservazione una directory, fra gli eventi + relativi ad essa e quelli relativi ai file che + essa contiene).\\ + \const{IN\_Q\_OVERFLOW}& Si sono eccedute le dimensioni della coda degli + eventi (\textit{overflow} della coda); in questo + caso il valore di \var{wd} è $-1$.\footnotemark\\ + \const{IN\_UNMOUNT} & Il filesystem contenente l'oggetto posto sotto + osservazione è stato smontato.\\ \hline \end{tabular} \caption{Le costanti che identificano i flag aggiuntivi usati nella maschera - binaria del campo \var{mask} di \structd{inotify\_event}.} + binaria del campo \var{mask} di \struct{inotify\_event}.} \label{tab:inotify_read_event_flag} \end{table} +\footnotetext{la coda di notifica ha una dimensione massima specificata dal + parametro di sistema \procfile{/proc/sys/fs/inotify/max\_queued\_events} che + indica il numero massimo di eventi che possono essere mantenuti sulla + stessa; quando detto valore viene ecceduto gli ulteriori eventi vengono + scartati, ma viene comunque generato un evento di tipo + \const{IN\_Q\_OVERFLOW}.} + +Il campo \var{cookie} contiene invece un intero univoco che permette di +identificare eventi correlati (per i quali avrà lo stesso valore), al momento +viene utilizzato soltanto per rilevare lo spostamento di un file, consentendo +così all'applicazione di collegare la corrispondente coppia di eventi +\const{IN\_MOVED\_TO} e \const{IN\_MOVED\_FROM}. + +Infine due campi \var{name} e \var{len} sono utilizzati soltanto quando +l'evento è relativo ad un file presente in una directory posta sotto +osservazione, in tal caso essi contengono rispettivamente il nome del file +(come pathname relativo alla directory osservata) e la relativa dimensione in +byte. Il campo \var{name} viene sempre restituito come stringa terminata da +NUL, con uno o più zeri di terminazione, a seconda di eventuali necessità di +allineamento del risultato, ed il valore di \var{len} corrisponde al totale +della dimensione di \var{name}, zeri aggiuntivi compresi. Questo significa che +le dimensioni di ciascun evento di \textit{inotify} saranno pari al valore +\code{sizeof(\struct{inotify\_event}) + len}. + +Vediamo allora un esempio dell'uso dell'interfaccia di \textit{inotify} con un +semplice programma che permette di mettere sotto osservazione un file o una +directory. + % TODO inserire anche inotify, vedi http://www.linuxjournal.com/article/8478 @@ -2713,7 +2769,7 @@ il loro accesso ai dati dei file. % TODO documentare \func{posix\_fadvise} % vedi http://insights.oetiker.ch/linux/fadvise.html % questo tread? http://www.ussg.iu.edu/hypermail/linux/kernel/0703.1/0032.html -% TODO documentare \func{fallocate} +% TODO documentare \func{fallocate}, introdotta con il 2.6.23 % vedi http://lwn.net/Articles/226710/ e http://lwn.net/Articles/240571/