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
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}
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
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.
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
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
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}
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,
{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}
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
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
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 è:
}
\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}
\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
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
(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
% 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