From: Simone Piccardi Date: Sat, 22 Jan 2011 18:54:44 +0000 (+0000) Subject: Correzioni varie e inizio timerfd X-Git-Url: https://gapil.gnulinux.it/gitweb/?a=commitdiff_plain;h=09a3b3a75ff3b6cb6760b9034b093b6d49923b00;p=gapil.git Correzioni varie e inizio timerfd --- diff --git a/fileadv.tex b/fileadv.tex index fe6dda6..156de8e 100644 --- a/fileadv.tex +++ b/fileadv.tex @@ -10,7 +10,6 @@ %% \chapter{La gestione avanzata dei file} \label{cha:file_advanced} - In questo capitolo affronteremo le tematiche relative alla gestione avanzata dei file. Inizieremo con la trattazione delle problematiche del \textit{file locking} e poi prenderemo in esame le varie funzionalità avanzate che @@ -1573,7 +1572,7 @@ controllare, per questo si deve usare la seconda funzione dell'interfaccia, 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 + per utente di file descriptor da osservare imposto da \procfile{/proc/sys/fs/epoll/max\_user\_watches}. \end{errlist} } @@ -1866,9 +1865,10 @@ programma che utilizza questa interfaccia in sez.~\ref{sec:TCP_serv_epoll}. Abbiamo visto in sez.~\ref{sec:file_select} come il meccanismo classico delle notifiche di eventi tramite i segnali, presente da sempre nei sistemi unix-like, porti a notevoli problemi nell'interazione con le funzioni per -l'I/O multiplexing, tanto che per evitare possibili \itindex{race~condition} -\textit{race condition} sono state introdotte estensioni dello standard POSIX e -funzioni apposite come \func{pselect}, \func{ppoll} e \funcd{epoll\_pwait}. +l'\textit{I/O multiplexing}, tanto che per evitare possibili +\itindex{race~condition} \textit{race condition} sono state introdotte +estensioni dello standard POSIX e funzioni apposite come \func{pselect}, +\func{ppoll} e \funcd{epoll\_pwait}. Benché i segnali siano il meccanismo più usato per effettuare notifiche ai processi, la loro interfaccia di programmazione, che comporta l'esecuzione di @@ -1898,10 +1898,10 @@ Abbiamo visto per sincrona dei segnali con la funzione \func{sigwait} e le sue affini. Queste funzioni consentono di gestire i segnali bloccando un processo fino alla avvenuta ricezione e disabilitando l'esecuzione asincrona rispetto al resto -del programma del gestore del segnale. Questo consente di risolvere i -problemi di atomicità nella gestione degli eventi associati ai segnali, avendo -tutto il controllo nel flusso principale del programma, ottenendo così una -gestione simile a quella dell'I/O multiplexing, ma non risolve i problemi +del programma del gestore del segnale. Questo consente di risolvere i problemi +di atomicità nella gestione degli eventi associati ai segnali, avendo tutto il +controllo nel flusso principale del programma, ottenendo così una gestione +simile a quella dell'\textit{I/O multiplexing}, ma non risolve i problemi delle interazioni con quest'ultimo, perché o si aspetta la ricezione di un segnale o si aspetta che un file descriptor sia accessibile e nessuna delle rispettive funzioni consente di fare contemporaneamente entrambe le cose. @@ -1918,25 +1918,27 @@ In sostanza, come per \func{sigwait}, si pu gestore in occasione dell'arrivo di un segnale, e rilevarne l'avvenuta ricezione leggendone la notifica tramite l'uso di uno speciale file descriptor. Trattandosi di un file descriptor questo potrà essere tenuto sotto -osservazione con le ordinarie funzioni dell'I/O multiplexing (vale a dire con -le solite \func{select}, \func{poll} e \funcd{epoll\_wait}) allo stesso modo -di quelli associati a file o socket, per cui alla fine si potrà attendere in -contemporanea sia l'arrivo del segnale che la disponibilità di accesso ai dati -relativi a questi ultimi. +osservazione con le ordinarie funzioni dell'\textit{I/O multiplexing} (vale a +dire con le solite \func{select}, \func{poll} e \funcd{epoll\_wait}) allo +stesso modo di quelli associati a file o socket, per cui alla fine si potrà +attendere in contemporanea sia l'arrivo del segnale che la disponibilità di +accesso ai dati relativi a questi ultimi. La funzione che permette di abilitare la ricezione dei segnali tramite file -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, +descriptor è \funcd{signalfd},\footnote{in realtà quella riportata è + l'interfaccia alla funzione fornita dalle \acr{glibc}, esistono infatti due + versioni diverse della \textit{system call}; una 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 è: + \acr{glibc} 2.8 che non supporta l'argomento \texttt{flags}, ed una seconda + versione, \func{signalfd4}, introdotta con il kernel 2.6.27 e che è quella + che viene sempre usata a partire dalle \acr{glibc} 2.9, che prende un + argomento aggiuntivo \code{size\_t sizemask} che indica la dimensione della + maschera dei segnali, il cui valore viene impostato automaticamente dalle + \acr{glibc}.} il cui prototipo è: \begin{prototype}{sys/signalfd.h} {int signalfd(int fd, const sigset\_t *mask, int flags)} - Crea o modifica un file descriptor pet la ricezione dei segnali. + Crea o modifica un file descriptor per la ricezione dei segnali. \bodydesc{La funzione restituisce un numero di file descriptor in caso di successo o $-1$ in caso di errore, nel qual caso \var{errno} assumerà uno @@ -1945,7 +1947,7 @@ il cui prototipo \item[\errcode{EBADF}] il valore \param{fd} non indica un file descriptor. \item[\errcode{EINVAL}] il file descriptor \param{fd} non è stato ottenuto con \func{signalfd} o il valore di \param{flags} non è valido. - \item[\errcode{ENOMEN}] non c'è memoria sufficiente per creare un nuovo file + \item[\errcode{ENOMEM}] non c'è memoria sufficiente per creare un nuovo file descriptor di \func{signalfd}. \item[\errcode{ENODEV}] il kernel non può montare internamente il dispositivo per la gestione anonima degli inode associati al file @@ -1968,19 +1970,21 @@ con \param{fd}, in caso di errore invece verr 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 già -illustrate in sez.~\ref{sec:sig_sigset}; la maschera deve indicare su quali +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. +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.} + per kernel precedenti il valore deve essere nullo.} L'argomento deve essere +specificato come maschera binaria dei valori riportati in +tab.~\ref{tab:signalfd_flags}. \begin{table}[htb] \centering @@ -2002,18 +2006,71 @@ impostazione successiva con \func{fcntl}.\footnote{questo \label{tab:signalfd_flags} \end{table} +Si tenga presente che la chiamata a \func{signalfd} non disabilita la gestione +ordinaria dei segnali indicati da \param{mask}; questa, se si vuole effettuare +la ricezione tramite il file descriptor, dovrà essere disabilitata +esplicitamente bloccando gli stessi segnali con \func{sigprocmask}, altrimenti +verranno comunque eseguite le azioni di default (o un eventuale gestore +installato in precedenza).\footnote{il blocco non ha invece nessun effetto sul + file descriptor restituito da \func{signalfd}, dal quale sarà possibile + pertanto ricevere qualunque segnale, anche se questo risultasse bloccato.} +Si tenga presente inoltre che la lettura di una struttura +\struct{signalfd\_siginfo} relativa ad un segnale pendente è equivalente alla +esecuzione di un gestore, vale a dire che una volta letta il segnale non sarà +più pendente e non potrà essere ricevuto, qualora si ripristino le normali +condizioni di gestione, né da un gestore né dalla funzione \func{sigwaitinfo}. + +Come anticipato, essendo questo lo scopo principale della nuova interfaccia, +il file descriptor può essere tenuto sotto osservazione tramite le funzioni +dell'\textit{I/O multiplexing} (vale a dire con le solite \func{select}, +\func{poll} e \funcd{epoll\_wait}), e risulterà accessibile in lettura quando +uno o più dei segnali indicati tramite \param{mask} sarà pendente. + +La funzione può essere chiamata più volte dallo stesso processo, consentendo +così di tenere sotto osservazione segnali diversi tramite file descriptor +diversi. Inoltre è anche possibile tenere sotto osservazione lo stesso segnale +con più file descriptor, anche se la pratica è sconsigliata; in tal caso la +ricezione del segnale potrà essere effettuata con una lettura da uno qualunque +dei file descriptor a cui è associato, ma questa potrà essere eseguita +soltanto una volta.\footnote{questo significa che tutti i file descriptor su + cui è presente lo stesso segnale risulteranno pronti in lettura per le + funzioni di \textit{I/O multiplexing}, ma una volta eseguita la lettura su + uno di essi il segnale sarà considerato ricevuto ed i relativi dati non + saranno più disponibili sugli altri file descriptor, che (a meno di una + ulteriore occorrenza del segnale nel frattempo) di non saranno più pronti.} + +Quando il file descriptor per la ricezione dei segnali non serve più potrà +essere chiuso con \func{close} liberando tutte le risorse da esso allocate. In +tal caso qualora vi fossero segnali pendenti questi resteranno tali, e +potranno essere ricevuti normalmente una volta che si rimuova il blocco +imposto con \func{sigprocmask}. + +Oltre che con le funzioni dell'\textit{I/O multiplexing} l'uso del file +descriptor restituito da \func{signalfd} cerca di seguire la semantica di un +sistema unix-like anche con altre \textit{system call}; in particolare esso +resta aperto (come ogni altro file descriptor) attraverso una chiamata ad +\func{exec}, a meno che non lo si sia creato con il flag di +\const{SFD\_CLOEXEC} o si sia successivamente impostato il +\textit{close-on-exec} con \func{fcntl}. Questo comportamento corrisponde +anche alla ordinaria semantica relativa ai segnali bloccati, che restano +pendenti attraverso una \func{exec}. + +Analogamente il file descriptor resta sempre disponibile attraverso una +\func{fork} per il processo figlio, che ne riceve una copia; in tal caso però +il figlio potrà leggere dallo stesso soltanto i dati relativi ai segnali +ricevuti da lui stesso. Nel caso di \textit{thread} viene nuovamente seguita +la semantica ordinaria dei segnali, che prevede che un singolo \textit{thread} +possa ricevere dal file descriptor solo le notifiche di segnali inviati +direttamente a lui o al processo in generale, e non quelli relativi ad altri +\textit{thread} appartenenti allo stesso processo. + L'interfaccia fornita da \func{signalfd} prevede che la ricezione dei segnali sia eseguita leggendo i dati relativi ai segnali pendenti dal file descriptor -restituito dalla funzione con una normalissima \func{read}. Questi dati -vengono scritti sul buffer indicato come secondo argomento di \func{read} in -forma di una sequenza di una o più strutture \struct{signalfd\_siginfo} (la -cui definizione si è riportata in fig.~\ref{fig:signalfd_siginfo}) a seconda -sia della dimensione del buffer che del numero di segnali pendenti. Per questo -motivo il buffer deve essere almeno di dimensione pari a quella di -\struct{signalfd\_siginfo}, qualora sia di dimensione maggiore potranno essere -letti in unica soluzione i dati relativi ad eventuali più segnali pendenti, -fino al numero massimo di strutture \struct{signalfd\_siginfo} che possono -rientrare nel buffer. +restituito dalla funzione con una normalissima \func{read}. Qualora non vi +siano segnali pendenti la \func{read} si bloccherà a meno di non aver +impostato la modalità di I/O non bloccante sul file descriptor, o direttamente +in fase di creazione con il flag \const{SFD\_NONBLOCK}, o in un momento +successivo con \func{fcntl}. \begin{figure}[!htb] \footnotesize \centering @@ -2026,11 +2083,39 @@ rientrare nel buffer. \label{fig:signalfd_siginfo} \end{figure} -Si tenga presente che lettura di una struttura \struct{signalfd\_siginfo} -relativa ad un segnale pendente è equivalente alla esecuzione di un gestore, -vale a dire che una volta letta il segnale non sarà più pendente e non potrà -essere ricevuto, qualora si ripristino le normali condizioni di gestione, né -da un gestore né dalla funzione \func{sigwaitinfo}. +I dati letti dal file descriptor vengono scritti sul buffer indicato come +secondo argomento di \func{read} nella forma di una sequenza di una o più +strutture \struct{signalfd\_siginfo} (la cui definizione si è riportata in +fig.~\ref{fig:signalfd_siginfo}) a seconda sia della dimensione del buffer che +del numero di segnali pendenti. Per questo motivo il buffer deve essere almeno +di dimensione pari a quella di \struct{signalfd\_siginfo}, qualora sia di +dimensione maggiore potranno essere letti in unica soluzione i dati relativi +ad eventuali più segnali pendenti, fino al numero massimo di strutture +\struct{signalfd\_siginfo} che possono rientrare nel buffer. + +Il contenuto di \struct{signalfd\_siginfo} ricalca da vicino quella della +analoga struttura \struct{siginfo\_t} (illustrata in +fig.~\ref{fig:sig_siginfo_t}) usata dall'interfaccia ordinaria dei segnali, e +restituisce dati simili. Come per \struct{siginfo\_t} i campi che vengono +avvalorati dipendono dal tipo di segnale e ricalcano i valori che abbiamo già +illustrato in sez.~\ref{sec:sig_sigaction}.\footnote{si tenga presente però + che per un bug i kernel fino al 2.6.25 non avvalorano correttamente i campi + \var{ssi\_ptr} e \var{ssi_int} per segnali inviati con \func{sigqueue}.} + +Lo stesso paradigma di notifica tramite file descriptor usato per i segnali è +stato adottato anche per i timer; in questo caso, rispetto a quanto visto in +sez.~\ref{sec:sig_timer_adv}, la scadenza di un timer potrà essere letta da un +file descriptor, senza dover ricorrere ad altri meccanismi come un segnale o +un \textit{thread} di notifica. Di nuovo questo ha il vantaggio di poter +utilizzare le funzioni dell'\textit{I/O multiplexing} per attendere allo +stesso tempo la disponibilità di dati o la ricezione di un segnale +qualunque.\footnote{in realtà per questo sarebbe già sufficiente + \func{signalfd} per ricevere i segnali associati ai timer, ma la nuova + interfaccia semplifica notevolmente la gestione.} + +Le funzioni di questa interfaccia riprendono da vicino + + % TODO trattare qui eventfd, timerfd introdotte con il 2.6.22 % timerfd è stata tolta nel 2.6.23 e rifatta per bene nel 2.6.25 @@ -5053,7 +5138,7 @@ livello di kernel. % LocalWords: only ETXTBSY DENYWRITE ENODEV filesystem EPERM EXEC noexec table % 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 +% LocalWords: GROWSDOWN ANON POPULATE prefaulting SIGBUS fifo VME fork old SFD % LocalWords: exec atime ctime mtime mprotect addr EACCESS mremap address new % LocalWords: long MAYMOVE realloc VMA virtual Ingo Molnar remap pages pgoff % LocalWords: dall' fault cache linker prelink advisory discrectionary lock fl @@ -5076,8 +5161,9 @@ livello di kernel. % LocalWords: SEQUENTIAL NOREUSE WILLNEED DONTNEED streaming fallocate EFBIG % LocalWords: POLLRDHUP half close pwait Gb madvise MADV ahead REMOVE tmpfs % LocalWords: DONTFORK DOFORK shmfs preadv pwritev syscall linux loff head XFS -% LocalWords: MERGEABLE EOVERFLOW prealloca hole FALLOC KEEP stat fstat -% LocalWords: conditions sigwait +% LocalWords: MERGEABLE EOVERFLOW prealloca hole FALLOC KEEP stat fstat union +% LocalWords: conditions sigwait CLOEXEC signalfd sizemask SIGKILL SIGSTOP ssi +% LocalWords: sigwaitinfo FifoReporter Windows ptr sigqueue %%% Local Variables: diff --git a/listati/signalfd_siginfo.h b/listati/signalfd_siginfo.h index 373e328..33c1d08 100644 --- a/listati/signalfd_siginfo.h +++ b/listati/signalfd_siginfo.h @@ -5,7 +5,7 @@ struct signalfd_siginfo { uint32_t ssi_pid; /* PID of sender */ uint32_t ssi_uid; /* Real UID of sender */ int32_t ssi_fd; /* File descriptor (SIGIO) */ - uint32_t ssi_tid; /* Kernel timer ID (POSIX timers) + uint32_t ssi_tid; /* Kernel timer ID (POSIX timers) */ uint32_t ssi_band; /* Band event (SIGIO) */ uint32_t ssi_overrun; /* POSIX timer overrun count */ uint32_t ssi_trapno; /* Trap number that caused signal */ diff --git a/signal.tex b/signal.tex index a51a08e..4400436 100644 --- a/signal.tex +++ b/signal.tex @@ -2617,7 +2617,7 @@ hardware che possono supportare risoluzioni molto elevate, ed in maniera del tutto indipendente dalla frequenza scelta per il timer di sistema che governa lo \textit{scheduler};\footnote{normalmente si possono ottenere precisioni fino al microsecondo, andando molto oltre in caso di hardware dedicato.} per -questo lo standard POSIX ha previsto una serie di nuove funzioni relative a a +questo lo standard POSIX ha previsto una serie di nuove funzioni relative a quelli che vengono chiamati ``\textsl{orologi} \textit{real-time}'', in grado di supportare risoluzioni fino al nanosecondo. Inoltre le CPU più moderne sono dotate a loro volta di contatori ad alta definizione che consentono una grande