From: Simone Piccardi Date: Tue, 8 Oct 2013 20:19:52 +0000 (+0000) Subject: Documentati i file di sysctl delle code di messaggi Posix X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=commitdiff_plain;h=2bea03cc4a057980b1cc9be27e8681095e736dc1 Documentati i file di sysctl delle code di messaggi Posix --- diff --git a/ipc.tex b/ipc.tex index 978e3b1..a5955ea 100644 --- a/ipc.tex +++ b/ipc.tex @@ -2602,8 +2602,6 @@ delle pagine di swap ad uso del meccanismo del \textit{copy on write} significa che caso di scrittura sul segmento quando non c'è più memoria disponibile, si avrà l'emissione di un \signal{SIGSEGV}. -% TODO verificare i privilegi necessari per SHM_HUGETLB - Infine l'argomento \param{size} specifica la dimensione del segmento di memoria condivisa; il valore deve essere specificato in byte, ma verrà comunque arrotondato al multiplo superiore di \const{PAGE\_SIZE}. Il valore @@ -2783,7 +2781,7 @@ si ha a cuore la portabilità. Questi comandi aggiuntivi sono: sez.~\ref{sec:proc_mem_lock} fino al kernel 2.6.9 solo l'amministratore poteva utilizzare questa capacità,\footnote{che richiedeva la \textit{capability} \const{CAP\_IPC\_LOCK}.} a partire dal dal kernel - 2.6.10 anche gli utenti normali possono farlo fina al limite massimo + 2.6.10 anche gli utenti normali possono farlo fino al limite massimo determinato da \const{RLIMIT\_MEMLOCK} (vedi sez.~\ref{sec:sys_resource_limit}). \item[\const{SHM\_UNLOCK}] Disabilita il \itindex{memory~locking} @@ -3343,7 +3341,7 @@ alternativi. La prima possibilità, utilizzata fin dalle origini di Unix, è quella di usare dei \textsl{file di lock} (per i quali è stata anche riservata una opportuna directory, \file{/var/lock}, nella standardizzazione del \textit{Filesystem - Hyerarchy Standard}). Per questo si usa la caratteristica della funzione + Hierarchy Standard}). Per questo si usa la caratteristica della funzione \func{open} (illustrata in sez.~\ref{sec:file_open_close}) che prevede\footnote{questo è quanto dettato dallo standard POSIX.1, ciò non toglie che in alcune implementazioni questa tecnica possa non funzionare; in @@ -3582,7 +3580,7 @@ POSIX prendono come primo argomento una stringa che indica uno di questi nomi; lo standard è molto generico riguardo l'implementazione, ed i nomi stessi possono avere o meno una corrispondenza sul filesystem; tutto quello che è richiesto è che: -\begin{itemize} +\begin{itemize*} \item i nomi devono essere conformi alle regole che caratterizzano i \textit{pathname}, in particolare non essere più lunghi di \const{PATH\_MAX} byte e terminati da un carattere nullo. @@ -3591,7 +3589,7 @@ richiesto è che: nome dipende dall'implementazione. \item l'interpretazione di ulteriori \texttt{/} presenti nel nome dipende dall'implementazione. -\end{itemize} +\end{itemize*} Data la assoluta genericità delle specifiche, il comportamento delle funzioni è subordinato in maniera quasi completa alla relativa implementazione, tanto @@ -3600,13 +3598,15 @@ standard usata dallo standard POSIX per consentire implementazioni non standardizzabili. Nel caso di Linux, sia per quanto riguarda la memoria condivisa ed i semafori, -che per quanto riguarda le code di messaggi, tutto viene creato usando come -radici delle opportune directory (rispettivamente \file{/dev/shm} e -\file{/dev/mqueue}, per i dettagli si faccia riferimento a -sez.~\ref{sec:ipc_posix_shm}, sez.~\ref{sec:ipc_posix_sem} e -sez.~\ref{sec:ipc_posix_mq}) ed i nomi specificati nelle relative funzioni -sono considerati come un \itindsub{pathname}{assoluto} \textit{pathname} -assoluto (comprendente eventuali sottodirectory) rispetto a queste radici. +che per le code di messaggi, tutto viene creato usando come radici delle +opportune directory (rispettivamente \file{/dev/shm} e \file{/dev/mqueue}, per +i dettagli si faccia riferimento a sez.~\ref{sec:ipc_posix_shm}, +sez.~\ref{sec:ipc_posix_sem} e sez.~\ref{sec:ipc_posix_mq}). I nomi +specificati nelle relative funzioni devono essere nella forma di un +\textit{pathname} assoluto (devono cioè iniziare con ``\texttt{/}'') e +corrisponderanno ad altrettanti file creati all'interno di queste directory; +per questo motivo detti nomi non possono contenere altre ``\texttt{/}'' oltre +quella iniziale. Il vantaggio degli oggetti di IPC POSIX è comunque che essi vengono inseriti nell'albero dei file, e possono essere maneggiati con le usuali funzioni e @@ -3614,48 +3614,42 @@ comandi di accesso ai file, che funzionano come su dei file normali; questo però è vero nel caso di Linux, che usa una implementazione che lo consente, non è detto che altrettanto valga per altri kernel. In particolare, come si può facilmente verificare con uno \cmd{strace}, sia per la memoria condivisa -che per le code di messaggi le system call utilizzate da Linux sono le stesse -di quelle dei file, essendo detti oggetti realizzati come tali in appositi -filesystem. +che per le code di messaggi varie \textit{system call} utilizzate da Linux +corrispondono in realtà a quelle ordinarie dei file, essendo detti oggetti +realizzati come tali in appositi filesystem. In particolare i permessi associati agli oggetti di IPC POSIX sono identici ai permessi dei file, ed il controllo di accesso segue esattamente la stessa semantica (quella illustrata in sez.~\ref{sec:file_access_control}), e non quella particolare (si ricordi quanto visto in sez.~\ref{sec:ipc_sysv_access_control}) che viene usata per gli oggetti del -SysV-IPC. Per quanto riguarda l'attribuzione dell'utente e del gruppo +SysV-IPC. Per quanto riguarda l'attribuzione dell'utente e del gruppo proprietari dell'oggetto alla creazione di quest'ultimo essa viene effettuata secondo la semantica SysV: corrispondono cioè a \ids{UID} e \ids{GID} effettivi del processo che esegue la creazione. -\subsection{Code di messaggi} +\subsection{Code di messaggi Posix} \label{sec:ipc_posix_mq} Le code di messaggi POSIX sono supportate da Linux a partire dalla versione -2.6.6-rc1 del kernel,\footnote{l'implementazione è dovuta a Michal Wronski e - Krzysztof Benedyczak, e le relative informazioni si possono trovare su - \url{http://www.geocities.com/wronski12/posix_ipc/index.html}.} In generale, -come le corrispettive del \textit{SysV-IPC}, le code di messaggi sono poco -usate, dato che i socket, nei casi in cui sono sufficienti, sono più comodi, e -che in casi più complessi la comunicazione può essere gestita direttamente con -mutex (o semafori) e memoria condivisa con tutta la flessibilità che occorre. +2.6.6 del kernel. In generale, come le corrispettive del \textit{SysV-IPC}, le +code di messaggi sono poco usate, dato che i socket, nei casi in cui sono +sufficienti, sono più comodi, e che in casi più complessi la comunicazione può +essere gestita direttamente con mutex (o semafori) e memoria condivisa con +tutta la flessibilità che occorre. Per poter utilizzare le code di messaggi, oltre ad utilizzare un kernel -superiore al 2.6.6 (o precedente, se sono stati opportunamente applicati i -relativi patch) occorre utilizzare la libreria \file{libmqueue}\footnote{i - programmi che usano le code di messaggi cioè devono essere compilati - aggiungendo l'opzione \code{-lmqueue} al comando \cmd{gcc}; in - corrispondenza all'inclusione del supporto nel kernel ufficiale anche - \file{libmqueue} è stata inserita nella \acr{glibc}, a partire dalla - versione 2.3.4 delle medesime.} che contiene le funzioni dell'interfaccia -POSIX (in realtà l'implementazione è realizzata tramite delle opportune -chiamate ad \func{ioctl} sui file del filesystem speciale su cui vengono -mantenuti questi oggetti di IPC). +superiore al 2.6.6 occorre utilizzare la libreria \file{librt} che contiene le +funzioni dell'interfaccia POSIX ed i programmi che usano le code di messaggi +devono essere compilati aggiungendo l'opzione \code{-lrt} al comando +\cmd{gcc}. In corrispondenza all'inclusione del supporto nel kernel ufficiale +le funzioni di libreria sono state inserite nella \acr{glibc}, e sono +disponibili a partire dalla versione 2.3.4 delle medesime. La libreria inoltre richiede la presenza dell'apposito filesystem di tipo -\texttt{mqueue} montato su \file{/dev/mqueue}; questo può essere fatto -aggiungendo ad \conffile{/etc/fstab} una riga come: +\texttt{mqueue} montato sulla directory \file{/dev/mqueue}; questo può essere +fatto aggiungendo ad \conffile{/etc/fstab} una riga come: \begin{Example} mqueue /dev/mqueue mqueue defaults 0 0 \end{Example} @@ -3666,10 +3660,12 @@ rispettivamente di impostare l'utente, il gruppo ed i permessi associati al filesystem. -La funzione che permette di aprire (e crearla se non esiste ancora) una coda -di messaggi POSIX è \funcd{mq\_open}, ed il suo prototipo è: +La funzione di sistema che permette di aprire (e crearla se non esiste ancora) +una coda di messaggi POSIX è \funcd{mq\_open}, ed il suo prototipo è: \begin{funcproto}{ +\fhead{fcntl.h} +\fhead{sys/stat.h} \fhead{mqueue.h} \fdecl{mqd\_t mq\_open(const char *name, int oflag)} \fdecl{mqd\_t mq\_open(const char *name, int oflag, unsigned long mode, @@ -3681,20 +3677,24 @@ di messaggi POSIX è \funcd{mq\_open}, ed il suo prototipo è: {La funzione ritorna il descrittore associato alla coda in caso di successo e $-1$ per un errore, nel qual caso \var{errno} assumerà uno dei valori: \begin{errlist} - \item[\errcode{EACCES}] il processo non ha i privilegi per accedere al - alla memoria secondo quanto specificato da \param{oflag}. - \item[\errcode{EEXIST}] si è specificato \const{O\_CREAT} e - \const{O\_EXCL} ma la coda già esiste. - \item[\errcode{EINVAL}] il file non supporta la funzione, o si è - specificato \const{O\_CREAT} con una valore non nullo di \param{attr} e - valori non validi di \var{mq\_maxmsg} e \var{mq\_msgsize}. - \item[\errcode{ENOENT}] non si è specificato \const{O\_CREAT} ma la coda - non esiste. + \item[\errcode{EACCES}] il processo non ha i privilegi per accedere alla + coda secondo quanto specificato da \param{oflag} oppure \const{name} + contiene più di una ``\texttt{/}''. + \item[\errcode{EEXIST}] si è specificato \const{O\_CREAT} e \const{O\_EXCL} + ma la coda già esiste. + \item[\errcode{EINVAL}] il file non supporta la funzione, o si è specificato + \const{O\_CREAT} con una valore non nullo di \param{attr} e valori non + validi dei campi \var{mq\_maxmsg} e \var{mq\_msgsize}; questi valori + devono essere positivi ed inferiori ai limiti di sistema se il processo + non ha privilegi amministrativi, inoltre \var{mq\_maxmsg} non può comunque + superare \const{HARD\_MAX}. + \item[\errcode{ENOENT}] non si è specificato \const{O\_CREAT} ma la coda non + esiste o si è usato il nome ``\texttt{/}''. + \item[\errcode{ENOSPC}] lo spazio è insufficiente, probabilmente per aver + superato il limite di \texttt{queues\_max}. \end{errlist} - ed inoltre \errval{ENOMEM}, \errval{ENOSPC}, \errval{EFAULT}, - \errval{EMFILE}, \errval{EINTR} ed \errval{ENFILE} nel loro significato - generico. -} + ed inoltre \errval{EMFILE}, \errval{ENAMETOOLONG}, \errval{ENFILE}, + \errval{ENOMEM} ed nel loro significato generico. } \end{funcproto} La funzione apre la coda di messaggi identificata dall'argomento \param{name} @@ -3704,15 +3704,19 @@ descriptor, con l'unica differenza che lo standard prevede un apposito tipo file descriptor; pertanto, anche se questo comportamento non è portabile, lo si può tenere sotto osservazione con le funzioni dell'I/O multiplexing (vedi sez.~\ref{sec:file_multiplexing}) come possibile alternativa all'uso -dell'interfaccia di notifica di \func{mq\_notify} (che vedremo a breve). Se la -coda esiste già il descrittore farà riferimento allo stesso oggetto, -consentendo così la comunicazione fra due processi diversi. +dell'interfaccia di notifica di \func{mq\_notify} (che vedremo a breve). + +Se il nome indicato fa riferimento ad una coda di messaggi già esistente, il +descrittore ottenuto farà riferimento allo stesso oggetto, pertanto tutti i +processi che hanno usato \func{mq\_open} su quel nome otterranno un +riferimento alla stessa coda. Diventa così immediato costruire un canale di +comunicazione fra detti processi. La funzione è del tutto analoga ad \func{open} ed analoghi sono i valori che possono essere specificati per \param{oflag}, che deve essere specificato come maschera binaria; i valori possibili per i vari bit sono quelli visti in -sez.~\ref{sec:file_open_close} dei quali però \func{mq\_open} riconosce solo i -seguenti: +sez.~\ref{sec:file_open_close} (per questo occorre includere \texttt{fcntl.h}) +dei quali però \func{mq\_open} riconosce solo i seguenti: \begin{basedescript}{\desclabelwidth{2.2cm}\desclabelstyle{\nextlinelabel}} \item[\const{O\_RDONLY}] Apre la coda solo per la ricezione di messaggi. Il processo potrà usare il descrittore con \func{mq\_receive} ma non con @@ -3744,11 +3748,13 @@ Se la coda non esiste e la si vuole creare si deve specificare creazione con l'argomento \param{mode};\footnote{fino al 2.6.14 per un bug i valori della \textit{umask} del processo non venivano applicati a questi permessi.} i valori di quest'ultimo sono identici a quelli usati per -\func{open}, anche se per le code di messaggi han senso solo i permessi di -lettura e scrittura. Oltre ai permessi di creazione possono essere specificati -anche gli attributi specifici della coda tramite l'argomento \param{attr}; -quest'ultimo è un puntatore ad una apposita struttura \struct{mq\_attr}, la -cui definizione è riportata in fig.~\ref{fig:ipc_mq_attr}. +\func{open} (per questo occorre includere \texttt{sys/stat.h}), anche se per +le code di messaggi han senso solo i permessi di lettura e scrittura. + +Oltre ai permessi di creazione possono essere specificati anche gli attributi +specifici della coda tramite l'argomento \param{attr}; quest'ultimo è un +puntatore ad una apposita struttura \struct{mq\_attr}, la cui definizione è +riportata in fig.~\ref{fig:ipc_mq_attr}. \begin{figure}[!htb] \footnotesize \centering @@ -3765,10 +3771,46 @@ Per la creazione della coda i campi della struttura che devono essere specificati sono \var{mq\_maxmsg} e \var{mq\_msgsize}, che indicano rispettivamente il numero massimo di messaggi che può contenere e la dimensione massima di un messaggio. Il valore dovrà essere positivo e minore -dei rispettivi limiti di sistema \const{MQ\_MAXMSG} e \const{MQ\_MSGSIZE}, -altrimenti la funzione fallirà con un errore di \errcode{EINVAL}. -Se \param{attr} è un puntatore nullo gli attributi della coda saranno -impostati ai valori predefiniti. +dei rispettivi limiti di sistema altrimenti la funzione fallirà con un errore +di \errcode{EINVAL}. Se \param{attr} è un puntatore nullo gli attributi della +coda saranno impostati ai valori predefiniti. + +I suddetti limiti di sistema sono impostati attraverso altrettanti file in +\texttt{/proc/sys/fs/mqueue}, in particolare i file che controllano i valori +dei limiti sono: +\begin{basedescript}{\desclabelwidth{1.5cm}\desclabelstyle{\nextlinelabel}} +\item[\sysctlfile{fs/mqueue/msg\_max}] Indica il valore massimo del numero di + messaggi in una coda e agisce come limite superiore per il valore di + \var{attr->mq\_maxmsg} in \func{mq\_open}. Il suo valore di default è 10. Il + valore massimo è \const{HARD\_MAX} che vale \code{(131072/sizeof(void *))}, + ed il valore minimo 1 (ma era 10 per i kernel precedenti il 2.6.28). Questo + limite viene ignorato per i processi con privilegi amministrativi (più + precisamente con la \itindex{capability} \textit{capability} + \const{CAP\_SYS\_RESOURCE}) ma \const{HARD\_MAX} resta comunque non + superabile. + +\item[\sysctlfile{fs/mqueue/msgsize\_max}] Indica il valore massimo della + dimensione in byte di un messaggio sulla coda ed agisce come limite + superiore per il valore di \var{attr->mq\_msgsize} in \func{mq\_open}. Il + suo valore di default è 8192. Il valore massimo è 1048576 ed il valore + minimo 128 (ma per i kernel precedenti il 2.6.28 detti limiti erano + rispettivamente \const{INT\_MAX} e 8192). Questo valore viene ignorato dai + processi con privilegi amministrativi (la \itindex{capability} + \textit{capability} \const{CAP\_SYS\_RESOURCE}). + +\item[\sysctlfile{fs/mqueue/queues\_max}] Indica il numero massimo di code di + messaggi creabili in totale sul sistema, il valore di default è 256 ma si + può usare un valore qualunque fra $0$ e \const{INT\_MAX}. Il limite non + viene applicato ai processi con privilegi amministrativi (cioè con la + \itindex{capability} \textit{capability} \const{CAP\_SYS\_RESOURCE}). + +\end{basedescript} + +Infine sulle code di messaggi si applica il limite imposto sulla risorsa +\const{RLIMIT\_MSGQUEUE} (vedi sez.~\ref{sec:sys_resource_limit}) che indica +lo spazio massimo (in byte) occupabile da tutte le code di messaggi +appartenenti ai processi di uno stesso utente, identificato dal loro +\textit{real user ID}. Quando l'accesso alla coda non è più necessario si può chiudere il relativo descrittore con la funzione \funcd{mq\_close}, il cui prototipo è: @@ -3786,18 +3828,20 @@ descrittore con la funzione \funcd{mq\_close}, il cui prototipo è: } \end{funcproto} -La funzione è analoga a \func{close} (e in Linux, dove le code sono -implementate come file su un filesystem dedicato, è esattamente la stessa -funzione) dopo la sua esecuzione il processo non sarà più in grado di usare il -descrittore della coda, ma quest'ultima continuerà ad esistere nel sistema e -potrà essere acceduta con un'altra chiamata a \func{mq\_open}. All'uscita di -un processo tutte le code aperte, così come i file, vengono chiuse -automaticamente. Inoltre se il processo aveva agganciato una richiesta di -notifica sul descrittore che viene chiuso, questa sarà rilasciata e potrà -essere richiesta da qualche altro processo. +La funzione è analoga a \func{close},\footnote{su Linux, dove le code sono + implementate come file su un filesystem dedicato, è esattamente la stessa + funzione, per cui non esiste una \textit{system call} autonoma e la funzione + viene rimappata su \func{close} dalle \acr{glibc}.} dopo la sua esecuzione +il processo non sarà più in grado di usare il descrittore della coda, ma +quest'ultima continuerà ad esistere nel sistema e potrà essere acceduta con +un'altra chiamata a \func{mq\_open}. All'uscita di un processo tutte le code +aperte, così come i file, vengono chiuse automaticamente. Inoltre se il +processo aveva agganciato una richiesta di notifica sul descrittore che viene +chiuso, questa sarà rilasciata e potrà essere richiesta da qualche altro +processo. Quando si vuole effettivamente rimuovere una coda dal sistema occorre usare la -funzione \funcd{mq\_unlink}, il cui prototipo è: +funzione di sistema \funcd{mq\_unlink}, il cui prototipo è: \begin{funcproto}{ \fhead{mqueue.h} @@ -3812,9 +3856,11 @@ funzione \funcd{mq\_unlink}, il cui prototipo è: \end{funcproto} Anche in questo caso il comportamento della funzione è analogo a quello di -\func{unlink} per i file, (e di nuovo l'implementazione di Linux usa -direttamente \func{unlink}) la funzione rimuove la coda \param{name}, così che -una successiva chiamata a \func{mq\_open} fallisce o crea una coda diversa. +\func{unlink} per i file, la funzione rimuove la coda \param{name} (ed il +relativo file sotto \texttt{/dev/mqueue}), così che una successiva chiamata a +\func{mq\_open} fallisce o crea una coda diversa. + +% TODO, verificare se mq_unlink è davvero una system call indipendente. Come per i file ogni coda di messaggi ha un contatore di riferimenti, per cui la coda non viene effettivamente rimossa dal sistema fin quando questo non si @@ -3981,8 +4027,6 @@ selezionare quale messaggio estrarre con delle condizioni sulla priorità, a differenza di quanto avveniva con le code di messaggi di SysV che permettono invece la selezione in base al valore del campo \var{mtype}. -% TODO inserire i dati di /proc/sys/fs/mqueue - Qualora la coda sia vuota entrambe le funzioni si bloccano, a meno che non si sia selezionata la modalità non bloccante; in tal caso entrambe ritornano immediatamente con l'errore \errcode{EAGAIN}. Anche in questo caso la sola @@ -4404,7 +4448,7 @@ Si tenga presente che la funzione può sempre essere interrotta da un segnale (nel qual caso si avrà un errore di \const{EINTR}) e che questo avverrà comunque, anche se si è richiesta la semantica BSD installando il relativo gestore con \const{SA\_RESTART} (vedi sez.~\ref{sec:sig_sigaction}) per -riavviare le system call interrotte. +riavviare le \textit{system call} interrotte. Della funzione \func{sem\_wait} esistono due varianti che consentono di gestire diversamente le modalità di attesa in caso di risorsa occupata, la @@ -4933,14 +4977,15 @@ testo alla terminazione di quest'ultimo. % LocalWords: process getvalue sval execve pshared ENOSYS heap PAGE destroy it % LocalWords: xffffffff Arrays owner perms Queues used bytes messages device % LocalWords: Cannot find such Segments getter Signal MSGMAXSIZE been stable -% LocalWords: for now it's break Berlin sources Let's an accidental feature +% LocalWords: for now it's break Berlin sources Let's an accidental feature fs % LocalWords: Larry Wall Escape the Hell William ipctestid Identifier segment % LocalWords: violation dell'I SIGINT setter Fri Dec Sleeping seconds ECHILD % LocalWords: SysV capability short RESOURCE INFO UNDEFINED EFBIG semtimedop -% LocalWords: scan +% LocalWords: scan HUGETLB huge page NORESERVE copy RLIMIT MEMLOCK REMAP %%% Local Variables: %%% mode: latex %%% TeX-master: "gapil" %%% End: +% LocalWords: readmon Hierarchy defaults queues MSGQUEUE