% \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
valutata solo se \val{WIFSIGNALED} ha restituito
un valore non nullo.\\
\macro{WCOREDUMP(s)} & Vera se il processo terminato ha generato un
- file di \textit{core dump}. Può essere valutata
- solo se \val{WIFSIGNALED} ha restituito un valore
- non nullo.\footnotemark \\
+ file di \itindex{core~dump}\textit{core
+ dump}. Può essere valutata solo se
+ \val{WIFSIGNALED} ha restituito un valore non
+ nullo.\footnotemark \\
\macro{WIFSTOPPED(s)} & Vera se il processo che ha causato il ritorno di
\func{waitpid} è bloccato. L'uso è possibile solo
avendo specificato l'opzione \const{WUNTRACED}. \\
presente come estensione sia in Linux che in altri Unix.}
Entrambe le funzioni di attesa restituiscono lo stato di terminazione del
-processo tramite il puntatore \param{status} (se non interessa memorizzare lo
-stato si può passare un puntatore nullo). Il valore restituito da entrambe le
-funzioni dipende dall'implementazione, e tradizionalmente alcuni bit (in
-genere 8) sono riservati per memorizzare lo stato di uscita, e altri per
-indicare il segnale che ha causato la terminazione (in caso di conclusione
-anomala), uno per indicare se è stato generato un core file, ecc.\footnote{le
- definizioni esatte si possono trovare in \file{<bits/waitstatus.h>} ma
- questo file non deve mai essere usato direttamente, esso viene incluso
- attraverso \file{<sys/wait.h>}.}
+processo tramite il puntatore \param{status} (se non interessa memorizzare
+lo stato si può passare un puntatore nullo). Il valore restituito da
+entrambe le funzioni dipende dall'implementazione, e tradizionalmente alcuni
+bit (in genere 8) sono riservati per memorizzare lo stato di uscita, e altri
+per indicare il segnale che ha causato la terminazione (in caso di
+conclusione anomala), uno per indicare se è stato generato un
+\itindex{core~dump}\textit{core dump}, ecc.\footnote{le definizioni esatte
+ si possono trovare in \file{<bits/waitstatus.h>} ma questo file non deve
+ mai essere usato direttamente, esso viene incluso attraverso
+ \file{<sys/wait.h>}.}
Lo standard POSIX.1 definisce una serie di macro di preprocessore da usare per
analizzare lo stato di uscita. Esse sono definite sempre in
Come accennato in sez.~\ref{sec:intro_multiuser} il modello base\footnote{in
realtà già esistono estensioni di questo modello base, che lo rendono più
- flessibile e controllabile, come le \textit{capabilities}, le ACL per i file
- o il \textit{Mandatory Access Control} di SELinux; inoltre basandosi sul
- lavoro effettuato con SELinux, a partire dal kernel 2.5.x, è iniziato lo
- sviluppo di una infrastruttura di sicurezza, il \textit{Linux Security
- Modules}, o LSM, in grado di fornire diversi agganci a livello del kernel
- per modularizzare tutti i possibili controlli di accesso.} di sicurezza di
-un sistema unix-like è fondato sui concetti di utente e gruppo, e sulla
+ flessibile e controllabile, come le
+ \itindex{capability}\textit{capabilities}, le ACL per i file o il
+ \textit{Mandatory Access Control} di SELinux; inoltre basandosi sul lavoro
+ effettuato con SELinux, a partire dal kernel 2.5.x, è iniziato lo sviluppo
+ di una infrastruttura di sicurezza, il \textit{Linux Security Modules}, o
+ LSM, in grado di fornire diversi agganci a livello del kernel per
+ modularizzare tutti i possibili controlli di accesso.} di sicurezza di un
+sistema unix-like è fondato sui concetti di utente e gruppo, e sulla
separazione fra l'amministratore (\textsl{root}, detto spesso anche
\textit{superuser}) che non è sottoposto a restrizioni, ed il resto degli
utenti, per i quali invece vengono effettuati i vari controlli di accesso.
scrivere codice portabile.
-%\subsection{La gestione delle capabilities}
-%\label{sec:proc_capabilities}
-
+\subsection{La gestione delle capabilities}
+\label{sec:proc_capabilities}
+Da fare
\section{La gestione della priorità di esecuzione}
processi con la stessa priorità assoluta questi vengono tenuti in una coda e
tocca al kernel decidere quale deve essere eseguito. Il meccanismo con cui
vengono gestiti questi processi dipende dalla politica di scheduling che si è
-scelto; lo standard ne prevede due:
+scelta; lo standard ne prevede due:
\begin{basedescript}{\desclabelwidth{1.2cm}\desclabelstyle{\nextlinelabel}}
\item[\textit{FIFO}] \textit{First In First Out}. Il processo viene eseguito
fintanto che non cede volontariamente la CPU (con \func{sched\_yield}), si
I segnali che rappresentano errori del programma (divisione per zero o
violazioni di accesso) hanno anche la caratteristica di scrivere un file di
-\textit{core dump} che registra lo stato del processo (ed in particolare della
-memoria e dello stack) prima della terminazione. Questo può essere esaminato
-in seguito con un debugger per investigare sulla causa dell'errore. Lo stesso
-avviene se i suddetti segnali vengono generati con una \func{kill}.
+\itindex{core~dump}\textit{core dump} che registra lo stato del processo (ed
+in particolare della memoria e dello stack) prima della terminazione. Questo
+può essere esaminato in seguito con un debugger per investigare sulla causa
+dell'errore. Lo stesso avviene se i suddetti segnali vengono generati con una
+\func{kill}.
\section{La classificazione dei segnali}
In alcuni casi alla terminazione del processo è associata la creazione di un
file (posto nella directory corrente del processo e chiamato \file{core}) su
cui viene salvata un'immagine della memoria del processo (il cosiddetto
-\textit{core dump}), che può essere usata da un debugger per esaminare lo
-stato dello stack e delle variabili al momento della ricezione del segnale.
+\itindex{core~dump}\textit{core dump}), che può essere usata da un debugger
+per esaminare lo stato dello stack e delle variabili al momento della
+ricezione del segnale.
\begin{table}[htb]
\footnotesize
L'azione predefinita per tutti questi segnali è causare la terminazione del
processo che li ha causati. In genere oltre a questo il segnale provoca pure
-la registrazione su disco di un file di \textit{core dump} che viene scritto
-in un file \file{core} nella directory corrente del processo al momento
-dell'errore, che il debugger può usare per ricostruire lo stato del programma
-al momento della terminazione. Questi segnali sono:
+la registrazione su disco di un file di \itindex{core~dump}\textit{core dump}
+che viene scritto in un file \file{core} nella directory corrente del processo
+al momento dell'errore, che il debugger può usare per ricostruire lo stato del
+programma al momento della terminazione. Questi segnali sono:
\begin{basedescript}{\desclabelwidth{2.0cm}}
\item[\const{SIGFPE}] Riporta un errore aritmetico fatale. Benché il nome
derivi da \textit{floating point exception} si applica a tutti gli errori
\item[\const{SIGQUIT}] È analogo a \const{SIGINT} con la differenza che è
controllato da un altro carattere di controllo, QUIT, corrispondente alla
sequenza \verb|C-\|. A differenza del precedente l'azione predefinita, oltre
- alla terminazione del processo, comporta anche la creazione di un core dump.
+ alla terminazione del processo, comporta anche la creazione di un
+ \itindex{core~dump}\textit{core dump}.
In genere lo si può pensare come corrispondente ad una condizione di
errore del programma rilevata dall'utente. Per questo motivo non è opportuno
dall'utente generico, ad esempio in generale tutti i socket di tipo
\const{SOCK\_RAW} possono essere creati solo da processi che hanno i privilegi
di amministratore (cioè con user-ID effettivo uguale a zero) o dotati della
-capability \const{CAP\_NET\_RAW}.
+\itindex{capability}\textit{capability} \const{CAP\_NET\_RAW}.
\subsection{Il tipo, o stile}
specifica il \textsl{numero di porta}. I numeri di porta sotto il 1024 sono
chiamati \textsl{riservati} in quanto utilizzati da servizi standard e
soltanto processi con i privilegi di amministratore (con user-ID effettivo
-uguale a zero) o con la capability \const{CAP\_NET\_BIND\_SERVICE} possono
-usare la funzione \func{bind} (che vedremo in sez.~\ref{sec:TCP_func_bind}) su
-queste porte.
+uguale a zero) o con la \itindex{capability}\textit{capability}
+\const{CAP\_NET\_BIND\_SERVICE} possono usare la funzione \func{bind} (che
+vedremo in sez.~\ref{sec:TCP_func_bind}) su queste porte.
Il membro \var{sin\_addr} contiene un indirizzo internet, e viene acceduto sia
come struttura (un resto di una implementazione precedente in cui questa era
Il campo \var{sat\_family} deve essere sempre \const{AF\_APPLETALK}, mentre il
campo \var{sat\_port} specifica la porta che identifica i vari servizi. Valori
inferiori a 129 sono usati per le \textsl{porte riservate}, e possono essere
-usati solo da processi con i privilegi di amministratore o con la capability
-\const{CAP\_NET\_BIND\_SERVICE}. L'indirizzo remoto è specificato nella
-struttura \var{sat\_addr}, e deve essere in \textit{network order} (vedi
-sez.~\ref{sec:sock_endianess}); esso è composto da un parte di rete data dal
-campo \var{s\_net}, che può assumere il valore \const{AT\_ANYNET}, che indica
-una rete generica e vale anche per indicare la rete su cui si è, il singolo
-nodo è indicato da \var{s\_node}, e può prendere il valore generico
-\const{AT\_ANYNODE} che indica anche il nodo corrente, ed il valore
-\const{ATADDR\_BCAST} che indica tutti i nodi della rete.
+usati solo da processi con i privilegi di amministratore o con la
+\itindex{capability}\textit{capability} \const{CAP\_NET\_BIND\_SERVICE}.
+L'indirizzo remoto è specificato nella struttura \var{sat\_addr}, e deve
+essere in \textit{network order} (vedi sez.~\ref{sec:sock_endianess}); esso è
+composto da un parte di rete data dal campo \var{s\_net}, che può assumere il
+valore \const{AT\_ANYNET}, che indica una rete generica e vale anche per
+indicare la rete su cui si è, il singolo nodo è indicato da \var{s\_node}, e
+può prendere il valore generico \const{AT\_ANYNODE} che indica anche il nodo
+corrente, ed il valore \const{ATADDR\_BCAST} che indica tutti i nodi della
+rete.
\subsection{La struttura degli indirizzi dei \textit{packet socket}}
pacchetti, qualunque sia il loro protocollo di collegamento. Ovviamente l'uso
di questi socket è una operazione privilegiata e può essere effettuati solo da
un processo con i privilegi di amministratore (user-ID effettivo nullo) o con
-la capability \const{CAP\_NET\_RAW}.
+la \itindex{capability}\textit{capability} \const{CAP\_NET\_RAW}.
Una volta aperto un \textit{packet socket}, tutti i pacchetti del protocollo
specificato passeranno attraverso di esso, qualunque sia l'interfaccia da cui
\subsection{Limiti sulle risorse}
\label{sec:sys_resource_limit}
-Come accennato nell'introduzione oltre a mantenere i dati relativi all'uso
-delle risorse da parte dei vari processi, il kernel mette anche a disposizione
-delle funzioni con cui si possono imporre dei limiti sulle risorse che essi
-possono utilizzare. In generale ad ogni processo vengono associati due
-diversi limiti per ogni risorsa; questi sono detti il \textsl{limite corrente}
-(o \textit{current limit}) che esprime il valore massimo che attualmente il
-processo non può superare, ed il \textsl{limite massimo} (o \textit{maximum
- limit}) che esprime il valore massimo che può assumere il \textsl{limite
- corrente}.
+Come accennato nell'introduzione il kernel mette a disposizione delle
+funzionalita che permettono non solo di mantenere dati statistici relativi
+all'uso delle risorse, ma anche di imporre dei limiti precisi sul loro
+utilizzo da parte dei vari processi o degli utenti.
+
+Per far questo esistono una serie di risorse e ad ogni processo vengono
+associati due diversi limiti per ciascuna di esse; questi sono il
+\textsl{limite corrente} (o \textit{current limit}) che esprime un valore
+massimo che il processo non può superare ad un certo momento, ed il
+\textsl{limite massimo} (o \textit{maximum limit}) che invece esprime il
+valore massimo che può assumere il \textsl{limite corrente}. In generale il
+primo viene chiamato anche \textit{soft limit} dato che il suo valore può
+essere aumentato dal processo stesso durante l'esecuzione, ciò può però essere
+fatto solo fino al valore del secondo, che per questo viene detto \textit{hard
+ limit}.
-\begin{figure}[!htb]
+\begin{table}[htb]
\footnotesize
\centering
- \begin{minipage}[c]{15cm}
- \includestruct{listati/rlimit.h}
- \end{minipage}
- \normalsize
- \caption{La struttura \structd{rlimit} per impostare i limiti di utilizzo
- delle risorse usate da un processo.}
- \label{fig:sys_rlimit_struct}
-\end{figure}
-
-In generale il primo viene chiamato anche \textsl{limite soffice} (o
-\textit{soft limit}) dato che il suo valore può essere aumentato fino al
-valore del secondo, mentre il secondo è detto \textsl{limite duro} (o
-\textit{hard limit}), in quanto un processo normale può solo diminuirne il
-valore. Il valore di questi due limiti è mantenuto in una struttura
-\struct{rlimit}, la cui definizione è riportata in
-fig.~\ref{fig:sys_rlimit_struct}, ed i cui campi corrispondono appunto a
-limite corrente e limite massimo.
+ \begin{tabular}[c]{|l|p{12cm}|}
+ \hline
+ \textbf{Valore} & \textbf{Significato}\\
+ \hline
+ \hline
+ \const{RLIMIT\_AS} & La dimensione massima della memoria virtuale di
+ un processo, il cosidetto \textit{Address
+ Space}, (vedi sez.~\ref{sec:proc_mem_gen}). Se
+ il limite viene superato dall'uso di funzioni
+ come \func{brk}, \func{mremap} o \func{mmap}
+ esse falliranno con un errore di
+ \errcode{ENOMEM}, mentre se il superamento viene
+ causato dalla crescita dello stack il processo
+ riceverà un segnale di \const{SIGSEGV}. \\
+ \const{RLIMIT\_CORE} & La massima dimensione per di un file di
+ \textit{core dump}\itindex{core~dump} (vedi
+ sez.~\ref{sec:sig_prog_error}) creato nella
+ terminazione di un processo; file di dimensioni
+ maggiori verranno troncati a questo valore,
+ mentre con un valore si bloccherà la creazione
+ dei \textit{core dump}\itindex{core~dump}.\\
+ \const{RLIMIT\_CPU} & Il massimo tempo di CPU (vedi
+ sez.~\ref{sec:sys_cpu_times}) che il processo può
+ usare. Il superamento del limite corrente
+ comporta l'emissione di un segnale di
+ \const{SIGXCPU} la cui azione predefinita (vedi
+ sez.~\ref{sec:sig_classification}) è terminare
+ il processo. Il superamento del limite massimo
+ comporta l'emissione di un segnale di
+ \const{SIGKILL}.\footnotemark\\
+ \const{RLIMIT\_DATA} & La massima dimensione del segmento dati di un
+ processo (vedi sez.~\ref{sec:proc_mem_layout}).
+ Il tentativo di allocare più memoria di quanto
+ indicato dal limite corrente causa il fallimento
+ della funzione di allocazione (\func{brk} o
+ \func{sbrk}) con un errore di \errcode{ENOMEM}.\\
+ \const{RLIMIT\_FSIZE} & La massima dimensione di un file che un processo
+ può creare. Se il processo cerca di scrivere
+ oltre questa dimensione riceverà un segnale di
+ \const{SIGXFSZ}, che di norma termina il
+ processo; se questo viene intercettato la
+ system call che ha causato l'errore fallirà con
+ un errore di \errcode{EFBIG}.\\
+ \const{RLIMIT\_LOCKS}& È un limite presente solo nelle prime versioni
+ del kernel 2.4 sul numero massimo di
+ \index{file!lock}\texttt{file lock} (vedi
+ sez.~\ref{sec:file_locking}) che un
+ processo poteva effettuare.\\
+ \const{RLIMIT\_MEMLOCK}& L'ammontare massimo di memoria che può essere
+ bloccata in RAM da un processo (vedi
+ sez.~\ref{sec:proc_mem_lock}). Dal kernel 2.6.9
+ questo limite comprende anche la memoria che può
+ essere bloccata da ciascun utente nell'uso della
+ memoria condivisa (vedi
+ sez.~\ref{sec:ipc_sysv_shm}) che viene
+ contabilizzata separatamente ma sulla quale
+ viene applicato questo stesso limite.\\
+ \const{RLIMIT\_NOFILE} & Il numero massimo di file che il processo può
+ aprire. L'apertura di un ulteriore file farà
+ fallire la funzione (\func{open}, \func{dup} o
+ \func{pipe}) con un errore \errcode{EMFILE}.\\
+ \const{RLIMIT\_NPROC} & Il numero massimo di processi che possono essere
+ creati sullo stesso user id real. Se il limite
+ viene raggiunto \func{fork} fallirà con un
+ \errcode{EAGAIN}.\\
+ \const{RLIMIT\_SIGPENDING}& Il numero massimo di segnali che possono
+ essere mantenuti in coda per ciascun utente,
+ considerando sia i segnali normali che real-time
+ (vedi sez.~\ref{sec:sig_real_time}). Il limite è
+ attivo solo per \func{sigqueue}, con \func{kill}
+ si potrà sempre inviare un segnale che non sia
+ già presente su una coda.\footnotemark\\
+ \const{RLIMIT\_STACK} & La massima dimensione dello stack del
+ processo. Se il processo esegue operazioni che
+ estendano lo stack oltre questa dimensione
+ riceverà un segnale di \const{SIGSEGV}.\\
+ \const{RLIMIT\_RSS} & L'ammontare massimo di pagine di memoria dato al
+ testo del processo. Il limite è solo una
+ indicazione per il kernel, qualora ci fosse un
+ surplus di memoria questa verrebbe assegnata.\\
+% TODO integrare con la roba di madvise
+ \hline
+ \end{tabular}
+ \caption{Valori possibili dell'argomento \param{resource} delle funzioni
+ \func{getrlimit} e \func{setrlimit}.}
+ \label{tab:sys_rlimit_values}
+\end{table}
-In genere il superamento di un limite comporta o l'emissione di un segnale o
-il fallimento della system call che lo ha provocato; per permettere di leggere
-e di impostare i limiti di utilizzo delle risorse da parte di un processo
-Linux prevede due funzioni, \funcd{getrlimit} e \funcd{setrlimit}, i cui
-prototipi sono:
+\footnotetext[18]{questo è quanto avviene per i kernel dalla serie 2.2 fino ad
+ oggi (la 2.6.x); altri kernel possono avere comportamenti diversi per quanto
+ avviene quando viene superato il \textit{soft limit}; perciò per avere
+ operazioni portabili è sempre opportuno intercettare \const{SIGXCPU} e
+ terminare in maniera ordinata il processo.}
+
+\footnotetext{il limite su questa risorsa è stato introdotto con il kernel
+ 2.6.8.}
+
+In generale il superamento di un limite corrente\footnote{di norma quanto
+ riportato in tab.~\ref{tab:sys_rlimit_values} fa riferimento a quanto
+ avviene al superamento del limite corrente, con l'eccesione
+ \const{RLIMIT\_CPU} in cui si ha in comportamento diverso per il superamento
+ dei due limiti.} comporta o l'emissione di un segnale o il fallimento della
+system call che lo ha provocato;\footnote{si nuovo c'è una eccezione per
+ \const{RLIMIT\_CORE} che influenza soltanto la dimensione (o l'eventuale
+ creazinone) dei file di \itindex{core~dump}\textit{core dump}.} per
+permettere di leggere e di impostare i limiti di utilizzo delle risorse da
+parte di un processo sono previste due funzioni, \funcd{getrlimit} e
+\funcd{setrlimit}, i cui prototipi sono:
\begin{functions}
\headdecl{sys/time.h}
\headdecl{sys/resource.h}
questo argomento sono elencati in tab.~\ref{tab:sys_rlimit_values}. L'acceso
(rispettivamente in lettura e scrittura) ai valori effettivi dei limiti viene
poi effettuato attraverso la struttura \struct{rlimit} puntata da
-\param{rlim}.
+\param{rlim}, la cui definizione è riportata in
+fig.~\ref{fig:sys_rlimit_struct}, ed i cui campi corrispondono appunto a
+limite corrente e limite massimo.
-\begin{table}[htb]
+
+\begin{figure}[!htb]
\footnotesize
\centering
- \begin{tabular}[c]{|l|p{12cm}|}
- \hline
- \textbf{Valore} & \textbf{Significato}\\
- \hline
- \hline
- \const{RLIMIT\_CPU} & Il massimo tempo di CPU che il processo può
- usare. Il superamento del limite comporta
- l'emissione di un segnale di \const{SIGXCPU}.\\
- \const{RLIMIT\_FSIZE} & La massima dimensione di un file che un processo
- può usare. Se il processo cerca di scrivere
- oltre questa dimensione riceverà un segnale di
- \const{SIGXFSZ}.\\
- \const{RLIMIT\_DATA} & La massima dimensione della memoria dati di un
- processo. Il tentativo di allocare più memoria
- causa il fallimento della funzione di
- allocazione. \\
- \const{RLIMIT\_STACK} & La massima dimensione dello stack del
- processo. Se il processo esegue operazioni che
- estendano lo stack oltre questa dimensione
- riceverà un segnale di \const{SIGSEGV}.\\
- \const{RLIMIT\_CORE} & La massima dimensione di un file di \textit{core
- dump} creato da un processo. Nel caso le
- dimensioni dovessero essere maggiori il file non
- verrebbe generato.\footnotemark\\
- \const{RLIMIT\_RSS} & L'ammontare massimo di memoria fisica dato al
- processo. Il limite è solo una indicazione per
- il kernel, qualora ci fosse un surplus di
- memoria questa verrebbe assegnata.\\
- \const{RLIMIT\_NPROC} & Il numero massimo di processi che possono essere
- creati sullo stesso user id. Se il limite viene
- raggiunto \func{fork} fallirà con un
- \errcode{EAGAIN}.\\
- \const{RLIMIT\_NOFILE} & Il numero massimo di file che il processo può
- aprire. L'apertura di un ulteriore file fallirà
- con un errore \errcode{EMFILE}.\\
- \const{RLIMIT\_MEMLOCK}& L'ammontare massimo di memoria che può essere
- bloccata in RAM senza
- paginazione\index{paginazione} (vedi
- sez.~\ref{sec:proc_mem_lock}).\\
- \const{RLIMIT\_AS} & La dimensione massima di tutta la memoria che il
- processo può ottenere. Se il processo tenta di
- allocarne di più funzioni come \func{brk},
- \func{malloc} o \func{mmap} falliranno. \\
- \hline
- \end{tabular}
- \caption{Valori possibili dell'argomento \param{resource} delle funzioni
- \func{getrlimit} e \func{setrlimit}.}
- \label{tab:sys_rlimit_values}
-\end{table}
+ \begin{minipage}[c]{15cm}
+ \includestruct{listati/rlimit.h}
+ \end{minipage}
+ \normalsize
+ \caption{La struttura \structd{rlimit} per impostare i limiti di utilizzo
+ delle risorse usate da un processo.}
+ \label{fig:sys_rlimit_struct}
+\end{figure}
-\footnotetext{Impostare questo limite a zero è la maniera più semplice per
- evitare la creazione di \file{core} file (al proposito si veda
- sez.~\ref{sec:sig_prog_error}).}
Nello specificare un limite, oltre a fornire dei valori specifici, si può
anche usare la costante \const{RLIM\_INFINITY} che permette di sbloccare l'uso
di una risorsa; ma si ricordi che solo un processo con i privilegi di
-amministratore può innalzare un limite al di sopra del valore corrente del
-limite massimo. Si tenga conto infine che tutti i limiti vengono ereditati dal
-processo padre attraverso una \func{fork} (vedi sez.~\ref{sec:proc_fork}) e
-mantenuti per gli altri programmi eseguiti attraverso una \func{exec} (vedi
-sez.~\ref{sec:proc_exec}).
+amministratore\footnote{per essere precisi in questo caso quello che serve è
+ la \itindex{capability}\textit{capability} \const{CAP\_SYS\_RESOURCE}.} può
+innalzare un limite al di sopra del valore corrente del limite massimo ed
+usare un valore qualsiasi per entrambi i limiti. Si tenga conto infine che
+tutti i limiti vengono ereditati dal processo padre attraverso una \func{fork}
+(vedi sez.~\ref{sec:proc_fork}) e mantenuti per gli altri programmi eseguiti
+attraverso una \func{exec} (vedi sez.~\ref{sec:proc_exec}).
\subsection{Le risorse di memoria e processore}
precedenti le \acr{glibc} 2.1 implementavano questa funzione restituendo
sempre un valore statico.
+% TODO verificare meglio la faccenda di const{PAGE\_SIZE}
+
Le \acr{glibc} forniscono, come specifica estensione GNU, altre due funzioni,
\funcd{get\_phys\_pages} e \funcd{get\_avphys\_pages} che permettono di
ottenere informazioni riguardo la memoria; i loro prototipi sono: