From: Simone Piccardi Date: Sun, 25 Mar 2012 15:58:04 +0000 (+0000) Subject: Materiale nei momento liberi X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=commitdiff_plain;h=e2bece451ff1f495d624ca89ad9d065ddd392bc6 Materiale nei momento liberi --- diff --git a/listati/kexec_segment.h b/listati/kexec_segment.h index 54e50ca..a8b7de0 100644 --- a/listati/kexec_segment.h +++ b/listati/kexec_segment.h @@ -1,6 +1,6 @@ - struct kexec_segment { - void *buf; /* Buffer in user space */ - size_t bufsz; /* Buffer length in user space */ - void *mem; /* Physical address of kernel */ - size_t memsz; /* Physical address length */ - }; +struct kexec_segment { + void *buf; /* Buffer in user space */ + size_t bufsz; /* Buffer length in user space */ + void *mem; /* Physical address of kernel */ + size_t memsz; /* Physical address length */ +}; diff --git a/listati/rlimit.h b/listati/rlimit.h index 0b7d797..13f8979 100644 --- a/listati/rlimit.h +++ b/listati/rlimit.h @@ -1,5 +1,4 @@ struct rlimit { rlim_t rlim_cur; /* Soft limit */ rlim_t rlim_max; /* Hard limit (ceiling for rlim_cur) */ - }; diff --git a/process.tex b/process.tex index 4fc31e6..2e06276 100644 --- a/process.tex +++ b/process.tex @@ -737,7 +737,7 @@ accedere. Solitamente un programma C viene suddiviso nei seguenti segmenti: Contiene il codice del programma, delle funzioni di librerie da esso utilizzate, e le costanti. Normalmente viene condiviso fra tutti i processi che eseguono lo stesso programma e nel caso delle librerie anche da processi - che eseguono altri programmi. + che eseguono altri programmi. Quando l'architettura hardware lo supporta viene marcato in sola lettura per evitare sovrascritture accidentali (o maliziose) che ne modifichino le diff --git a/prochand.tex b/prochand.tex index a87e848..52172f5 100644 --- a/prochand.tex +++ b/prochand.tex @@ -335,9 +335,8 @@ valore nullo, che non è il \ids{PID} di nessun processo. Normalmente la chiamata a \func{fork} può fallire solo per due ragioni: o ci sono già troppi processi nel sistema, il che di solito è sintomo che qualcos'altro non sta andando per il verso giusto, o si è ecceduto il limite -sul numero totale di processi permessi all'utente argomento su cui torneremo -in sez.~\ref{sec:sys_resource_limit}, (vedi in particolare -tab.~\ref{tab:sys_rlimit_values}). +sul numero totale di processi permessi all'utente, argomento che tratteremo in +dettaglio in sez.~\ref{sec:sys_resource_limit}. L'uso di \func{fork} avviene secondo due modalità principali; la prima è quella in cui all'interno di un programma si creano processi figli cui viene @@ -1578,7 +1577,8 @@ seguenti proprietà non vengano preservate: \item le mappature dei file in memoria (vedi sez.~\ref{sec:file_memory_map}); \item i segmenti di memoria condivisa SysV (vedi sez.~\ref{sec:ipc_sysv_shm}) e POSIX (vedi sez.~\ref{sec:ipc_posix_shm}); -\item i \textit{memory lock} (vedi sez.~\ref{sec:proc_mem_lock}); +\item i \itindex{memory~locking} \textit{memory lock} (vedi + sez.~\ref{sec:proc_mem_lock}); \item le funzioni registrate all'uscita (vedi sez.~\ref{sec:proc_atexit}); \item i semafori e le code di messaggi POSIX (vedi sez.~\ref{sec:ipc_posix_sem} e sez.~\ref{sec:ipc_posix_mq}); diff --git a/system.tex b/system.tex index 1ea7b2c..9b76399 100644 --- a/system.tex +++ b/system.tex @@ -1289,16 +1289,14 @@ illustra i comandi attualmente disponibili: \end{basedescript} -% TODO trattare reboot, kexec_load, ... - Come appena illustrato usando il comando \const{LINUX\_REBOOT\_CMD\_KEXEC} si può eseguire un riavvio immediato pre-caricando una immagine del kernel, che verrà eseguita direttettamente. Questo meccanismo consente di evitare la reinizializzazione della macchina da parte del BIOS, ed oltre a velocizzare un -eventuale riavvio, ha il vantaggio di non modificare lo stato della macchina e -della memoria, per cui viene usato spesso per installare un kernel di -emergenza da eseguire in caso di crollo del sistema per recuperare il maggior -numero di informazioni possibili. +eventuale riavvio, ha il vantaggio poter accedere allo stato corrente della +macchina e della memoria, per cui viene usato spesso per installare un kernel +di emergenza da eseguire in caso di crollo del sistema per recuperare il +maggior numero di informazioni possibili. La funzione di sistema che consente di caricare questa immagine del kernel è \funcd{kexec\_load}, la funzione non viene definita nella \acr{glibc} e deve @@ -1307,7 +1305,8 @@ pertanto essere invocata con \func{syscall}, il suo prototipo è: \begin{funcproto}{ \fhead{linux/kexec.h} \fdecl{long kexec\_load(unsigned long entry, unsigned long nr\_segments, - struct kexec\_segment *segments, unsigned long flags)} +struct kexec\_segment \phantom{long kexec\_load(}*segments, unsigned long +flags)} \fdesc{Carica un kernel per un riavvio immediato.} } @@ -1316,7 +1315,7 @@ pertanto essere invocata con \func{syscall}, il suo prototipo è: caso \var{errno} assumerà uno dei valori: \begin{errlist} \item[\errcode{EBUSY}] c'è già un caricamento in corso, o un altro kernel è - già stato caricato. + già in uso. \item[\errcode{EINVAL}] il valore di \param{flags} non è valido o si è indicato un valore eccessivo per \param{nr\_segments}. \item[\errcode{EPERM}] il chiamante non ha i privilegi di amministratore (la @@ -1328,11 +1327,9 @@ pertanto essere invocata con \func{syscall}, il suo prototipo è: Il primo argomento indica l'indirizzo fisico di esecuzione del nuovo kernel questo viene caricato usando un vettore di strutture \struct{kexec\_segment} (la cui definizione è riportata in fig.~\ref{fig:kexec_segment}) che -contengono i singoli segmenti dell'immagine. L'argomento \param{flags} è una -maschera binaria che contiene i flag che consentono di indicare alcune -specifiche relative alle modalità con cui dovrà essere eseguito il nuovo -kernel. La parte meno significativa viene usata per impostare l'architettura -di esecuzione +contengono i singoli segmenti dell'immagine. I primi due campi indicano +indirizzo e dimensione del segmento di memoria in \textit{user space}, i +secondi indirizzo e dimensione in \textit{kernel space}. \begin{figure}[!htb] @@ -1347,8 +1344,13 @@ di esecuzione \label{fig:kexec_segment} \end{figure} - - +L'argomento \param{flags} è una maschera binaria che contiene i flag che +consentono di indicare alcune specifiche relative alle modalità con cui dovrà +essere eseguito il nuovo kernel. La parte meno significativa viene usata per +impostare l'architettura di esecuzione, il valore \const{KEXEC\_ARCH\_DEFAULT} +indica l'architettura corrente, ma se ne può specificare anche una diversa, +con i valori della seconda parte di tab.~\ref{tab:kexec_load_flags}, e questa +verrà usato posto che sia effettivamente eseguibile sul proprio processore. \begin{table}[htb] \footnotesize @@ -1358,18 +1360,45 @@ di esecuzione \textbf{Valore} & \textbf{Significato}\\ \hline \hline - \const{KEXEC\_ON\_CRASH} & \\ - \const{KEXEC\_PRESERVE\_CONTEXT}& \\ + \const{KEXEC\_ON\_CRASH} & Il kernel caricato sarà eseguito + automaticamente in caso di crollo del + sistema.\\ + \const{KEXEC\_PRESERVE\_CONTEXT}& Viene preservato lo stato dei programmi + e dei dispositivi prima dell'esecuzione + del nuovo kernel. Viene usato + principalmente per l'ibernazione del + sistema ed ha senso solo se si è + indicato un numero di segmento maggiore + di zero.\\ \hline - \const{KEXEC\_ARCH\_DEFAULT} & \\ - \const{} & \\ + \const{KEXEC\_ARCH\_DEFAULT} & Il kernel caricato verrà eseguito nella + architettura corrente. \\ + \texttt{KEXEC\_ARCH\_XXX} & Il kernel caricato verrà eseguito nella + architettura indicata (con \texttt{XXX} + che può essere: \texttt{386}, + \texttt{X86\_64}, \texttt{PPC}, + \texttt{PPC64}, \texttt{IA\_64}, + \texttt{ARM}, \texttt{S390}, + \texttt{SH}\texttt{MIPS} + e \texttt{MIPS\_LE}).\\ +% \const{} & \\ \hline \end{tabular} \caption{Valori per l'argomento \param{flags} di \func{kexec\_load}.} \label{tab:kexec_load_flags} \end{table} - +I due valori più importanti sono però quelli della parte più significativa +di \param{flags} (riportati nella prima sezione di +tab.~\ref{tab:kexec_load_flags}). Il primo, \const{KEXEC\_ON\_CRASH}, consente +di impostare l'esecuzione automatica del nuovo kernel caricato in caso di +crollo del sistema, e viene usato quando si carica un kernel di emergenza da +utilizzare per poter raccogliere informazioni diagnostiche che altrimenti +verrebbero perdute non essendo il kernel ordinario più in grado di essere +eseguito in maniera coerente. Il secondo valore, +\const{KEXEC\_PRESERVE\_CONTEXT}, indica invece di preservare lo stato dei +programmi e dei dispositivi, e viene in genere usato per realizzare la +cosiddetta ibernazione in RAM. % TODO documentare keyctl ???? % (fare sezione dedicata ????) @@ -1381,12 +1410,12 @@ di esecuzione \label{sec:sys_res_limits} -Dopo aver esaminato le funzioni che permettono di controllare le varie -caratteristiche, capacità e limiti del sistema a livello globale, in questa -sezione tratteremo le varie funzioni che vengono usate per quantificare le -risorse (CPU, memoria, ecc.) utilizzate da ogni singolo processo e quelle che -permettono di imporre a ciascuno di essi vincoli e limiti di -utilizzo. +Dopo aver esaminato in sez.~\ref{sec:sys_management} le funzioni che +permettono di controllare le varie caratteristiche, capacità e limiti del +sistema a livello globale, in questa sezione tratteremo le varie funzioni che +vengono usate per quantificare le risorse (CPU, memoria, ecc.) utilizzate da +ogni singolo processo e quelle che permettono di imporre a ciascuno di essi +vincoli e limiti di utilizzo. \subsection{L'uso delle risorse} @@ -1395,12 +1424,14 @@ utilizzo. Come abbiamo accennato in sez.~\ref{sec:proc_wait} le informazioni riguardo l'utilizzo delle risorse da parte di un processo è mantenuto in una struttura di tipo \struct{rusage}, la cui definizione (che si trova in -\headfile{sys/resource.h}) è riportata in fig.~\ref{fig:sys_rusage_struct}. +\headfile{sys/resource.h}) è riportata in fig.~\ref{fig:sys_rusage_struct}. Si +ricordi che questa è una delle informazioni preservate attraverso una +\func{exec}. \begin{figure}[!htb] \footnotesize \centering - \begin{minipage}[c]{\textwidth} + \begin{minipage}[c]{0.8\textwidth} \includestruct{listati/rusage.h} \end{minipage} \normalsize @@ -1411,23 +1442,30 @@ di tipo \struct{rusage}, la cui definizione (che si trova in La definizione della struttura in fig.~\ref{fig:sys_rusage_struct} è ripresa da BSD 4.3,\footnote{questo non ha a nulla a che fare con il cosiddetto - \textit{BSD accounting} (vedi sez. \ref{sec:sys_bsd_accounting}) che si trova - nelle opzioni di compilazione del kernel (e di norma è disabilitato) che - serve per mantenere una contabilità delle risorse usate da ciascun processo - in maniera molto più dettagliata.} ma attualmente (con i kernel della serie -2.4.x e 2.6.x) i soli campi che sono mantenuti sono: \var{ru\_utime}, -\var{ru\_stime}, \var{ru\_minflt}, \var{ru\_majflt}, e \var{ru\_nswap}. I -primi due indicano rispettivamente il tempo impiegato dal processo -nell'eseguire le istruzioni in user space, e quello impiegato dal kernel nelle -system call eseguite per conto del processo. - -Gli altri tre campi servono a quantificare l'uso della memoria + \textit{BSD accounting} (vedi sez. \ref{sec:sys_bsd_accounting}) che si + trova nelle opzioni di compilazione del kernel (e di norma è disabilitato) + che serve per mantenere una contabilità delle risorse usate da ciascun + processo in maniera molto più dettagliata.} ma attualmente solo alcuni dei +campi definiti sono effettivamente mantenuti. Con i kernel della serie 2.4 i +soli campi che sono mantenuti sono: \var{ru\_utime}, \var{ru\_stime}, +\var{ru\_minflt}, \var{ru\_majflt}, e \var{ru\_nswap}. Con i kernel della +serie 2.6 si aggiungono anche \var{ru\_nvcsw} e \var{ru\_nivcsw}, e a partire +dal 2.6.22 anche \var{ru\_inblock} e \var{ru\_oublock}. + +I campi più utilizzati sono comunque \var{ru\_utime} e \var{ru\_stime} che +indicano rispettivamente il tempo impiegato dal processo nell'eseguire le +istruzioni in user space, e quello impiegato dal kernel nelle \textit{system + call} eseguite per conto del processo. I campi \var{ru\_minflt} e +\var{ru\_majflt} servono a quantificare l'uso della memoria virtuale\index{memoria~virtuale} e corrispondono rispettivamente al numero di \itindex{page~fault} \textit{page fault} (vedi sez.~\ref{sec:proc_mem_gen}) avvenuti senza richiedere I/O su disco (i cosiddetti \textit{minor page fault}), a quelli che invece han richiesto I/O su disco (detti invece -\textit{major page fault}) ed al numero di volte che il processo è stato -completamente tolto dalla memoria per essere inserito nello swap. +\textit{major page fault}), mentre \var{ru\_nswap} ed al numero di volte che +il processo è stato completamente tolto dalla memoria per essere inserito +nello swap. + +% TODO verificare \var{ru\_nswap} non citato nelle pagine di manuali recenti In genere includere esplicitamente \file{} non è più strettamente necessario, ma aumenta la portabilità, e serve comunque quando, come nella @@ -1435,31 +1473,72 @@ maggior parte dei casi, si debba accedere ai campi di \struct{rusage} relativi ai tempi di utilizzo del processore, che sono definiti come strutture di tipo \struct{timeval} (vedi fig.~\ref{fig:sys_timeval_struct}). -Questa è la stessa struttura utilizzata da \func{wait4} (si ricordi quando -visto in sez.~\ref{sec:proc_wait}) per ricavare la quantità di risorse -impiegate dal processo di cui si è letto lo stato di terminazione, ma essa può -anche essere letta direttamente utilizzando la funzione \funcd{getrusage}, il -cui prototipo è: -\begin{functions} - \headdecl{sys/time.h} - \headdecl{sys/resource.h} - \headdecl{unistd.h} - - \funcdecl{int getrusage(int who, struct rusage *usage)} - Legge la quantità di risorse usate da un processo. +La struttura \struct{rusage} è la struttura utilizzata da \func{wait4} (si +ricordi quando visto in sez.~\ref{sec:proc_wait}) per ricavare la quantità di +risorse impiegate dal processo di cui si è letto lo stato di terminazione, ma +essa può anche essere letta direttamente utilizzando la funzione di sistema +\funcd{getrusage}, il cui prototipo è: +\begin{funcproto}{ +\fhead{sys/time.h} +\fhead{sys/resource.h} +\fhead{unistd.h} +\fdecl{int getrusage(int who, struct rusage *usage)} - \bodydesc{La funzione ritorna 0 in caso di successo e -1 in caso di errore, - nel qual caso \var{errno} può essere \errval{EINVAL} o \errval{EFAULT}.} -\end{functions} +\fdesc{Legge la quantità di risorse usate da un processo.} +} -L'argomento \param{who} permette di specificare il processo di cui si vuole -leggere l'uso delle risorse; esso può assumere solo i due valori -\const{RUSAGE\_SELF} per indicare il processo corrente e -\const{RUSAGE\_CHILDREN} per indicare l'insieme dei processi figli di cui si è -ricevuto lo stato di terminazione. +{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{EINVAL}] l'argomento \param{who} non è valido + \end{errlist} + ed inoltre \errval{EFAULT} nel suo significato generico. +} +\end{funcproto} + +La funzione ritorna i valori per l'uso delle risorse nella struttura +\struct{rusage} puntata dall'argomento \param{usage}. L'argomento \param{who} +permette di specificare il soggetto di cui si vuole leggere l'uso delle +risorse; esso può assumere solo i valori illustrati in +tab.~\ref{tab:getrusage_who}, di questi \const{RUSAGE\_THREAD} è specifico di +Linux ed è disponibile solo a partire dal kernel 2.6.26. La funzione è stata +recepita nello standard POSIX.1-2001, che però indica come campi di +\struct{rusage} soltanto \var{ru\_utime} e \var{ru\_stime}. + +\begin{table}[htb] + \footnotesize + \centering + \begin{tabular}[c]{|l|p{8cm}|} + \hline + \textbf{Valore} & \textbf{Significato}\\ + \hline + \hline + \const{RUSAGE\_SELF} & ritorna l'uso delle risorse del processo + corrente, che in caso di uso dei + \textit{thread} ammonta alla somma delle + risorse utilizzate da tutti i \textit{thread} + del processo.\\ + \const{RUSAGE\_CHILDREN} & ritorna l'uso delle risorse dell'insieme dei + processi figli di cui è ricevuto lo stato di + terminazione, che a loro volta comprendono + quelle dei loro figli e così via.\\ + \const{RUSAGE\_THREAD} & ritorna l'uso delle risorse del \textit{thread} + chiamante.\\ + \hline + \end{tabular} + \caption{Valori per l'argomento \param{who} di \func{getrusage}.} + \label{tab:getrusage_who} +\end{table} + +Si tenga conto che per un errore di implementazione nei i kernel precedenti il +2.6.9, nonostante questo fosse esplicitamente proibito dallo standard POSIX.1, +l'uso di \const{RUSAGE\_CHILDREN} comportava l'inserimento dell'ammontare +delle risorse usate dai processi figli anche quando si era impostata una +azione di \const{SIG\_ING} per il segnale \const{SIGCHLD} (per i segnali si +veda cap.~\ref{cha:signals}). Il comportamento è stato corretto per aderire +allo standard a partire dal kernel 2.6.9. -% TODO previsto in futuro \const{RUSAGE\_THREAD}, verificare. \subsection{Limiti sulle risorse} \label{sec:sys_resource_limit} @@ -1467,9 +1546,9 @@ ricevuto lo stato di terminazione. Come accennato nell'introduzione il kernel mette a disposizione delle funzionalità 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. +utilizzo da parte sia dei singoli processi che degli utenti. -Per far questo esistono una serie di risorse e ad ogni processo vengono +Per far questo sono definite 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 @@ -1480,183 +1559,50 @@ essere aumentato dal processo stesso durante l'esecuzione, ciò può però esser fatto solo fino al valore del secondo, che per questo viene detto \textit{hard limit}. -%TODO: tabella troppo grossa, trasformare in lista - -\begin{table}[htb] - \footnotesize - \centering - \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 cosiddetto \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 \itindex{stack} - \textit{stack} il processo riceverà un segnale di - \signal{SIGSEGV}.\\ - \const{RLIMIT\_CORE} & La massima dimensione per di un file di - \itindex{core~dump} \textit{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 \itindex{core~dump} \textit{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 - \signal{SIGXCPU}, la cui azione predefinita (vedi - sez.~\ref{sec:sig_classification}) è terminare - il processo, una volta al secondo fino al - raggiungimento del limite massimo. Il - superamento del limite massimo - comporta l'emissione di un segnale di - \signal{SIGKILL}.\footnotemark\\ - \const{RLIMIT\_DATA} & La massima dimensione del \index{segmento!dati} - 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 - \signal{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 - \itindex{file~locking} \textit{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.\\ -% TODO trattare i seguenti... -% \const{RLIMIT\_MSGQUEUE}& Il numero massimo di \\ -% \const{RLIMIT\_NICE}& Il numero massimo di \\ -% \const{RLIMIT\_RTPRIO}& Il numero massimo di \\ -% aggiungere i limiti che mancano come RLIMIT_RTTIME introdotto con il 2.6.25 -% vedi file include/asm-generic/resource.h - \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 \itindex{stack} - \textit{stack} del processo. Se il processo - esegue operazioni che estendano lo - \textit{stack} oltre questa dimensione - riceverà un segnale di \signal{SIGSEGV}.\\ -% TODO dal 2.6.23 il significato è cambiato, vedi anche man execve - \const{RLIMIT\_RSS} & L'ammontare massimo di pagine di memoria dato al - \index{segmento!testo} testo del processo. Il - limite è solo una indicazione per il kernel, - qualora ci fosse un surplus di memoria questa - verrebbe assegnata.\\ -% TODO: aggiungere a \const{RLIMIT\_STACK} i dati di execve: -% Questi fino al kernel 2.6.23 erano fissi e costituiti da -% 32 pagine di memoria (corrispondenti per la gran parte delle architetture a -% 128kb di dati). Dal 2.6.23 su molte architettire il limite viene stabilito in -% base al valore della risorsa \const{RLIMIT\_STACK} (vedi -% sez.~\ref{sec:sys_resource_limit}), ad un quarto dello spazio da essa -% indicato). Dal 2.6.25 viene comunque garantito uno spazio base di 32 pagine. - -% TODO integrare con la roba di madvise -% TODO integrare con le ultime aggiunte, vedi pagina di manuale - \hline - \end{tabular} - \caption{Valori possibili dell'argomento \param{resource} delle funzioni - \func{getrlimit} e \func{setrlimit}.} - \label{tab:sys_rlimit_values} -\end{table} - -\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 il primo - \signal{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 comporta o l'emissione di uno +specifico segnale o il fallimento della \textit{system call} che lo ha +provocato. A questo comportamento generico fanno eccezione \const{RLIMIT\_CPU} +in cui si ha in comportamento diverso per il superamento dei due limiti e +\const{RLIMIT\_CORE} che influenza soltanto la dimensione (o l'eventuale +creazione) dei file di \itindex{core~dump} \textit{core dump}. -% TODO trattare prlimit64 introdotta con il 2.6.36 che dovrebbe sostituire -% setrlimit +Per permettere di leggere e di impostare i limiti di utilizzo delle risorse da +parte di un processo sono previste due funzioni di sistema, \funcd{getrlimit} +e \funcd{setrlimit}, i cui prototipi sono: +\begin{funcproto}{ +\fhead{sys/time.h} +\fhead{sys/resource.h} +\fhead{unistd.h} +\fdecl{int getrlimit(int resource, struct rlimit *rlim)} +\fdesc{Legge il limite corrente di una risorsa.} +\fdecl{int setrlimit(int resource, const struct rlimit *rlim)} +\fdesc{Imposta il limite di una risorsa.} +} -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'eccezione - \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 - creazione) 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} - \headdecl{unistd.h} - - \funcdecl{int getrlimit(int resource, struct rlimit *rlim)} - - Legge il limite corrente per la risorsa \param{resource}. - - \funcdecl{int setrlimit(int resource, const struct rlimit *rlim)} - - Imposta il limite per la risorsa \param{resource}. - - \bodydesc{Le funzioni ritornano 0 in caso di successo e -1 in caso di - errore, nel qual caso \var{errno} assumerà uno dei valori: - \begin{errlist} +{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} assumerà uno dei valori: + \begin{errlist} \item[\errcode{EINVAL}] i valori per \param{resource} non sono validi. \item[\errcode{EPERM}] un processo senza i privilegi di amministratore ha cercato di innalzare i propri limiti. - \end{errlist} - ed \errval{EFAULT}.} -\end{functions} - + \end{errlist} + ed inoltre \errval{EFAULT} nel suo significato generico. +} +\end{funcproto} -Entrambe le funzioni permettono di specificare, attraverso l'argomento -\param{resource}, su quale risorsa si vuole operare: i possibili valori di -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 +Entrambe le funzioni permettono di specificare attraverso l'argomento +\param{resource} su quale risorsa si vuole operare. L'accesso (rispettivamente +in lettura e scrittura) ai valori effettivi dei limiti viene poi effettuato +attraverso la struttura \struct{rlimit} puntata da \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{figure}[!htb] \footnotesize \centering - \begin{minipage}[c]{\textwidth} + \begin{minipage}[c]{0.8\textwidth} \includestruct{listati/rlimit.h} \end{minipage} \normalsize @@ -1665,17 +1611,185 @@ limite corrente e limite massimo. \label{fig:sys_rlimit_struct} \end{figure} +Come accennato processo ordinario può alzare il proprio limite corrente fino +al valore del limite massimo, può anche ridurre, irreversibilmente, il valore +di quest'ultimo. Nello specificare un limite, oltre a fornire dei valori +specifici, si può anche usare la costante \const{RLIM\_INFINITY} che permette +di sbloccare completamente l'uso di una risorsa; ma si ricordi che solo un +processo con i privilegi di amministratore\footnote{per essere precisi in + questo caso quello che serve è la \itindex{capabilities} \textit{capability} + \const{CAP\_SYS\_RESOURCE} (vedi sez.~\ref{sec:proc_capabilities}).} può +innalzare un limite al di sopra del valore corrente del limite massimo ed +usare un valore qualsiasi per entrambi i limiti. + +Come accennato ciascuna risorsa è identificata da uno specifico valore +dell'argomento \param{resource}, i valori possibili per questo argomento, ed +il significato della risorsa corrispondente, dei rispettivi limiti e gli +effetti causati dal superamento degli stessi sono riportati nel seguente +elenco: + +\begin{basedescript}{\desclabelwidth{2.2cm}}%\desclabelstyle{\nextlinelabel}} +\item[\const{RLIMIT\_AS}] Questa risorsa indica, in byte, la dimensione + massima consentita per la memoria virtuale di un processo, il cosiddetto + \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 \itindex{stack} + \textit{stack} il processo riceverà un segnale di \signal{SIGSEGV}. Dato che + il valore usato è un intero di tipo \ctyp{long} nelle macchine a 32 bit + questo può assumere un valore massimo di 2Gb (anche se la memoria + disponibile può essere maggiore), in tal caso il limite massimo indicabile + resta 2Gb, altrimenti la risorsa si dà per non limitata. + +\item[\const{RLIMIT\_CORE}] Questa risorsa indica, in byte, la massima + dimensione per un file di \itindex{core~dump} \textit{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 nullo si bloccherà la creazione dei \itindex{core~dump} + \textit{core dump}. + +\item[\const{RLIMIT\_CPU}] Questa risorsa indica, in secondi, 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 + \signal{SIGXCPU}, la cui azione predefinita (vedi + sez.~\ref{sec:sig_classification}) è terminare il processo. Il segnale però + può essere intercettato e ignorato, in tal caso esso verrà riemesso una + volta al secondo fino al raggiungimento del limite massimo. Il superamento + del limite massimo comporta comunque l'emissione di un segnale di + \signal{SIGKILL}. Si tenga presente che questo è il comportamento presente + su Linux dai kernel della serie 2.2 ad oggi, altri kernel possono avere + comportamenti diversi per quanto avviene quando viene superato il + \textit{soft limit}, pertanto per avere operazioni portabili è suggerito di + intercettare sempre \signal{SIGXCPU} e terminare in maniera ordinata il + processo con la prima ricezione. + +\item[\const{RLIMIT\_DATA}] Questa risorsa indica, in byte, la massima + dimensione del \index{segmento!dati} 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 eseguita (\func{brk} o \func{sbrk}) con un errore di + \errcode{ENOMEM}. + +\item[\const{RLIMIT\_FSIZE}] Questa risorsa indica, in byte, la massima + dimensione di un file che un processo può usare. Se il processo cerca di + scrivere o di estendere il file oltre questa dimensione riceverà un segnale + di \signal{SIGXFSZ}, che di norma termina il processo. Se questo segnale + viene intercettato la \textit{system call} che ha causato l'errore fallirà + con un errore di \errcode{EFBIG}. + +\item[\const{RLIMIT\_LOCKS}] Questa risorsa indica il numero massimo di + \itindex{file~locking} \textit{file lock} (vedi sez.~\ref{sec:file_locking}) + e di \textit{file lease} (vedi sez.~\ref{sec:file_asyncronous_lease}) che un + processo poteva effettuare. È un limite presente solo nelle prime versioni + del kernel 2.4, pertanto non deve essere più utilizzato. + +\item[\const{RLIMIT\_MEMLOCK}] Questa risorsa indica, in byte, l'ammontare + massimo di memoria che può essere bloccata in RAM da un processo (vedi + sez.~\ref{sec:proc_mem_lock}). Dato che il \itindex{memory~locking} + \textit{memory locking} viene effettuato sulle pagine di memoria, il valore + indicato viene automaticamente arrotondato al primo multiplo successivo + della dimensione di una pagina di memoria. Il limite comporta il fallimento + delle \textit{system call} che eseguono il \textit{memory locking} + (\func{mlock}, \func{mlockall} ed anche, vedi + sez.~\ref{sec:file_memory_map}, \func{mmap} con l'operazione + \const{MAP\_LOCKED}). + + 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}) con \func{shmctl}, che viene contabilizzata + separatamente ma sulla quale viene applicato questo stesso limite. In + precedenza invece questo limite veniva applicato sulla memoria condivisa per + processi con privilegi amministrativi, il limite su questi è stato rimosso e + la semantica della risorsa cambiata. + + +\item[\const{RLIMIT\_MSGQUEUE}] Questa risorsa indica il numero massimo di + byte che possono essere utilizzati da un utente, identificato con + l'\ids{UID} reale del processo chiamante, per le code di messaggi POSIX + (vedi sez.~\ref{sec:ipc_posix_mq}). Per ciascuna coda che viene creata viene + calcolata un'occupazione pari a: +\includecodesnip{listati/mq_occupation.c} +dove \var{attr} è la struttura \struct{mq\_attr} (vedi +fig.~\ref{fig:ipc_mq_attr}) usata nella creazione della coda. Il primo addendo +consente di evitare la creazione di una coda con un numero illimitato di +messaggi vuoti che comunque richiede delle risorse di gestione. Questa risorsa +è stata introdotta con il kernel 2.6.8. + +\item[\const{RLIMIT\_NICE}] Questa risorsa indica il numero massimo a cui può + essere il portato il valore di \textit{nice} (vedi + sez.~\ref{sec:proc_sched_stand}). Dato che non possono essere usati numeri + negativi per specificare un limite, il valore di \textit{nice} viene + calcolato come \code{20-rlim\_cur}. Questa risorsa è stata introdotta con il + kernel 2.6.12. + +\item[\const{RLIMIT\_NOFILE}] Questa risorsa indica il numero massimo di file + che un processo può aprire. Il tentativo di creazione di un ulteriore file + descriptor farà fallire la funzione (\func{open}, \func{dup}, \func{pipe}, + ecc.) con un errore \errcode{EMFILE}. + +\item[\const{RLIMIT\_NPROC}] Questa risorsa indica il numero massimo di + processi che possono essere creati dallo stesso utente, che viene + identificato con l'\ids{UID} reale (vedi sez.~\ref{sec:proc_access_id}) del + processo chiamante. Se il limite viene raggiunto \func{fork} fallirà con un + \errcode{EAGAIN}. + +\item[\const{RLIMIT\_RSS}] Questa risorsa indica, in pagine di memoria, la + dimensione massima della memoria residente (il codiddetto RSS + \itindex{Resident~Set~Size~(RSS)} \textit{Resident Set Size}) cioè + l'ammontare della memoria associata al processo che risiede effettivamente + in RAM (e non a quella eventualmente portata sulla \textit{swap} o non + ancora caricata dal filesystem (per il \index{segmento!testo} segmento testo + del programma). Ha effetto solo sulle chiamate a \func{madvise} con + \const{MADV\_WILLNEED} (vedi sez.~\ref{sec:file_memory_map}). Presente solo + sui i kernel precedenti il 2.4.30. + +\item[\const{RLIMIT\_RTPRIO}] Questa risorsa indica il -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\footnote{per essere precisi in questo caso quello che serve è - la \itindex{capabilities} \textit{capability} \const{CAP\_SYS\_RESOURCE} - (vedi sez.~\ref{sec:proc_capabilities}).} 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 +% TODO trattare i seguenti... +% \const{RLIMIT\_RTPRIO}& Il numero massimo di \\ +% aggiungere i limiti che mancano come RLIMIT_RTTIME introdotto con il 2.6.25 +% vedi file include/asm-generic/resource.h + + +\item[\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.\footnote{il limite su questa + risorsa è stato introdotto con il kernel 2.6.8.} + + +\item[\const{RLIMIT\_RSS}] L'ammontare massimo di pagine di memoria dato al + \index{segmento!testo} testo del processo. Il limite è solo una indicazione + per il kernel, qualora ci fosse un surplus di memoria questa verrebbe + assegnata. + +\item[\const{RLIMIT\_STACK}] La massima dimensione dello \itindex{stack} + \textit{stack} del processo. Se il processo esegue operazioni che estendano + lo \textit{stack} oltre questa dimensione riceverà un segnale di + \signal{SIGSEGV}. + +% TODO dal 2.6.23 il significato è cambiato, vedi anche man execve + +% TODO: aggiungere a \const{RLIMIT\_STACK} i dati di execve: +% Questi fino al kernel 2.6.23 erano fissi e costituiti da +% 32 pagine di memoria (corrispondenti per la gran parte delle architetture a +% 128kb di dati). Dal 2.6.23 su molte architettire il limite viene stabilito in +% base al valore della risorsa \const{RLIMIT\_STACK} (vedi +% sez.~\ref{sec:sys_resource_limit}), ad un quarto dello spazio da essa +% indicato). Dal 2.6.25 viene comunque garantito uno spazio base di 32 pagine. + +% TODO integrare con la roba di madvise +% TODO integrare con le ultime aggiunte, vedi pagina di manuale + +% TODO trattare prlimit64 introdotta con il 2.6.36 che dovrebbe sostituire +% setrlimit + +\end{basedescript} + +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}). @@ -1716,11 +1830,11 @@ pagine di memoria; il suo prototipo è: La funzione è prevista in SVr4, BSD 4.4 e SUSv2, anche se questo ultimo standard la etichetta come obsoleta, mentre lo standard POSIX 1003.1-2001 la -ha eliminata. In Linux è implementata come una system call nelle architetture -in cui essa è necessaria, ed in genere restituisce il valore del simbolo -\const{PAGE\_SIZE} del kernel, che dipende dalla architettura hardware, anche -se le versioni delle librerie del C precedenti le \acr{glibc} 2.1 -implementavano questa funzione restituendo sempre un valore statico. +ha eliminata. In Linux è implementata come una \textit{system call} nelle +architetture in cui essa è necessaria, ed in genere restituisce il valore del +simbolo \const{PAGE\_SIZE} del kernel, che dipende dalla architettura +hardware, anche se le versioni delle librerie del C precedenti le \acr{glibc} +2.1 implementavano questa funzione restituendo sempre un valore statico. % TODO verificare meglio la faccenda di const{PAGE\_SIZE} @@ -1904,9 +2018,9 @@ processo il kernel calcola tre tempi diversi: sez.~\ref{sec:sys_resource_use}. \item[\textit{system time}] il tempo effettivo che il processore ha impiegato - per eseguire codice delle system call nel kernel per conto del processo. È - quello riportato nella risorsa \var{ru\_stime} di \struct{rusage} vista in - sez.~\ref{sec:sys_resource_use}. + per eseguire codice delle \textit{system call} nel kernel per conto del + processo. È quello riportato nella risorsa \var{ru\_stime} di + \struct{rusage} vista in sez.~\ref{sec:sys_resource_use}. \end{basedescript} In genere la somma di \textit{user time} e \textit{system time} indica il