From 85a775d4f7a3dae1e72e449f2c05f03170a3295d Mon Sep 17 00:00:00 2001 From: Simone Piccardi Date: Mon, 20 Jun 2005 22:41:33 +0000 Subject: [PATCH] Messi i riferimenti alle capability, corretto ed aggiornato il paragrafo sulla gestione dei limiti delle risorse con gli aggoirnamenti alle modifiche avvenute con il kernel 2.6, aggiornata anche la sezione sul memory locking, sempre per le modifiche del kernel 2.6 --- process.tex | 58 +++++++++---- prochand.tex | 49 ++++++----- signal.tex | 25 +++--- socket.tex | 29 ++++--- system.tex | 236 +++++++++++++++++++++++++++++++-------------------- 5 files changed, 241 insertions(+), 156 deletions(-) diff --git a/process.tex b/process.tex index 7c64e60..37ef2d0 100644 --- a/process.tex +++ b/process.tex @@ -710,6 +710,9 @@ standard descritte in precedenza, che sono costruite su di esse. % \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} @@ -751,42 +754,57 @@ motivi per cui si possono avere di queste necessit 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 @@ -809,6 +827,8 @@ prototipi sono: 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.} @@ -818,7 +838,9 @@ Le due funzioni permettono rispettivamente di bloccare e sbloccare la 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 @@ -832,8 +854,10 @@ di indirizzi di un processo. I prototipi di queste funzioni sono: \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 diff --git a/prochand.tex b/prochand.tex index 9272a20..569e06b 100644 --- a/prochand.tex +++ b/prochand.tex @@ -974,9 +974,10 @@ generato dalla terminazione di un figlio, avremo la certezza che la chiamata a 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}. \\ @@ -995,15 +996,16 @@ generato dalla terminazione di un figlio, avremo la certezza che la chiamata a 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{} ma - questo file non deve mai essere usato direttamente, esso viene incluso - attraverso \file{}.} +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{} ma questo file non deve + mai essere usato direttamente, esso viene incluso attraverso + \file{}.} Lo standard POSIX.1 definisce una serie di macro di preprocessore da usare per analizzare lo stato di uscita. Esse sono definite sempre in @@ -1305,13 +1307,14 @@ problematiche connesse ad una gestione accorta dei privilegi. 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. @@ -1856,10 +1859,10 @@ compila con il flag \cmd{-ansi}, 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} @@ -2184,7 +2187,7 @@ eseguito per primo quello con priorit 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 diff --git a/signal.tex b/signal.tex index 0c11317..66485bb 100644 --- a/signal.tex +++ b/signal.tex @@ -260,10 +260,11 @@ un eventuale messaggio di errore. 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} @@ -346,8 +347,9 @@ colonna standard sono stati indicati anche gli standard in cui ciascun segnale 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 @@ -431,10 +433,10 @@ gestore non ci fosse stato. 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 @@ -515,7 +517,8 @@ segnali sono: \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 diff --git a/socket.tex b/socket.tex index 3cb33d3..92a7564 100644 --- a/socket.tex +++ b/socket.tex @@ -240,7 +240,7 @@ Si tenga presente che non tutte le famiglie di protocolli sono utilizzabili 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} @@ -457,9 +457,9 @@ altrimenti si avr 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 @@ -582,15 +582,16 @@ il file \file{netatalk/at.h}. 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}} @@ -633,7 +634,7 @@ speciale \const{ETH\_P\_ALL} passeranno sul \textit{packet socket} tutti i 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 diff --git a/system.tex b/system.tex index d9b86d2..1efb2b9 100644 --- a/system.tex +++ b/system.tex @@ -1404,42 +1404,133 @@ ricevuto lo stato di terminazione. \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} @@ -1469,73 +1560,34 @@ Entrambe le funzioni permettono di specificare, attraverso l'argomento 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} @@ -1580,6 +1632,8 @@ in cui essa 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: -- 2.30.2