X-Git-Url: https://gapil.gnulinux.it/gitweb/?a=blobdiff_plain;f=fileadv.tex;h=dd197fb840c81e04cf0daea1b124587a5aa37d19;hb=9a033fefbeb05db296e50ee476d3db780866e3aa;hp=98111fe18014604f28fa44ca2216d59aa98f5ef6;hpb=cf6a76554e5241851e4b87f0e70f2ac530591990;p=gapil.git diff --git a/fileadv.tex b/fileadv.tex index 98111fe..dd197fb 100644 --- a/fileadv.tex +++ b/fileadv.tex @@ -1,6 +1,6 @@ %% fileadv.tex %% -%% Copyright (C) 2000-2009 Simone Piccardi. Permission is granted to +%% Copyright (C) 2000-2010 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", @@ -1811,6 +1811,92 @@ che utilizza questa interfaccia in sez.~\ref{sec:TCP_sock_multiplexing}. \itindend{epoll} +\subsection{La notifica di eventi tramite file descriptor} +\label{sec:sig_signalfd_eventfd} + +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}. + +Benché i segnali siano il meccanismo più usato per effettuare notifiche ai +processi, la loro interfaccia di programmazione, che comporta l'esecuzione di +una funzione di gestione in maniera asincrona e totalmente scorrelata +dall'ordinario flusso di esecuzione del processo, si è però dimostrata quasi +subito assai problematica. Oltre ai limiti relativi ai limiti al cosa si può +fare all'interno della funzione del gestore di segnali (quelli illustrati in +sez.~\ref{sec:sig_signal_handler}), c'è il problema più generale consistente +nel fatto che questa modalità di funzionamento cozza con altre interfacce di +programmazione previste dal sistema in cui si opera in maniera +\textsl{sincrona}, come quelle dell'I/O multiplexing appena illustrate. + +In questo tipo di interfacce infatti ci si aspetta che il processo gestisca +gli eventi a cui vuole rispondere in maniera sincrona generando le opportune +risposte, mentre con l'arrivo di un segnale si possono avere interruzioni +asincrone in qualunque momento. Questo comporta la necessità di dover +gestire, quando si deve tener conto di entrambi i tipi di eventi, le +interruzioni delle funzioni di attesa sincrone, ed evitare possibili +\itindex{race~condition} \textit{race conditions}.\footnote{in sostanza se non + fossero per i segnali non ci sarebbe da doversi preoccupare, fintanto che si + effettuano operazioni all'interno di un processo, della non atomicità delle + \index{system~call~lente} system call lente che vengono interrotte e devono + essere riavviate.} + +Abbiamo visto però in sez.~\ref{sec:sig_real_time} che insieme ai segnali +\textit{real-time} sono state introdotte anche delle interfacce di gestione +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 +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. + +Per risolvere questo problema nello sviluppo del kernel si è pensato di +introdurre un meccanismo alternativo alla notifica dei segnali (esteso anche +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.} + +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 +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. + +La funzione che permette di abilitare la ricezione dei segnali tramite file +descriptor è \funcd{signalfd}, il cui prototipo è: +\begin{prototype}{sys/signalfd.h} + {int signalfd(int fd, const sigset\_t *mask, int flags)} + + Attende che uno dei file descriptor osservati sia pronto, mascherando i + segnali. + + \bodydesc{La funzione restituisce il numero di file descriptor pronti in + caso di successo o $-1$ in caso di errore, nel qual caso \var{errno} + assumerà uno dei valori già visti con \funcd{epoll\_wait}. +} +\end{prototype} + +% 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/ +% http://lwn.net/Articles/267331/ + + + \section{L'accesso \textsl{asincrono} ai file} \label{sec:file_asyncronous_access} @@ -2076,7 +2162,7 @@ kernel \textit{lease breaker} rimaste bloccate proseguono automaticamente. -\index{file!dnotify|(} +\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 @@ -2154,7 +2240,7 @@ specificate in chiamate successive vengono aggiunte a quelle gi nelle precedenti. Se si vuole rimuovere la notifica si deve invece specificare un valore nullo. -\index{file!inotify|(} +\itindbeg{inotify} Il maggiore problema di \textit{dnotify} è quello della scalabilità: si deve usare un file descriptor per ciascuna directory che si vuole tenere sotto @@ -2174,7 +2260,7 @@ 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. -\index{file!dnotify|)} +\itindend{dnotify} Per risolvere i problemi appena illustrati è stata introdotta una nuova interfaccia per l'osservazione delle modifiche a file o directory, chiamata @@ -2656,10 +2742,10 @@ verificano pi dei campi \var{wd}, \var{mask}, \var{cookie}, e \var{name}) questi vengono raggruppati in un solo evento. -\index{file!inotify|)} +\itindend{inotify} % TODO trattare fanotify, vedi http://lwn.net/Articles/339399/ e -% http://lwn.net/Articles/343346/ +% http://lwn.net/Articles/343346/ (incluso nel 2.6.36) \subsection{L'interfaccia POSIX per l'I/O asincrono} @@ -2736,35 +2822,11 @@ come vedremo, permette di eseguire con una sola chiamata una serie di operazioni, usando un vettore di \textit{control block}. Tramite questo campo si specifica quale è la natura di ciascuna di esse. -\begin{figure}[!htb] - \footnotesize \centering - \begin{minipage}[c]{15cm} - \includestruct{listati/sigevent.h} - \end{minipage} - \normalsize - \caption{La struttura \structd{sigevent}, usata per specificare le modalità - di notifica degli eventi relativi alle operazioni di I/O asincrono.} - \label{fig:file_sigevent} -\end{figure} - Infine il campo \var{aio\_sigevent} è una struttura di tipo \struct{sigevent} -che serve a specificare il modo in cui si vuole che venga effettuata la -notifica del completamento delle operazioni richieste. La struttura è -riportata in fig.~\ref{fig:file_sigevent}; il campo \var{sigev\_notify} è -quello che indica le modalità della notifica, esso può assumere i tre valori: -\begin{basedescript}{\desclabelwidth{2.6cm}} -\item[\const{SIGEV\_NONE}] Non viene inviata nessuna notifica. -\item[\const{SIGEV\_SIGNAL}] La notifica viene effettuata inviando al processo - chiamante il segnale specificato da \var{sigev\_signo}; se il gestore di - questo è stato installato con \const{SA\_SIGINFO} gli verrà restituito il - valore di \var{sigev\_value} (la cui definizione è in - fig.~\ref{fig:sig_sigval}) come valore del campo \var{si\_value} di - \struct{siginfo\_t}. -\item[\const{SIGEV\_THREAD}] La notifica viene effettuata creando un nuovo - \itindex{thread} \textit{thread} che esegue la funzione specificata da - \var{sigev\_notify\_function} con argomento \var{sigev\_value}, e con gli - attributi specificati da \var{sigev\_notify\_attribute}. -\end{basedescript} +(illustrata in in fig.~\ref{fig:struct_sigevent}) che serve a specificare il +modo in cui si vuole che venga effettuata la notifica del completamento delle +operazioni richieste; per la trattazione delle modalità di utilizzo della +stessa si veda quanto già visto in proposito in sez.~\ref{sec:sig_timer_adv}. Le due funzioni base dell'interfaccia per l'I/O asincrono sono \funcd{aio\_read} ed \funcd{aio\_write}. Esse permettono di richiedere una @@ -3044,7 +3106,7 @@ file in una sezione dello spazio di indirizzi del processo che lo ha allocato. \begin{figure}[htb] \centering - \includegraphics[width=14cm]{img/mmap_layout} + \includegraphics[width=12cm]{img/mmap_layout} \caption{Disposizione della memoria di un processo quando si esegue la mappatura in memoria di un file.} \label{fig:file_mmap_layout} @@ -4729,13 +4791,16 @@ dello spazio disco cos realizzazione di \func{posix\_fallocate} a partire dalla versione 2.10.} Trattandosi di una funzione di servizio, ed ovviamente disponibile -esclusivamente su Linux, \funcd{fallocate} non è stata definita come funzione -di libreria e pertanto può essere invocata da un programma soltanto in maniera -indiretta con l'ausilio di \func{syscall} (vedi sez.~\ref{sec:intro_syscall}); -il suo prototipo è: +esclusivamente su Linux, inizialmente \funcd{fallocate} non era stata definita +come funzione di libreria,\footnote{pertanto poteva essere invocata soltanto + in maniera indiretta con l'ausilio di \func{syscall}, vedi + sez.~\ref{sec:intro_syscall}, come \code{long fallocate(int fd, int mode, + loff\_t offset, loff\_t len)}.} ma a partire dalle \acr{glibc} 2.10 è + stato fornito un supporto esplicito; il suo prototipo è: \begin{functions} - \headdecl{linux/falloc.h} - \funcdecl{long fallocate(int fd, int mode, loff\_t offset, loff\_t len)} + \headdecl{linux/fcntl.h} + + \funcdecl{int fallocate(int fd, int mode, off\_t offset, off\_t len)} Prealloca dello spazio disco per un file. @@ -4775,12 +4840,8 @@ estensione dello stesso viene aggiornata, come richiesto per \func{fallocate} come l'implementazione ottimale di \func{posix\_fallocate} a livello di kernel. - -% TODO documentare \func{fallocate}, introdotta con il 2.6.23 % vedi http://lwn.net/Articles/226710/ e http://lwn.net/Articles/240571/ % http://kernelnewbies.org/Linux_2_6_23 -% \func{fallocate} con il 2.6.25 supporta pure XFS - @@ -4846,6 +4907,7 @@ livello di kernel. % 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 %%% Local Variables: