% \subsection{La personalizzazione delle funzioni di allocazione}
% \label{sec:proc_mem_malloc_custom}
+% TODO documentare \func{madvise}
+% TODO documentare \func{mincore}
+% TODO documentare \func{mprotect} forse da mettere insieme a mmap
\subsection{Il controllo della memoria virtuale}
\label{sec:proc_mem_lock}
crittografia richiedono il blocco di alcune pagine di memoria.
\end{itemize}
-\itindbeg{memory~locking}
+\itindbeg{memory~locking}
+
Il meccanismo che previene la paginazione\index{paginazione} di parte della
memoria virtuale di un processo è chiamato \textit{memory locking} (o
\textsl{blocco della memoria}). Il blocco è sempre associato alle pagine della
memoria virtuale del processo, e non al segmento reale di RAM su cui essa
-viene mantenuta.
-
-La regola è che se un segmento di RAM fa da supporto ad almeno una pagina
-bloccata allora esso viene escluso dal meccanismo della
+viene mantenuta. La regola è che se un segmento di RAM fa da supporto ad
+almeno una pagina bloccata allora esso viene escluso dal meccanismo della
paginazione\index{paginazione}. I blocchi non si accumulano, se si blocca due
volte la stessa pagina non è necessario sbloccarla due volte, una pagina o è
-bloccata oppure no.
+bloccata oppure no.
Il \textit{memory lock} persiste fintanto che il processo che detiene la
memoria bloccata non la sblocca. Chiaramente la terminazione del processo
comporta anche la fine dell'uso della sua memoria virtuale, e quindi anche di
tutti i suoi \textit{memory lock}. Infine i \textit{memory lock} non sono
-ereditati dai processi figli.\footnote{ma siccome Linux usa il
+ereditati dai processi figli,\footnote{ma siccome Linux usa il
\itindex{copy~on~write}\textit{copy on write} (vedi
sez.~\ref{sec:proc_fork}) gli indirizzi virtuali del figlio sono mantenuti
sullo stesso segmento di RAM del padre, quindi fintanto che un figlio non
- scrive su un segmento, può usufruire del \textit{memory lock} del padre.}
+ scrive su un segmento, può usufruire del \textit{memory lock} del padre.} e
+vengono automaticamente rimossi se si pone in esecuzione un altro programma
+con \func{exec} (vedi sez.~\ref{sec:proc_exec}).
Siccome la richiesta di un \textit{memory lock} da parte di un processo riduce
la memoria fisica disponibile nel sistema, questo ha un evidente impatto su
-tutti gli altri processi, per cui solo un processo con i privilegi di
-amministratore (vedremo in sez.~\ref{sec:proc_perms} cosa significa) ha la
-capacità di bloccare una pagina. Ogni processo può però sbloccare le pagine
-relative alla propria memoria.
+tutti gli altri processi, per cui fino al kernel 2.6.9 solo un processo con i
+privilegi opportuni (la \itindex{capability}\textit{capability}
+\const{CAP\_IPC\_LOCK}, vedi sez.~\ref{sec:proc_capabilities}) aveva la
+capacità di bloccare una pagina.
Il sistema pone dei limiti all'ammontare di memoria di un processo che può
essere bloccata e al totale di memoria fisica che si può dedicare a questo, lo
standard POSIX.1 richiede che sia definita in \file{unistd.h} la macro
\macro{\_POSIX\_MEMLOCK\_RANGE} per indicare la capacità di eseguire il
-\textit{memory locking} e la costante \const{PAGESIZE} in \file{limits.h} per
-indicare la dimensione di una pagina in byte.
+\textit{memory locking}. Inoltre in alcuni sistemi è definita la costante
+\const{PAGE\_SIZE} in \file{limits.h} per indicare la dimensione di una pagina
+in byte.\footnote{con Linux questo non avviene e si deve ricorrere alla
+ funzione \func{getpagesize}, vedi sez.~\ref{sec:sys_memory_res}.}
+
+
+Con il kernel 2.6.9 anche un processo normale può bloccare la propria
+memoria\footnote{la funzionalità è stata introdotta per non essere costretti a
+ dare privilegi eccessivi a programmi di crittografia, che necessitano di
+ questa funzionalità, ma che devono essere usati da utenti normali.} ma
+mentre un processo privilegiato non ha limiti sulla quantità di memoria che
+può bloccare, un processo normale è soggetto al limite della risorsa
+\const{RLIMIT\_MEMLOCK} (vedi sez.~\ref{sec:sys_resource_limit}). In generale
+poi ogni processo può sbloccare le pagine relative alla propria memoria, se
+però diversi processi bloccano la stessa pagina questa resterà bloccata
+fintanto che ci sarà almeno un processo che la blocca.
Le funzioni per bloccare e sbloccare la paginazione\index{paginazione} di
singole sezioni di memoria sono \funcd{mlock} e \funcd{munlock}; i loro
corrispondono allo spazio di indirizzi del processo o si è ecceduto
il numero massimo consentito di pagine bloccate.
\item[\errcode{EINVAL}] \param{len} non è un valore positivo.
+ \item[\errcode{EPERM}] con un kernel successivo al 2.6.9 il processo non è
+ privilegiato e si un limite nullo per \const{RLIMIT\_MEMLOCK}.
\end{errlist}
e, per \func{mlock}, anche \errval{EPERM} quando il processo non ha i
privilegi richiesti per l'operazione.}
paginazione\index{paginazione} per l'intervallo di memoria specificato dagli
argomenti, che ne indicano nell'ordine l'indirizzo iniziale e la lunghezza.
Tutte le pagine che contengono una parte dell'intervallo bloccato sono
-mantenute in RAM per tutta la durata del blocco.
+mantenute in RAM per tutta la durata del blocco.\footnote{con altri kernel si
+ può ottenere un errore di \errcode{EINVAL} se \param{addr} non è un multiplo
+ della dimensione delle pagine di memoria.}
Altre due funzioni, \funcd{mlockall} e \funcd{munlockall}, consentono di
bloccare genericamente la paginazione\index{paginazione} per l'intero spazio
\funcdecl{int munlockall(void)}
Sblocca la paginazione per lo spazio di indirizzi del processo corrente.
- \bodydesc{Codici di ritorno ed errori sono gli stessi di \func{mlock}
- e \func{munlock}.}
+ \bodydesc{Codici di ritorno ed errori sono gli stessi di \func{mlock} e
+ \func{munlock}, con un kernel successivo al 2.6.9 l'uso di
+ func{munlockall} senza la la \itindex{capability}\textit{capability}
+\const{CAP\_IPC\_LOCK} genera un errore di \errcode{EPERM}.}
\end{functions}
L'argomento \param{flags} di \func{mlockall} permette di controllarne il