%% fileadv.tex
%%
-%% Copyright (C) 2000-2011 Simone Piccardi. Permission is granted to
+%% Copyright (C) 2000-2012 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",
inode\itindex{inode},\footnote{in particolare, come accennato in
fig.~\ref{fig:file_flock_struct}, i \textit{file lock} sono 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.
+ \kstruct{file\_lock}. La lista è referenziata dall'indirizzo di partenza
+ mantenuto dal campo \var{i\_flock} della struttura \kstruct{inode} (per le
+ definizioni esatte si faccia riferimento al file \file{include/linux/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]
\centering
quando, come nelle versioni più recenti del kernel, questo limite è stato
rimosso, esso indica le dimensioni massime dei numeri usati nei \textit{file
descriptor set}.\footnote{il suo valore, secondo lo standard POSIX
- 1003.1-2001, è definito in \file{sys/select.h}, ed è pari a 1024.}
+ 1003.1-2001, è definito in \headfile{sys/select.h}, ed è pari a 1024.}
Si tenga presente che i \textit{file descriptor set} devono sempre essere
inizializzati con \macro{FD\_ZERO}; passare a \func{select} un valore non
multiplexing}, introdotto solo con le ultime revisioni dello standard (POSIX
1003.1g-2000 e POSIX 1003.1-2001). La scelta è stata quella di seguire
l'interfaccia creata da BSD, ma prevede che tutte le funzioni ad esso relative
-vengano dichiarate nell'header \file{sys/select.h}, che sostituisce i
+vengano dichiarate nell'header \headfile{sys/select.h}, che sostituisce i
precedenti, ed inoltre aggiunge a \func{select} una nuova funzione
\funcd{pselect},\footnote{il supporto per lo standard POSIX 1003.1-2001, ed
- l'header \file{sys/select.h}, compaiono in Linux a partire dalle \acr{glibc}
- 2.1. Le \acr{libc4} e \acr{libc5} non contengono questo header, le
- \acr{glibc} 2.0 contengono una definizione sbagliata di \func{psignal},
+ l'header \headfile{sys/select.h}, compaiono in Linux a partire dalle
+ \acr{glibc} 2.1. Le \acr{libc4} e \acr{libc5} non contengono questo header,
+ le \acr{glibc} 2.0 contengono una definizione sbagliata di \func{psignal},
senza l'argomento \param{sigmask}, la definizione corretta è presente dalle
\acr{glibc} 2.1-2.2.1 se si è definito \macro{\_GNU\_SOURCE} e nelle
\acr{glibc} 2.2.2-2.2.4 se si è definito \macro{\_XOPEN\_SOURCE} con valore
in stile SysV (in particolare le ultime due non vengono usate su Linux), e
sono utilizzabili soltanto qualora si sia definita la macro
\macro{\_XOPEN\_SOURCE}.\footnote{e ci si ricordi di farlo sempre in testa al
- file, definirla soltanto prima di includere \file{sys/poll.h} non è
+ file, definirla soltanto prima di includere \headfile{sys/poll.h} non è
sufficiente.}
In caso di successo funzione ritorna restituendo il numero di file (un valore
chiamate devono essere ripetute per ciascun file descriptor, incorrendo in
una perdita di prestazioni qualora il numero di file descriptor sia molto
grande; per questo è stato proposto di introdurre come estensione una
- funzione \func{epoll\_ctlv} che consenta di effettuare con una sola chiamata
+ funzione \code{epoll\_ctlv} che consenta di effettuare con una sola chiamata
le impostazioni per un blocco di file descriptor.} L'uso di
\const{EPOLL\_CTL\_MOD} consente in seguito di modificare le modalità di
osservazione di un file descriptor che sia già stato aggiunto alla lista di
osservazione.
+% TODO verificare se prima o poi epoll_ctlv verrà introdotta
+
Le impostazioni di default prevedono che la notifica degli eventi richiesti
sia effettuata in modalità \textit{level triggered}, a meno che sul file
descriptor non si sia impostata la modalità \textit{edge triggered},
Una volta completata l'inizializzazione verrà eseguito indefinitamente il
ciclo principale del programma (\texttt{\small 2--45}) che si è riportato in
fig.~\ref{fig:fiforeporter_code_body}, fintanto che questo non riceva un
-segnale di \texttt{SIGINT} (ad esempio con la pressione di \texttt{C-c}). Il
+segnale di \signal{SIGINT} (ad esempio con la pressione di \texttt{C-c}). Il
ciclo prevede che si attenda (\texttt{\small 2--3}) la presenza di un file
descriptor pronto in lettura con \func{epoll\_wait},\footnote{si ricordi che
entrambi i file descriptor \var{fifofd} e \var{sigfd} sono stati posti in
ricevuto un segnale e che il file descriptor pronto corrisponda
(\texttt{\small 6}) a \var{sigfd}. Dato che in generale si possono ricevere
anche notifiche relativi a più di un singolo segnale, si è scelto di leggere
-una struttura \const{signalfd\_siginfo} alla volta, eseguendo la lettura
+una struttura \struct{signalfd\_siginfo} alla volta, eseguendo la lettura
all'interno di un ciclo (\texttt{\small 8--24}) che prosegue fintanto che vi
siano dati da leggere.
definizione si è omessa dal codice di fig.~\ref{fig:fiforeporter_code_init}
per brevità.} ed il \textit{pid} del processo da cui lo ha ricevuto; inoltre
(\texttt{\small 21--24}) si controllerà anche se il segnale ricevuto è
-\var{SIGINT}, che si è preso come segnale da utilizzare per la terminazione
+\signal{SIGINT}, che si è preso come segnale da utilizzare per la terminazione
del programma, che verrà eseguita dopo aver rimosso il file della \textit{name
fifo}.
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}.
+definita la macro \macro{\_GNU\_SOURCE} prima di includere \headfile{fcntl.h}.
\itindbeg{file~lease}
\bodydesc{La funzione restituisce un valore positivo in caso di successo, o
$-1$ in caso di errore, nel qual caso \var{errno} assumerà uno dei valori:
\begin{errlist}
- \item[\errcode{EACCESS}] non si ha accesso in lettura al file indicato.
+ \item[\errcode{EACCES}] non si ha accesso in lettura al file indicato.
\item[\errcode{EINVAL}] \param{mask} non contiene eventi legali o \param{fd}
non è un file descriptor di \textit{inotify}.
\item[\errcode{ENOSPC}] si è raggiunto il numero massimo di voci di
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. La stringa con il
-nome del file viene restituita nella lettura subito dopo la struttura
-\struct{inotify\_event}; questo significa che le dimensioni di ciascun evento
-di \textit{inotify} saranno pari a \code{sizeof(\struct{inotify\_event}) +
- len}.
+(come \itindsub{pathname}{relativo} \textit{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. La stringa con il nome del file viene restituita nella
+lettura subito dopo la struttura \struct{inotify\_event}; questo significa che
+le dimensioni di ciascun evento di \textit{inotify} saranno pari a
+\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 uno o più file e
attraverso l'uso di una apposita struttura \struct{aiocb} (il cui nome sta per
\textit{asyncronous I/O control block}), che viene passata come argomento a
tutte le funzioni dell'interfaccia. La sua definizione, come effettuata in
-\file{aio.h}, è riportata in fig.~\ref{fig:file_aiocb}. Nello steso file è
+\headfile{aio.h}, è riportata in fig.~\ref{fig:file_aiocb}. Nello steso file è
definita la macro \macro{\_POSIX\_ASYNCHRONOUS\_IO}, che dichiara la
disponibilità dell'interfaccia per l'I/O asincrono.
di notifica non verrà invocato. Se si specifica una operazione relativa ad un
altro file descriptor il risultato è indeterminato. In caso di successo, i
possibili valori di ritorno per \func{aio\_cancel} (anch'essi definiti in
-\file{aio.h}) sono tre:
+\headfile{aio.h}) sono tre:
\begin{basedescript}{\desclabelwidth{3.0cm}}
\item[\const{AIO\_ALLDONE}] indica che le operazioni di cui si è richiesta la
cancellazione sono state già completate,
\begin{errlist}
\item[\errcode{EINVAL}] il valore di \param{addr} non è valido o non è un
multiplo di \const{PAGE\_SIZE}.
- \item[\errcode{EACCESS}] l'operazione non è consentita, ad esempio si è
+ \item[\errcode{EACCES}] l'operazione non è consentita, ad esempio si è
cercato di marcare con \const{PROT\_WRITE} un segmento di memoria cui si
ha solo accesso in lettura.
% \item[\errcode{ENOMEM}] non è stato possibile allocare le risorse
maschera binaria per i flag che controllano il comportamento della funzione.
Il solo valore utilizzato è \const{MREMAP\_MAYMOVE}\footnote{per poter
utilizzare questa costante occorre aver definito \macro{\_GNU\_SOURCE} prima
- di includere \file{sys/mman.h}.} che consente di eseguire l'espansione
+ di includere \headfile{sys/mman.h}.} che consente di eseguire l'espansione
anche quando non è possibile utilizzare il precedente indirizzo. Per questo
motivo, se si è usato questo flag, la funzione può restituire un indirizzo
della nuova zona di memoria che non è detto coincida con \param{old\_address}.
POSIX.1-2001 prevede anche che sia possibile avere un limite al numero di
elementi del vettore \param{vector}. Qualora questo sussista, esso deve essere
indicato dal valore dalla costante \const{IOV\_MAX}, definita come le altre
-costanti analoghe (vedi sez.~\ref{sec:sys_limits}) in \file{limits.h}; lo
+costanti analoghe (vedi sez.~\ref{sec:sys_limits}) in \headfile{limits.h}; lo
stesso valore deve essere ottenibile in esecuzione tramite la funzione
\func{sysconf} richiedendo l'argomento \const{\_SC\_IOV\_MAX} (vedi
sez.~\ref{sec:sys_sysconf}).
che anzi in certi casi si potevano avere anche dei peggioramenti. Questo ha
portato, per i kernel della serie 2.6,\footnote{per alcune motivazioni di
questa scelta si può fare riferimento a quanto illustrato da Linus Torvalds
- in \href{http://www.cs.helsinki.fi/linux/linux-kernel/2001-03/0200.html}
- {\textsf{http://www.cs.helsinki.fi/linux/linux-kernel/2001-03/0200.html}}.}
+ in \url{http://www.cs.helsinki.fi/linux/linux-kernel/2001-03/0200.html}.}
alla decisione di consentire l'uso della funzione soltanto quando il file da
cui si legge supporta le operazioni di \textit{memory mapping} (vale a dire
non è un socket) e quello su cui si scrive è un socket; in tutti gli altri
scopi da \func{sendfile}, quello che rende \func{splice} davvero diversa è
stata la reinterpretazione che ne è stata fatta nell'implementazione su
Linux realizzata da Jens Anxboe, concetti che sono esposti sinteticamente
- dallo stesso Linus Torvalds in \href{http://kerneltrap.org/node/6505}
- {\textsf{http://kerneltrap.org/node/6505}}.} si tratta semplicemente di una
-funzione che consente di fare in maniera del tutto generica delle operazioni
-di trasferimento di dati fra un file e un buffer gestito interamente in kernel
-space. In questo caso il cuore della funzione (e delle affini \func{vmsplice}
-e \func{tee}, che tratteremo più avanti) è appunto l'uso di un buffer in
-kernel space, e questo è anche quello che ne ha semplificato l'adozione,
-perché l'infrastruttura per la gestione di un tale buffer è presente fin dagli
-albori di Unix per la realizzazione delle \textit{pipe} (vedi
-sez.~\ref{sec:ipc_unix}). Dal punto di vista concettuale allora \func{splice}
-non è altro che una diversa interfaccia (rispetto alle \textit{pipe}) con cui
-utilizzare in user space l'oggetto ``\textsl{buffer in kernel space}''.
+ dallo stesso Linus Torvalds in \url{http://kerneltrap.org/node/6505}.} si
+tratta semplicemente di una funzione che consente di fare in maniera del tutto
+generica delle operazioni di trasferimento di dati fra un file e un buffer
+gestito interamente in kernel space. In questo caso il cuore della funzione (e
+delle affini \func{vmsplice} e \func{tee}, che tratteremo più avanti) è
+appunto l'uso di un buffer in kernel space, e questo è anche quello che ne ha
+semplificato l'adozione, perché l'infrastruttura per la gestione di un tale
+buffer è presente fin dagli albori di Unix per la realizzazione delle
+\textit{pipe} (vedi sez.~\ref{sec:ipc_unix}). Dal punto di vista concettuale
+allora \func{splice} non è altro che una diversa interfaccia (rispetto alle
+\textit{pipe}) con cui utilizzare in user space l'oggetto ``\textsl{buffer in
+ kernel space}''.
Così se per una \textit{pipe} o una \textit{fifo} il buffer viene utilizzato
come area di memoria (vedi fig.~\ref{fig:ipc_pipe_singular}) dove appoggiare i
\func{splice}, oppure nessuno dei file descriptor è una pipe, oppure si
è dato un valore a \param{off\_in} o \param{off\_out} ma il
corrispondente file è un dispositivo che non supporta la funzione
- \func{seek}.
+ \func{lseek}.
\item[\errcode{ENOMEM}] non c'è memoria sufficiente per l'operazione
richiesta.
\item[\errcode{ESPIPE}] o \param{off\_in} o \param{off\_out} non sono
detto che i dati vengono effettivamente spostati o copiati, il kernel infatti
realizza le \textit{pipe} come un insieme di puntatori\footnote{per essere
precisi si tratta di un semplice buffer circolare, un buon articolo sul tema
- si trova su \href{http://lwn.net/Articles/118750/}
- {\textsf{http://lwn.net/Articles/118750/}}.} alle pagine di memoria interna
-che contengono i dati, per questo una volta che i dati sono presenti nella
-memoria del kernel tutto quello che viene fatto è creare i suddetti puntatori
-ed aumentare il numero di referenze; questo significa che anche con \func{tee}
-non viene mai copiato nessun byte, vengono semplicemente copiati i puntatori.
+ si trova su \url{http://lwn.net/Articles/118750/}.} alle pagine di memoria
+interna che contengono i dati, per questo una volta che i dati sono presenti
+nella memoria del kernel tutto quello che viene fatto è creare i suddetti
+puntatori ed aumentare il numero di referenze; questo significa che anche con
+\func{tee} non viene mai copiato nessun byte, vengono semplicemente copiati i
+puntatori.
% TODO?? dal 2.6.25 splice ha ottenuto il supporto per la ricezione su rete
% LocalWords: ENFILE lenght segment violation SIGSEGV FIXED msync munmap copy
% LocalWords: DoS Denial Service EXECUTABLE NORESERVE LOCKED swapping stack fs
% LocalWords: GROWSDOWN ANON POPULATE prefaulting SIGBUS fifo VME fork old SFD
-% LocalWords: exec atime ctime mtime mprotect addr EACCESS mremap address new
+% LocalWords: exec atime ctime mtime mprotect addr mremap address new
% LocalWords: long MAYMOVE realloc VMA virtual Ingo Molnar remap pages pgoff
% LocalWords: dall' fault cache linker prelink advisory discrectionary lock fl
% LocalWords: flock shared exclusive operation dup inode linked NFS cmd ENOLCK