Prosecuzione lavoro su esempio signalfd
[gapil.git] / fileadv.tex
index 77e058e920ae77b2a6e90f00277af8ab6219cb30..fdf294698312d9d9f307039e954d642d88b27569 100644 (file)
@@ -1494,36 +1494,59 @@ La prima versione \textit{epoll} prevedeva l'apertura di uno speciale file di
 dispositivo, \texttt{/dev/epoll}, per ottenere un file descriptor da
 utilizzare con le funzioni dell'interfaccia,\footnote{il backporting
   dell'interfaccia per il kernel 2.4, non ufficiale, utilizza sempre questo
-  file.} ma poi si è passati all'uso una apposita \textit{system call}.  Il
-primo passo per usare l'interfaccia di \textit{epoll} è pertanto quello di
-chiamare la funzione \funcd{epoll\_create}, il cui prototipo è:
-\begin{prototype}{sys/epoll.h}
-  {int epoll\_create(int size)}
+  file.} ma poi si è passati all'uso di apposite \textit{system call}.  Il
+primo passo per usare l'interfaccia di \textit{epoll} è pertanto quello
+ottenere detto file descriptor chiamando una delle funzioni
+\funcd{epoll\_create} e \funcd{epoll\_create1},\footnote{l'interfaccia di
+  \textit{epoll} è stata inserita nel kernel a partire dalla versione 2.5.44,
+  ed il supporto è stato aggiunto alle \acr{glibc} 2.3.2.} i cui prototipi
+sono:
+\begin{functions}
+  \headdecl{sys/epoll.h}
+
+  \funcdecl{int epoll\_create(int size)}
+  \funcdecl{int epoll\_create1(int flags)}
   
   Apre un file descriptor per \textit{epoll}.
   
-  \bodydesc{La funzione restituisce un file descriptor in caso di successo, o
-    $-1$ in caso di errore, nel qual caso \var{errno} assumerà uno dei valori:
+  \bodydesc{Le funzioni restituiscono un file descriptor per \textit{epoll} in
+    caso di successo, o $-1$ in caso di errore, nel qual caso \var{errno}
+    assumerà uno dei valori:
   \begin{errlist}
   \item[\errcode{EINVAL}] si è specificato un valore di \param{size} non
-    positivo.
+    positivo o non valido per \param{flags}.
   \item[\errcode{ENFILE}] si è raggiunto il massimo di file descriptor aperti
     nel sistema.
+  \item[\errcode{EMFILE}] si è raggiunto il limite sul numero massimo di
+    istanze di \textit{epoll} per utente stabilito da
+    \procfile{/proc/sys/fs/epoll/max\_user\_instances}.
   \item[\errcode{ENOMEM}] non c'è sufficiente memoria nel kernel per creare
     l'istanza.
   \end{errlist}
 }
-\end{prototype}
+\end{functions}
 
-La funzione restituisce un file descriptor speciale,\footnote{esso non è
-  associato a nessun file su disco, inoltre a differenza dei normali file
-  descriptor non può essere inviato ad un altro processo attraverso un socket
-  locale (vedi sez.~\ref{sec:sock_fd_passing}).} detto anche \textit{epoll
-  descriptor}, che viene associato alla infrastruttura utilizzata dal kernel
-per gestire la notifica degli eventi; l'argomento \param{size} serve a dare
-l'indicazione del numero di file descriptor che si vorranno tenere sotto
-controllo, ma costituisce solo un suggerimento per semplificare l'allocazione
-di risorse sufficienti, non un valore massimo.
+Entrambe le funzioni restituiscono un file descriptor speciale,\footnote{esso
+  non è associato a nessun file su disco, inoltre a differenza dei normali
+  file descriptor non può essere inviato ad un altro processo attraverso un
+  socket locale (vedi sez.~\ref{sec:sock_fd_passing}).} detto anche
+\textit{epoll descriptor}, che viene associato alla infrastruttura utilizzata
+dal kernel per gestire la notifica degli eventi. Nel caso di
+\func{epoll\_create} l'argomento \param{size} serviva a dare l'indicazione del
+numero di file descriptor che si vorranno tenere sotto controllo, e costituiva
+solo un suggerimento per semplificare l'allocazione di risorse sufficienti,
+non un valore massimo.\footnote{ma a partire dal kernel 2.6.8 esso viene
+  totalmente ignorato e l'allocazione è sempre dinamica.}
+
+La seconda versione della funzione, \func{epoll\_create1} è stata
+introdotta\footnote{è disponibile solo a partire dal kernel 2.6.27.} come
+estensione della precedente, per poter passare dei flag di controllo come
+maschera binaria in fase di creazione del file descriptor. Al momento l'unico
+valore legale per \param{flags} (a parte lo zero) è \const{EPOLL\_CLOEXEC},
+che consente di impostare in maniera atomica sul file descriptor il flag di
+\itindex{close-on-exec} \textit{close-on-exec} (si veda il significato di
+\const{O\_CLOEXEC} in tab.~\ref{tab:file_open_flags}), senza che sia
+necessaria una successiva chiamata a \func{fcntl}.
 
 Una volta ottenuto un file descriptor per \textit{epoll} il passo successivo è
 indicare quali file descriptor mettere sotto osservazione e quali operazioni
@@ -1549,6 +1572,9 @@ controllare, per questo si deve usare la seconda funzione dell'interfaccia,
   \item[\errcode{ENOMEM}] non c'è sufficiente memoria nel kernel gestire
     l'operazione richiesta.
   \item[\errcode{EPERM}] il file \param{fd} non supporta \textit{epoll}.
+  \item[\errcode{ENOSPC}] si è raggiunto il limite massimo di registrazioni
+    per utente di file descriptor da osservere imposto da
+    \procfile{/proc/sys/fs/epoll/max\_user\_watches}.
   \end{errlist}
 }
 \end{prototype}
@@ -1597,8 +1623,10 @@ di tipo \struct{epoll\_event}, ed ha significato solo con le operazioni
 indicare quale tipo di evento relativo ad \param{fd} si vuole che sia tenuto
 sotto controllo.  L'argomento viene ignorato con l'operazione
 \const{EPOLL\_CTL\_DEL}.\footnote{fino al kernel 2.6.9 era comunque richiesto
-  che questo fosse un puntatore valido, anche se poi veniva ignorato, a
-  partire dal 2.6.9 si può specificare anche un valore \texttt{NULL}.}
+  che questo fosse un puntatore valido, anche se poi veniva ignorato; a
+  partire dal 2.6.9 si può specificare anche un valore \texttt{NULL} ma se si
+  vuole mantenere la compatibilità con le versioni precedenti occorre usare un
+  puntatore valido.}
 
 \begin{figure}[!htb]
   \footnotesize \centering
@@ -1624,7 +1652,8 @@ deve essere specificato come OR aritmetico delle costanti riportate in
 tab.~\ref{tab:epoll_events}. Il secondo campo, \var{data}, serve ad indicare a
 quale file descriptor si intende fare riferimento, ed in astratto può
 contenere un valore qualsiasi che permetta di identificarlo, di norma comunque
-si usa come valore lo stesso \param{fd}.
+si usa come valore lo stesso argomento \param{fd}, che ha un significato
+immediato.
 
 \begin{table}[htb]
   \centering
@@ -1641,7 +1670,8 @@ si usa come valore lo stesso \param{fd}.
     \const{EPOLLRDHUP}  & L'altro capo di un socket di tipo
                           \const{SOCK\_STREAM} (vedi sez.~\ref{sec:sock_type})
                           ha chiuso la connessione o il capo in scrittura
-                          della stessa (vedi sez.~\ref{sec:TCP_shutdown}).\\
+                          della stessa (vedi
+                          sez.~\ref{sec:TCP_shutdown}).\footnotemark\\
     \const{EPOLLPRI}    & Ci sono \itindex{out-of-band} dati urgenti
                           disponibili in lettura (analogo di
                           \const{POLLPRI}); questa condizione viene comunque
@@ -1651,7 +1681,9 @@ si usa come valore lo stesso \param{fd}.
                           (analogo di \const{POLLERR}); questa condizione
                           viene comunque riportata in uscita, e non è
                           necessaria impostarla in ingresso.\\
-    \const{EPOLLHUP}    & Si è verificata una condizione di hung-up.\\
+    \const{EPOLLHUP}    & Si è verificata una condizione di hung-up; questa
+                          condizione viene comunque riportata in uscita, e non
+                          è necessaria impostarla in ingresso.\\
     \const{EPOLLET}     & Imposta la notifica in modalità \textit{edge
                             triggered} per il file descriptor associato.\\ 
     \const{EPOLLONESHOT}& Imposta la modalità \textit{one-shot} per il file
@@ -1663,7 +1695,12 @@ si usa come valore lo stesso \param{fd}.
   \label{tab:epoll_events}
 \end{table}
 
-\footnotetext{questa modalità è disponibile solo a partire dal kernel 2.6.2.}
+\footnotetext{questa modalità è disponibile solo a partire dal kernel 2.6.17,
+  ed è utile per riconoscere la chiusura di una connessione dall'altro capo
+  quando si lavora in modalità \textit{edge triggered}.}
+
+\footnotetext[48]{questa modalità è disponibile solo a partire dal kernel
+  2.6.2.}
 
 Le modalità di utilizzo di \textit{epoll} prevedono che si definisca qual'è
 l'insieme dei file descriptor da tenere sotto controllo tramite un certo
@@ -1781,9 +1818,10 @@ restituiti meno dati di quelli richiesti.
 
 Come già per \func{select} e \func{poll} anche per l'interfaccia di
 \textit{epoll} si pone il problema di gestire l'attesa di segnali e di dati
-contemporaneamente, per far questo di nuovo è necessaria una variante della
-funzione di attesa che consenta di reimpostare all'uscita una maschera di
-segnali, analoga alle precedenti estensioni \func{pselect} e \func{ppoll} di
+contemporaneamente per le osservazioni fatte in sez.~\ref{sec:file_select},
+per fare questo di nuovo è necessaria una variante della funzione di attesa
+che consenta di reimpostare all'uscita una maschera di segnali, analoga alle
+estensioni \func{pselect} e \func{ppoll} che abbiamo visto in precedenza per
 \func{select} e \func{poll}; in questo caso la funzione si chiama
 \funcd{epoll\_pwait}\footnote{la funziona è stata introdotta a partire dal
   kernel 2.6.19, ed è come tutta l'interfaccia di \textit{epoll}, specifica di
@@ -1871,7 +1909,7 @@ ad altri eventi generici) che, ispirandosi di nuovo alla filosofia di Unix per
 cui tutto è un file, consentisse di eseguire la notifica con l'uso di
 opportuni file descriptor.\footnote{ovviamente si tratta di una funzionalità
   specifica di Linux, non presente in altri sistemi unix-like, e non prevista
-  da nessuno standard.}
+  da nessuno standard, per cui va evitata se si ha a cuore la portabilità.}
 
 In sostanza, come per \func{sigwait}, si può disabilitare l'esecuzione di un
 gestore in occasione dell'arrivo di un segnale, e rilevarne l'avvenuta
@@ -1884,9 +1922,14 @@ contemporanea sia l'arrivo del segnale che la disponibilit
 relativi a questi ultimi.
 
 La funzione che permette di abilitare la ricezione dei segnali tramite file
-descriptor è \funcd{signalfd},\footnote{in realtà questa è il nome della
-  funzione fornita dalle \acr{glibc},  esistono in realtà due
-  versioni, anche se } il cui prototipo è:
+descriptor è \funcd{signalfd},\footnote{in realtà quella riportata è la
+  interfacia alla funzione fornita dalle \acr{glibc}, esistono in realtà due
+  versioni diverse della \textit{system call}, la prima versione,
+  \func{signalfd}, introdotta nel kernel 2.6.22 e disponibile con le
+  \acr{glibc} 2.8 che non supporta l'argomento, ed una seconda versione,
+  \func{signalfd4}, che prende argomenti aggiuntivi, introdotta con il kernel
+  2.6.27 che è quella che viene sempre usata a partire dalle \acr{glibc} 2.9.}
+il cui prototipo è:
 \begin{prototype}{sys/signalfd.h} 
   {int signalfd(int fd, const sigset\_t *mask, int flags)}
 
@@ -1911,29 +1954,30 @@ descriptor 
 
 La funzione consente di creare o modificare le caratteristiche di un file
 descriptor speciale su cui ricevere le notifiche della ricezione di
-segnali. Per creare un nuovo file descriptor è necessario passare $-1$ come
-valore per l'argomento \param{fd}, ogni altro valore positivo verrà invece
-interpretato come il numero del file descriptor (che deve esser stato
+segnali. Per creare ex-novo uno di questi file descriptor è necessario passare
+$-1$ come valore per l'argomento \param{fd}, ogni altro valore positivo verrà
+invece interpretato come il numero del file descriptor (che deve esser stato
 precedentemente creato sempre con \func{signalfd}) di cui si vogliono
-modificare le caratteristiche. Nel primo caso la funzione ritornerà il nuovo
-file descriptor e nel secondo caso \param{fd}, in caso di errore verrà invece
-restituito $-1$.
+modificare le caratteristiche. Nel primo caso la funzione ritornerà il valore
+del nuovo file descriptor e nel secondo caso il valore indicato
+con \param{fd}, in caso di errore invece verrà restituito $-1$.
 
 L'elenco dei segnali che si vogliono gestire con \func{signalfd} deve essere
 specificato tramite l'argomento \param{mask}. Questo deve essere passato come
-puntatore ad una maschera di segnali creata con l'uso delle apposite macro
-illustrate in sez.~\ref{sec:sig_sigset} che indichi su quali segnali si
-intende operare con \func{signalfd}, l'elenco può essere modificato da una
-chiamata successiva. Dato che \const{SIGKILL} e \const{SIGSTOP} non possono
-essere intercettati (e non prevedono neanche la possibilità di un gestore) un
-loro inserimento nella maschera verrà semplicemente ignorato, senza generare
-errori.
-
-Infine l'argomento \param{flags} consente di impostare direttamente in fase di
-creazione due flag per il file descriptor analoghe a quelle che si possono
-impostare con \func{open}, evitando una impostazione successiva con
-\func{fcntl}.\footnote{questo è un argomento aggiuntivo introdotto con il
-  kernel 2.6.27, in precedenza il valore era nullo } 
+puntatore ad una maschera di segnali creata con l'uso delle apposite macro già
+illustrate in sez.~\ref{sec:sig_sigset}; la maschera deve indicare su quali
+segnali si intende operare con \func{signalfd}; l'elenco può essere modificato
+con una successiva chiamata a \func{signalfd}. Dato che \const{SIGKILL} e
+\const{SIGSTOP} non possono essere intercettati (e non prevedono neanche la
+possibilità di un gestore) un loro inserimento nella maschera verrà ignorato,
+senza generare errori.
+
+L'argomento \param{flags} consente di impostare direttamente in fase di
+creazione due flag per il file descriptor analoghi a quelli che si possono
+impostare con una creazione ordinaria con \func{open}, evitando una
+impostazione successiva con \func{fcntl}.\footnote{questo è un argomento
+  aggiuntivo, introdotto con la versione fornita a partire dal kernel 2.6.27,
+  per kernel precedenti il valore deve essere nullo.}
 
 \begin{table}[htb]
   \centering
@@ -1951,11 +1995,19 @@ impostare con \func{open}, evitando una impostazione successiva con
     \hline    
   \end{tabular}
   \caption{Valori dell'argomento \param{flags} per la funzione \func{signalfd}
-    che consentono di impostare fl.} 
+    che consentono di impostare i flag del file descriptor.} 
   \label{tab:signalfd_flags}
 \end{table}
 
-% TODO trattare qui eventfd signalfd e timerfd introdotte con il 2.6.22 
+L'interfaccia fornita da \func{signalfd} prevede che la ricezione dei segnali
+sia eseguita leggendo dal file descriptor restituito dalla funzione. La
+lettura fornisce nel buffer indicato come secondo argomento alla funzione
+\func{read} una o più strutture \struct{signalfd\_siginfo} a seconda della
+dimensione dello stesso e del numero di segnali pendenti. Pertanto il buffer
+deve essere almeno di dimensione pari a \code{sizeof(signalfd\_siginfo)}; se
+di dimensione maggiore potranno essere letti in unica soluzione 
+
+% TODO trattare qui eventfd, signalfd e timerfd introdotte con il 2.6.22 
 % timerfd è stata tolta nel 2.6.23 e rifatta per bene nel 2.6.25
 % vedi: http://lwn.net/Articles/233462/
 %       http://lwn.net/Articles/245533/
@@ -2227,14 +2279,17 @@ 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.
 
-
-\itindbeg{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
 risolvere il problema di rilevare automaticamente quando un file o una
-directory vengono modificati, che è quanto necessario ad esempio ai programma
-di gestione dei file dei vari desktop grafici.
+directory vengono modificati,\footnote{questa funzionalità venne aggiunta
+  principalmente ad uso di Samba per poter facilitare l'emulazione del
+  comportamento di Windows sui file, ma ad oggi viene considerata una
+  interfaccia mal progettata ed il suo uso è fortemente sconsigliato a favore
+  di \textit{inotify}.} che è quanto necessario ad esempio ai programma di
+gestione dei file dei vari desktop grafici.
+
+\itindbeg{dnotify}
 
 Per risolvere questo problema a partire dal kernel 2.4 è stata allora creata
 un'altra interfaccia,\footnote{si ricordi che anche questa è una interfaccia
@@ -2324,7 +2379,7 @@ numero di file).  Infine l'uso dei segnali come interfaccia di notifica
 comporta tutti i problemi di gestione visti in sez.~\ref{sec:sig_management} e
 sez.~\ref{sec:sig_adv_control}.  Per tutta questa serie di motivi in generale
 quella di \textit{dnotify} viene considerata una interfaccia di usabilità
-problematica.
+problematica ed il suo uso oggi è fortemente sconsigliato.
 
 \itindend{dnotify}