From: Simone Piccardi Date: Wed, 2 Oct 2013 15:29:10 +0000 (+0000) Subject: Revisione segmenti memoria condivisa SysV IPC X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=commitdiff_plain;h=1950828363ce9bfcb68b2646e68b82d162e4313d Revisione segmenti memoria condivisa SysV IPC --- diff --git a/filedir.tex b/filedir.tex index b0e42ac..2ac0f15 100644 --- a/filedir.tex +++ b/filedir.tex @@ -6877,7 +6877,8 @@ opportuno dettagliare maggiormente. funzioni \func{mlock}, \func{mlockall}, \func{shmctl}, \func{mmap} (vedi sez.~\ref{sec:proc_mem_lock} e - sez.~\ref{sec:file_memory_map}). \\ + sez.~\ref{sec:file_memory_map}). \\ +% TODO verificare l'interazione con SHM_HUGETLB \const{CAP\_IPC\_OWNER} & Evitare il controllo dei permessi per le operazioni sugli oggetti di intercomunicazione fra processi (vedi diff --git a/ipc.tex b/ipc.tex index 6bfab48..69c6760 100644 --- a/ipc.tex +++ b/ipc.tex @@ -1,4 +1,4 @@ -%% ipc.tex +<%% ipc.tex %% %% Copyright (C) 2000-2013 Simone Piccardi. Permission is granted to %% copy, distribute and/or modify this document under the terms of the GNU Free @@ -2573,19 +2573,47 @@ memoria condivisa. La funzione di sistema che permette di ottenerne uno è già esiste \param{size} è maggiore delle sue dimensioni. \item[\errcode{ENOMEM}] il sistema non ha abbastanza memoria per poter contenere le strutture per un nuovo segmento di memoria condivisa. + \item[\errcode{ENOMEM}] si è specificato \const{IPC\_HUGETLB} ma non si + hanno i privilegi di amministratore. \end{errlist} ed inoltre \errval{EACCES}, \errval{ENOENT}, \errval{EEXIST}, \errval{EIDRM}, con lo stesso significato che hanno per \func{msgget}.} \end{funcproto} -La funzione, come \func{semget}, è del tutto analoga a \func{msgget}, ed -identico è l'uso degli argomenti \param{key} e \param{flag} per cui non -ripeteremo quanto detto al proposito in sez.~\ref{sec:ipc_sysv_mq}. L'argomento -\param{size} specifica invece la dimensione, in byte, del segmento, che viene -comunque arrotondata al multiplo superiore di \const{PAGE\_SIZE}. - -% TODO aggiungere l'uso di SHM_HUGETLB introdotto con il kernel 2.6.0 +La funzione, come \func{semget}, è analoga a \func{msgget}, ed identico è +l'uso degli argomenti \param{key} e \param{flag} per cui non ripeteremo quanto +detto al proposito in sez.~\ref{sec:ipc_sysv_mq}. A partire dal kernel 2.6 +però sono stati introdotti degli ulteriori bit di controllo per +l'argomento \param{flag}, specifici di \func{shmget}, attinenti alle modalità +di gestione del segmento di memoria condivisa in relazione al sistema della +memoria virtuale. + +Il primo dei due flag è \const{SHM\_HUGETLB} che consente di richiedere la +creazione del segmento usando una \itindex{huge~page} \textit{huge page}, le +pagine di memoria di grandi dimensioni introdotte con il kernel 2.6 per +ottimizzare le prestazioni nei sistemi più recenti che hanno grandi quantità +di memoria. L'operazione è privilegiata e richiede che il processo abbia la +\itindex{capability} \textit{capability} \const{CAP\_IPC\_LOCK}. Questa +funzionalità è specifica di Linux e non è portabile. + +Il secondo flag aggiuntivo, introdotto a partire dal kernel 2.6.15, è +\const{SHM\_NORESERVE}, ed ha lo stesso scopo del flag \const{MAP\_NORESERVE} +di \func{mmap} (vedi sez.~\ref{sec:file_memory_map}): non vengono riservate +delle pagine di swap ad uso del meccanismo del \textit{copy on write} +\itindex{copy~on~write} per mantenere le modifiche fatte sul segmento. Questo +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 +deve essere specificato quando si crea un nuovo segmento di memoria con +\const{IPC\_CREAT} o \const{IPC\_PRIVATE}, se invece si accede ad un segmento +di memoria condivisa esistente non può essere maggiore del valore con cui esso +è stato creato. La memoria condivisa è la forma più veloce di comunicazione fra due processi, in quanto permette agli stessi di vedere nel loro spazio di indirizzi una @@ -2679,7 +2707,9 @@ che permettono di cambiarne il valore. pagina di memoria).\\ \const{SHMSEG}& --- & --- & Numero massimo di segmenti di memoria condivisa per ciascun - processo.\\ + processo (l'implementazione non + prevede l'esistenza di questo + limite).\\ \hline @@ -2690,39 +2720,43 @@ che permettono di cambiarne il valore. \label{tab:ipc_shm_limits} \end{table} -Al solito la funzione che permette di effettuare le operazioni di controllo su -un segmento di memoria condivisa è \funcd{shmctl}; il suo prototipo è: -\begin{functions} - \headdecl{sys/ipc.h} - \headdecl{sys/shm.h} - - \funcdecl{int shmctl(int shmid, int cmd, struct shmid\_ds *buf)} - - Esegue le operazioni di controllo su un segmento di memoria condivisa. - - \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di - errore, nel qual caso \var{errno} assumerà i valori: - \begin{errlist} +Al solito la funzione di sistema che permette di effettuare le operazioni di +controllo su un segmento di memoria condivisa è \funcd{shmctl}; il suo +prototipo è: + +\begin{funcproto}{ +\fhead{sys/ipc.h} +\fhead{sys/shm.h} +\fdecl{int shmctl(int shmid, int cmd, struct shmid\_ds *buf)} + +\fdesc{Esegue le operazioni di controllo su un segmento di memoria condivisa.} +} + +{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} assumerà uno dei valori: + \begin{errlist} \item[\errcode{EACCES}] si è richiesto \const{IPC\_STAT} ma i permessi non consentono l'accesso in lettura al segmento. - \item[\errcode{EINVAL}] o \param{shmid} non è un identificatore valido o - \param{cmd} non è un comando valido. + \item[\errcode{EFAULT}] l'indirizzo specificato con \param{buf} non è + valido. \item[\errcode{EIDRM}] l'argomento \param{shmid} fa riferimento ad un segmento che è stato cancellato. - \item[\errcode{EPERM}] si è specificato un comando con \const{IPC\_SET} o - \const{IPC\_RMID} senza i permessi necessari. + \item[\errcode{EINVAL}] o \param{shmid} non è un identificatore valido o + \param{cmd} non è un comando valido. + \item[\errcode{ENOMEM}] si è richiesto un \textit{memory lock} di + dimensioni superiori al massimo consentito. \item[\errcode{EOVERFLOW}] si è tentato il comando \const{IPC\_STAT} ma il valore del \ids{GID} o dell'\ids{UID} è troppo grande per essere memorizzato nella struttura puntata da \param{buf}. - \item[\errcode{EFAULT}] l'indirizzo specificato con \param{buf} non è - valido. - \end{errlist} -} -\end{functions} + \item[\errcode{EPERM}] si è specificato un comando con \const{IPC\_SET} o + \const{IPC\_RMID} senza i permessi necessari. + \end{errlist} +} +\end{funcproto} Il comando specificato attraverso l'argomento \param{cmd} determina i diversi -effetti della funzione; i possibili valori che esso può assumere, ed il -corrispondente comportamento della funzione, sono i seguenti: +effetti della funzione. Nello standard POSIX.1-2001 i valori che esso può +assumere, ed il corrispondente comportamento della funzione, sono i seguenti: \begin{basedescript}{\desclabelwidth{2.2cm}\desclabelstyle{\nextlinelabel}} \item[\const{IPC\_STAT}] Legge le informazioni riguardo il segmento di memoria @@ -2738,17 +2772,29 @@ corrispondente comportamento della funzione, sono i seguenti: \var{shm\_perm.uid} e \var{shm\_perm.gid} occorre essere il proprietario o il creatore del segmento, oppure l'amministratore. Compiuta l'operazione aggiorna anche il valore del campo \var{shm\_ctime}. +\end{basedescript} + +Oltre ai precedenti su Linux sono definiti anche degli ulteriori comandi, che +consentono di estendere le funzionalità, ovviamente non devono essere usati se +si ha a cuore la portabilità. Questi comandi aggiuntivi sono: + +\begin{basedescript}{\desclabelwidth{2.2cm}\desclabelstyle{\nextlinelabel}} \item[\const{SHM\_LOCK}] Abilita il \itindex{memory~locking} \textit{memory - locking}\footnote{impedisce cioè che la memoria usata per il segmento - venga salvata su disco dal meccanismo della \index{memoria~virtuale} - memoria virtuale; si ricordi quanto trattato in - sez.~\ref{sec:proc_mem_lock}.} sul segmento di memoria condivisa. Solo - l'amministratore può utilizzare questo comando. + locking} sul segmento di memoria condivisa, impedendo che la memoria usata + per il segmento venga salvata su disco dal meccanismo della + \index{memoria~virtuale} memoria virtuale. Come illustrato in + 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 + determinato da \const{RLIMIT\_MEMLOCK} (vedi + sez.~\ref{sec:sys_resource_limit}). \item[\const{SHM\_UNLOCK}] Disabilita il \itindex{memory~locking} - \textit{memory locking} sul segmento di memoria condivisa. Solo - l'amministratore può utilizzare questo comando. + \textit{memory locking} sul segmento di memoria condivisa. Fino al kernel + 2.6.9 solo l'amministratore poteva utilizzare questo comando. \end{basedescript} -i primi tre comandi sono gli stessi già visti anche per le code di messaggi e + +I primi tre comandi sono gli stessi già visti anche per le code di messaggi e gli insiemi di semafori, gli ultimi due sono delle estensioni specifiche previste da Linux, che permettono di abilitare e disabilitare il meccanismo della \index{memoria~virtuale} memoria virtuale per il segmento. @@ -4861,11 +4907,11 @@ testo alla terminazione di quest'ultimo. % LocalWords: for now it's break Berlin sources Let's an accidental feature % 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 %%% Local Variables: %%% mode: latex %%% TeX-master: "gapil" %%% End: -% LocalWords: SysV capability short RESOURCE INFO UNDEFINED EFBIG semtimedop -% LocalWords: scan diff --git a/process.tex b/process.tex index a43b810..994c2f6 100644 --- a/process.tex +++ b/process.tex @@ -656,13 +656,13 @@ necessariamente adiacenti. Per la gestione da parte del kernel la memoria viene divisa in pagine di dimensione fissa. Inizialmente queste pagine erano di 4kb sulle macchine a 32 bit e di 8kb sulle alpha. Con le versioni più recenti del kernel è possibile -anche utilizzare pagine di dimensioni maggiori (di 4Mb, dette \textit{huge - page}), per sistemi con grandi quantitativi di memoria in cui l'uso di -pagine troppo piccole comporta una perdita di prestazioni. In alcuni sistemi -la costante \const{PAGE\_SIZE}, definita in \headfile{limits.h}, indica la -dimensione di una pagina in byte, con Linux questo non avviene e per ottenere -questa dimensione si deve ricorrere alla funzione \func{getpagesize} (vedi -sez.~\ref{sec:sys_memory_res}). +anche utilizzare pagine di dimensioni maggiori (di 4Mb, dette +\itindex{huge~page} \textit{huge page}), per sistemi con grandi quantitativi +di memoria in cui l'uso di pagine troppo piccole comporta una perdita di +prestazioni. In alcuni sistemi la costante \const{PAGE\_SIZE}, definita in +\headfile{limits.h}, indica la dimensione di una pagina in byte, con Linux +questo non avviene e per ottenere questa dimensione si deve ricorrere alla +funzione \func{getpagesize} (vedi sez.~\ref{sec:sys_memory_res}). Ciascuna pagina di memoria nello spazio di indirizzi virtuale è associata ad un supporto che può essere una pagina di memoria reale o ad un dispositivo di