Documentati i file di sysctl delle code di messaggi Posix
authorSimone Piccardi <piccardi@gnulinux.it>
Tue, 8 Oct 2013 20:19:52 +0000 (20:19 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Tue, 8 Oct 2013 20:19:52 +0000 (20:19 +0000)
ipc.tex

diff --git a/ipc.tex b/ipc.tex
index 978e3b19e399cad38e84949e380ac68b63530fb9..a5955eae676deecabacf7dfee5346591b7b9d980 100644 (file)
--- 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