qualunque processo può a sua volta generarne altri, detti processi figli
(\textit{child process}). Ogni processo è identificato presso il sistema da un
numero univoco, il cosiddetto \textit{process identifier} o, più brevemente,
-\acr{pid}, assegnato in forma progressiva (vedi sez.~\ref{sec:proc_pid}) quando
-il processo viene creato.
+\acr{pid}, assegnato in forma progressiva (vedi sez.~\ref{sec:proc_pid})
+quando il processo viene creato.
Una seconda caratteristica di un sistema Unix è che la generazione di un
processo è un'operazione separata rispetto al lancio di un programma. In
\const{HZ},\footnote{fino al kernel 2.4 il valore usuale di questa costante
era 100, per tutte le architetture eccetto l'alpha, per la quale era 1000,
nel 2.6 è stato portato a 1000 su tutte le architetture; occorre fare
- attenzione a non confondere questo valore con quello dei clock tick (vedi
+ attenzione a non confondere questo valore con quello dei
+ \itindex{clock~tick} \textit{clock tick} (vedi
sez.~\ref{sec:sys_unix_time}).} definita in \file{asm/param.h}, ed il cui
valore è espresso in Hertz.\footnote{a partire dal kernel 2.6.21 è stato
introdotto (a cura di Ingo Molnar) un meccanismo completamente diverso,
Quando un processo ha concluso il suo compito o ha incontrato un errore non
risolvibile esso può essere terminato con la funzione \func{exit} (si veda
quanto discusso in sez.~\ref{sec:proc_conclusion}). La vita del processo però
-termina solo quando la notifica della sua conclusione viene ricevuta dal
-processo padre, a quel punto tutte le risorse allocate nel sistema ad esso
-associate vengono rilasciate.
+termina completamente solo quando la notifica della sua conclusione viene
+ricevuta dal processo padre, a quel punto tutte le risorse allocate nel
+sistema ad esso associate vengono rilasciate.
Avere due processi che eseguono esattamente lo stesso codice non è molto
utile, normalmente si genera un secondo processo per affidargli l'esecuzione
non ritorna mai (in quanto con essa viene eseguito un altro programma).
-
\section{Le funzioni di base}% della gestione dei processi}
\label{sec:proc_handling}
al kernel 2.4.x, sono definiti dalla macro \const{PID\_MAX} in
\file{threads.h} e direttamente in \file{fork.c}, con il kernel 2.5.x e la
nuova interfaccia per i thread creata da Ingo Molnar anche il meccanismo di
- allocazione dei \acr{pid} è stato modificato.} che serve a riservare i
-\acr{pid} più bassi ai processi eseguiti direttamente dal kernel. Per questo
-motivo, come visto in sez.~\ref{sec:proc_hierarchy}, il processo di avvio
-(\cmd{init}) ha sempre il \acr{pid} uguale a uno.
+ allocazione dei \acr{pid} è stato modificato; il valore massimo è
+ impostabile attraverso il file \procfile{/proc/sys/kernel/pid\_max} e di
+ default vale 32768.} che serve a riservare i \acr{pid} più bassi ai processi
+eseguiti direttamente dal kernel. Per questo motivo, come visto in
+sez.~\ref{sec:proc_hierarchy}, il processo di avvio (\cmd{init}) ha sempre il
+\acr{pid} uguale a uno.
Tutti i processi inoltre memorizzano anche il \acr{pid} del genitore da cui
sono stati creati, questo viene chiamato in genere \acr{ppid} (da
senza specificare attese (come si può notare in (\texttt{\small 17--19}) i
valori predefiniti specificano di non attendere), otterremo come output sul
terminale:
-
\footnotesize
\begin{verbatim}
[piccardi@selidor sources]$ export LD_LIBRARY_PATH=./; ./forktest 3
\normalsize
Esaminiamo questo risultato: una prima conclusione che si può trarre è che non
-si può dire quale processo fra il padre ed il figlio venga eseguito per
-primo\footnote{a partire dal kernel 2.5.2-pre10 è stato introdotto il nuovo
- \itindex{scheduler} \textit{scheduler} di Ingo Molnar che esegue sempre per
- primo il figlio; per mantenere la portabilità è opportuno non fare comunque
- affidamento su questo comportamento.} dopo la chiamata a \func{fork};
-dall'esempio si può notare infatti come nei primi due cicli sia stato eseguito
-per primo il padre (con la stampa del \acr{pid} del nuovo processo) per poi
-passare all'esecuzione del figlio (completata con i due avvisi di esecuzione
-ed uscita), e tornare all'esecuzione del padre (con la stampa del passaggio al
-ciclo successivo), mentre la terza volta è stato prima eseguito il figlio
-(fino alla conclusione) e poi il padre.
+si può dire quale processo fra il padre ed il figlio venga eseguito per primo
+dopo la chiamata a \func{fork}; dall'esempio si può notare infatti come nei
+primi due cicli sia stato eseguito per primo il padre (con la stampa del
+\acr{pid} del nuovo processo) per poi passare all'esecuzione del figlio
+(completata con i due avvisi di esecuzione ed uscita), e tornare
+all'esecuzione del padre (con la stampa del passaggio al ciclo successivo),
+mentre la terza volta è stato prima eseguito il figlio (fino alla conclusione)
+e poi il padre.
In generale l'ordine di esecuzione dipenderà, oltre che dall'algoritmo di
\itindex{scheduler} scheduling usato dal kernel, dalla particolare situazione
rischio di incorrere nelle cosiddette \itindex{race~condition} \textit{race
condition} (vedi sez.~\ref{sec:proc_race_cond}).
+In realtà a partire dal kernel 2.5.2-pre10 il nuovo \itindex{scheduler}
+\textit{scheduler} di Ingo Molnar esegue sempre per primo il
+figlio;\footnote{i risultati precedenti sono stati ottenuti usando un kernel
+ della serie 2.4.} questa è una ottimizzazione che serve a evitare che il
+padre, effettuando per primo una operazione di scrittura in memoria, attivi il
+meccanismo del \itindex{copy~on~write} \textit{copy on write}. Questa
+operazione infatti potrebbe risultare del tutto inutile qualora il figlio
+fosse stato creato solo per eseguire una \func{exec}, in tal caso infatti si
+invocherebbe un'altro proramma scartando completamente lo spazio degli
+indirizzi, rendendo superflua la copia della memoria modificata dal padre.
+
+Eseguendo sempre per primo il figlio la \func{exec} verrebbe effettuata subito
+avendo così la certezza che il \itindex{copy~on~write} \textit{copy on write}
+viene utilizzato solo quando necessario. Quanto detto in precedenza vale
+allora soltanto per i kernel fino al 2.4; per mantenere la portabilità è però
+opportuno non fare affidamento su questo comportamento, che non si riscontra
+in altri Unix e nelle versioni del kernel precendenti a quella indicata.
+
Si noti inoltre che essendo i segmenti di memoria utilizzati dai singoli
processi completamente separati, le modifiche delle variabili nei processi
figli (come l'incremento di \var{i} in \texttt{\small 31}) sono visibili solo
quello dell'interazione dei vari processi con i file; per illustrarlo meglio
proviamo a redirigere su un file l'output del nostro programma di test, quello
che otterremo è:
-
\footnotesize
\begin{verbatim}
[piccardi@selidor sources]$ ./forktest 3 > output
quanto c'è nel buffer delle funzioni di I/O, comprese le linee scritte dal
padre fino allora. Così quando il buffer viene scritto su disco all'uscita del
figlio, troveremo nel file anche tutto quello che il processo padre aveva
-scritto prima della sua creazione. E alla fine del file (dato che in questo
+scritto prima della sua creazione. E alla fine del file (dato che in questo
caso il padre esce per ultimo) troveremo anche l'output completo del padre.
L'esempio ci mostra un altro aspetto fondamentale dell'interazione con i file,
Ma abbiamo accennato che oltre alla conclusione normale esistono anche delle
modalità di conclusione anomala; queste sono in sostanza due: il programma può
chiamare la funzione \func{abort} per invocare una chiusura anomala, o essere
-terminato da un segnale. In realtà anche la prima modalità si riconduce alla
-seconda, dato che \func{abort} si limita a generare il segnale
-\const{SIGABRT}.
+terminato da un segnale (torneremo sui segnali in cap.~\ref{cha:signals}). In
+realtà anche la prima modalità si riconduce alla seconda, dato che
+\func{abort} si limita a generare il segnale \const{SIGABRT}.
Qualunque sia la modalità di conclusione di un processo, il kernel esegue
comunque una serie di operazioni: chiude tutti i file aperti, rilascia la
terminato (si potrebbe avere cioè quello che si chiama un processo
\textsl{orfano}).
+% TODO verificare il reparenting
+
Questa complicazione viene superata facendo in modo che il processo orfano
venga \textsl{adottato} da \cmd{init}. Come già accennato quando un processo
termina, il kernel controlla se è il padre di altri processi in esecuzione: in
cui riportare il suo stato di terminazione. Come verifica di questo
comportamento possiamo eseguire il nostro programma \cmd{forktest} imponendo a
ciascun processo figlio due secondi di attesa prima di uscire, il risultato è:
-
\footnotesize
\begin{verbatim}
[piccardi@selidor sources]$ ./forktest -c2 3
adottarli e provvedere a concluderne la terminazione.
-\subsection{Le funzioni \func{wait} e \func{waitpid}}
+\subsection{La funzione \func{waitpid} e le funzioni di ricezione degli stati
+ di uscita}
\label{sec:proc_wait}
Uno degli usi più comuni delle capacità multitasking di un sistema unix-like
processi figli. Si è già sottolineato al paragrafo precedente come in questo
caso diventi necessario gestire esplicitamente la conclusione dei figli onde
evitare di riempire di \index{zombie} \textit{zombie} la tabella dei processi;
-le funzioni deputate a questo compito sono sostanzialmente due, \funcd{wait} e
+le funzioni deputate a questo compito sono principalmente due, \funcd{wait} e
\func{waitpid}. La prima, il cui prototipo è:
\begin{functions}
\headdecl{sys/types.h}
\funcd{waitpid} che effettua lo stesso servizio, ma dispone di una serie di
funzionalità più ampie, legate anche al controllo di sessione (si veda
sez.~\ref{sec:sess_job_control}). Dato che è possibile ottenere lo stesso
-comportamento di \func{wait}\footnote{in effetti eseguire il codice
- \code{wait(\&s)} è del tutto equivalente a \code{waitpid(WAIT\_ANY}, \&s,
- 0)}. } si consiglia di utilizzare sempre questa funzione, il cui prototipo
-è:
+comportamento di \func{wait}\footnote{in effetti il codice
+ \code{wait(\&status)} è del tutto equivalente a \code{waitpid(WAIT\_ANY,
+ \&status, 0)}.} si consiglia di utilizzare sempre questa funzione, il cui
+prototipo è:
\begin{functions}
\headdecl{sys/types.h}
\headdecl{sys/wait.h}
è stata specificata l'opzione \const{WNOHANG} e il processo non è uscito e
-1 per un errore, nel qual caso \var{errno} assumerà i valori:
\begin{errlist}
- \item[\errcode{EINTR}] se non è stata specificata l'opzione \const{WNOHANG} e
+ \item[\errcode{EINTR}] non è stata specificata l'opzione \const{WNOHANG} e
la funzione è stata interrotta da un segnale.
\item[\errcode{ECHILD}] il processo specificato da \param{pid} non esiste o
non è figlio del processo chiamante.
+ \item[\errcode{EINVAL}] si è specificato un valore non valido per
+ l'argomento \param{options}.
\end{errlist}}
\end{functions}
-Le differenze principali fra le due funzioni sono che \func{wait} si blocca
-sempre fino a che un processo figlio non termina, mentre \func{waitpid} ha la
-possibilità si specificare un'opzione \const{WNOHANG} che ne previene il
-blocco; inoltre \func{waitpid} può specificare in maniera flessibile quale
-processo attendere, sulla base del valore fornito dall'argomento \param{pid},
-secondo lo specchietto riportato in tab.~\ref{tab:proc_waidpid_pid}.
+La prima differenza fra le due funzioni è che con \func{waitpid} si può
+specificare in maniera flessibile quale processo attendere, sulla base del
+valore fornito dall'argomento \param{pid}, questo può assumere diversi valori,
+secondo lo specchietto riportato in tab.~\ref{tab:proc_waidpid_pid}, dove si
+sono riportate anche le costanti definite per indicare alcuni di essi.
\begin{table}[!htb]
\centering
\textbf{Valore} & \textbf{Costante} &\textbf{Significato}\\
\hline
\hline
- $<-1$& -- & attende per un figlio il cui
+ $<-1$& -- & Attende per un figlio il cui
\itindex{process~group} \textit{process group}
(vedi sez.~\ref{sec:sess_proc_group}) è uguale
al valore assoluto di \param{pid}. \\
- $-1$& \const{WAIT\_ANY} & attende per un figlio qualsiasi, usata in
- questa maniera è equivalente a \func{wait}.\\
- $0$ &\const{WAIT\_MYPGRP}&attende per un figlio il cui
- \itindex{process~group} \textit{process group} è
+ $-1$&\const{WAIT\_ANY} & Attende per un figlio qualsiasi, usata in
+ questa maniera senza specificare nessuna opzione
+ è equivalente a \func{wait}.\\
+ $ 0$&\const{WAIT\_MYPGRP}&Attende per un figlio il cui
+ \itindex{process~group} \textit{process group}
+ (vedi sez.~\ref{sec:sess_proc_group}) è
uguale a quello del processo chiamante. \\
- $>0$& -- & attende per un figlio il cui \acr{pid} è uguale
+ $>0$& -- & Attende per un figlio il cui \acr{pid} è uguale
al valore di \param{pid}.\\
\hline
\end{tabular}
\label{tab:proc_waidpid_pid}
\end{table}
-Il comportamento di \func{waitpid} può inoltre essere modificato passando
-delle opportune opzioni tramite l'argomento \param{option}. I valori possibili
-sono il già citato \const{WNOHANG}, che previene il blocco della funzione
-quando il processo figlio non è terminato, e \const{WUNTRACED} che permette di
-tracciare i processi bloccati. Il valore dell'opzione deve essere specificato
-come maschera binaria ottenuta con l'OR delle suddette costanti con zero.
-
-In genere si utilizza \const{WUNTRACED} all'interno del controllo di sessione,
-(l'argomento è trattato in sez.~\ref{sec:sess_job_control}). In tal caso
-infatti la funzione ritorna, restituendone il \acr{pid}, quando c'è un
-processo figlio che è entrato in stato di sleep (vedi
-tab.~\ref{tab:proc_proc_states}) e del quale non si è ancora letto lo stato
-(con questa stessa opzione). In Linux sono previste altre opzioni non standard
-relative al comportamento con i thread, che riprenderemo in
-sez.~\ref{sec:thread_xxx}.
-
-La terminazione di un processo figlio è chiaramente un evento asincrono
-rispetto all'esecuzione di un programma e può avvenire in un qualunque
-momento. Per questo motivo, come accennato nella sezione precedente, una delle
-azioni prese dal kernel alla conclusione di un processo è quella di mandare un
-segnale di \const{SIGCHLD} al padre. L'azione predefinita (si veda
+Il comportamento di \func{waitpid} può inoltre essere modificato passando alla
+funzione delle opportune opzioni tramite l'argomento \param{options}; questo
+deve essere specificato come maschera binaria dei flag riportati in
+tab.~\ref{tab:proc_waitpid_options},\footnote{oltre a queste in Linux sono
+ previste del altre opzioni non standard, relative al comportamento con i
+ thread, che riprenderemo in sez.~\ref{sec:thread_xxx}.} che possono essere
+combinati fra loro con un OR aritmetico.
+
+L'uso dell'opzione \const{WNOHANG} consente di prevenire il blocco della
+funzione qualora nessun figlio sia uscito (o non si siano verificate le altre
+condizioni per l'uscita della funzione); in tal caso la funzione ritornerà un
+valore nullo anziché positivo.\footnote{anche in questo caso un valore
+ positivo indicherà il \acr{pid} del processo di cui si è ricevuto lo stato
+ ed un valore negativo un errore.}
+
+\begin{table}[!htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|p{8cm}|}
+ \hline
+ \textbf{Macro} & \textbf{Descrizione}\\
+ \hline
+ \hline
+ \const{WNOHANG} & La funzione ritorna immediatamente anche se non è
+ terminato nessun processo figlio. \\
+ \const{WUNTRACED} & Ritorna anche se un processo figlio è stato fermato. \\
+ \const{WCONTINUED}& Ritorna anche quando un processo figlio che era stato
+ fermato ha ripreso l'esecuzione.\footnotemark \\
+ \hline
+ \end{tabular}
+ \caption{Costanti che identificano i bit dell'argomento \param{options}
+ della funzione \func{waitpid}.}
+ \label{tab:proc_waitpid_options}
+\end{table}
+
+\footnotetext{disponibile solo a partire dal kernel 2.6.10.}
+
+Le altre due opzioni \const{WUNTRACED} e \const{WCONTINUED} consentono
+rispettivamente di tracciare non la terminazione di un processo, ma il fatto
+che esso sia stato fermato, o fatto ripartire, e sono utilizzate per la
+gestione del controllo di sessione (vedi sez.~\ref{sec:sess_job_control}).
+
+Nel caso di \const{WUNTRACED} la funzione ritorna, restituendone il \acr{pid},
+quando un processo figlio entra nello stato \textit{stopped}\footnote{in
+ realtà viene notificato soltanto il caso in cui il processo è stato fermato
+ da un segnale di stop (vedi sez.~\ref{sec:sess_ctrl_term}), e non quello in
+ cui lo stato \textit{stopped} è dovuto all'uso di \func{ptrace} (vedi
+ sez.~\ref{sec:xxx_ptrace}).} (vedi tab.~\ref{tab:proc_proc_states}), mentre
+con \const{WCONTINUED} la funzione ritorna quando un processo in stato
+\textit{stopped} riprende l'esecuzione per la ricezione del segnale
+\const{SIGCONT} (l'uso di questi segnali per il controllo di sessione è
+dettagliato in sez.~\ref{sec:sess_ctrl_term}).
+
+La terminazione di un processo figlio (così come gli altri eventi osservabili
+con \func{waitpid}) è chiaramente un evento asincrono rispetto all'esecuzione
+di un programma e può avvenire in un qualunque momento. Per questo motivo,
+come accennato nella sezione precedente, una delle azioni prese dal kernel
+alla conclusione di un processo è quella di mandare un segnale di
+\const{SIGCHLD} al padre. L'azione predefinita (si veda
sez.~\ref{sec:sig_base}) per questo segnale è di essere ignorato, ma la sua
generazione costituisce il meccanismo di comunicazione asincrona con cui il
kernel avverte il processo padre che uno dei suoi figli è terminato.
-In genere in un programma non si vuole essere forzati ad attendere la
-conclusione di un processo per proseguire, specie se tutto questo serve solo
-per leggerne lo stato di chiusura (ed evitare la presenza di \index{zombie}
-\textit{zombie}), per questo la modalità più usata per chiamare queste
-funzioni è quella di utilizzarle all'interno di un \textit{signal handler}
-(vedremo un esempio di come gestire \const{SIGCHLD} con i segnali in
-sez.~\ref{sec:sig_example}). In questo caso infatti, dato che il segnale è
-generato dalla terminazione di un figlio, avremo la certezza che la chiamata a
-\func{wait} non si bloccherà.
+Il comportamento delle funzioni è però cambiato nel passaggio dal kernel 2.4
+al kernel 2.6, quest'ultimo infatti si è adeguato alle prescrizioni dello
+standard POSIX.1-2001,\footnote{una revisione del 2001 dello standard POSIX.1
+ che ha aggiunto dei requisiti e delle nuove funzioni, come \func{waitid}.}
+e come da esso richiesto se \const{SIGCHLD} viene ignorato, o se si imposta il
+flag di \const{SA\_NOCLDSTOP} nella ricezione dello stesso (si veda
+sez.~\ref{sec:sig_sigaction}) i processi figli che terminano non diventano
+\textit{zombie} e sia \func{wait} che \func{waitpid} si bloccano fintanto che
+tutti i processi figli non sono terminati, dopo di che falliscono con un
+errore di \errcode{ENOCHLD}.\footnote{questo è anche il motivo per cui le
+ opzioni \const{WUNTRACED} e \const{WCONTINUED} sono utilizzabili soltanto
+ qualora non si sia impostato il flag di \const{SA\_NOCLDSTOP} per il segnale
+ \const{SIGCHLD}.}
+
+Con i kernel della serie 2.4 e tutti i kernel delle serie precedenti entrambe
+le funzioni di attesa ignorano questa prescrizione\footnote{lo standard POSIX.1
+ originale infatti lascia indefinito il comportamento di queste funzioni
+ quando \const{SIGCHLD} viene ignorato.} e si comportano sempre nello stesso
+modo, indipendentemente dal fatto \const{SIGCHLD} sia ignorato o meno:
+attendono la terminazione di un processo figlio e ritornano il relativo
+\acr{pid} e lo stato di terminazione nell'argomento \param{status}.
+
+In generale in un programma non si vuole essere forzati ad attendere la
+conclusione di un processo figlio per proseguire l'esecuzione, specie se tutto
+questo serve solo per leggerne lo stato di chiusura (ed evitare eventualmente
+la presenza di \index{zombie} \textit{zombie}). Per questo la modalità più
+comune di chiamare queste funzioni è quella di utilizzarle all'interno di un
+\textit{signal handler} (vedremo un esempio di come gestire \const{SIGCHLD}
+con i segnali in sez.~\ref{sec:sig_example}). In questo caso infatti, dato che
+il segnale è generato dalla terminazione di un figlio, avremo la certezza che
+la chiamata a \func{waitpid} non si bloccherà.
+
+Come accennato sia \func{wait} che \func{waitpid} 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, ma
+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
+\file{<sys/wait.h>} ed elencate in tab.~\ref{tab:proc_status_macro} (si tenga
+presente che queste macro prendono come parametro la variabile di tipo
+\ctyp{int} puntata da \param{status}).
\begin{table}[!htb]
\centering
\footnotesize
- \begin{tabular}[c]{|c|p{10cm}|}
+ \begin{tabular}[c]{|l|p{10cm}|}
\hline
\textbf{Macro} & \textbf{Descrizione}\\
\hline
\macro{WEXITSTATUS(s)} & Restituisce gli otto bit meno significativi dello
stato di uscita del processo (passato attraverso
\func{\_exit}, \func{exit} o come valore di
- ritorno di \func{main}). Può essere valutata solo
+ ritorno di \func{main}); può essere valutata solo
se \val{WIFEXITED} ha restituito un valore non
nullo.\\
- \macro{WIFSIGNALED(s)} & Vera se il processo figlio è terminato
+ \macro{WIFSIGNALED(s)} & Condizione vera se il processo figlio è terminato
in maniera anomala a causa di un segnale che non
è stato catturato (vedi
sez.~\ref{sec:sig_notification}).\\
\macro{WTERMSIG(s)} & Restituisce il numero del segnale che ha causato
- la terminazione anomala del processo. Può essere
+ la terminazione anomala del processo; può essere
valutata solo se \val{WIFSIGNALED} ha restituito
un valore non nullo.\\
\macro{WCOREDUMP(s)} & Vera se il processo terminato ha generato un
file di \itindex{core~dump} \textit{core
- dump}. Può essere valutata solo se
+ 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}. \\
+ \func{waitpid} è bloccato; l'uso è possibile solo
+ con \func{waitpid} avendo specificato l'opzione
+ \const{WUNTRACED}.\\
\macro{WSTOPSIG(s)} & Restituisce il numero del segnale che ha bloccato
- il processo. Può essere valutata solo se
+ il processo; può essere valutata solo se
\val{WIFSTOPPED} ha restituito un valore non
nullo. \\
+ \macro{WIFCONTINUED(s)}& Vera se il processo che ha causato il ritorno è
+ stato riavviato da un
+ \const{SIGCONT}.\footnotemark \\
\hline
\end{tabular}
\caption{Descrizione delle varie macro di preprocessore utilizzabili per
\label{tab:proc_status_macro}
\end{table}
-\footnotetext{questa macro non è definita dallo standard POSIX.1, ma è
- 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
-\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>}.}
+\footnotetext[18]{questa macro non è definita dallo standard POSIX.1-2001, ma è
+ presente come estensione sia in Linux che in altri Unix, deve essere
+ pertanto utilizzata con attenzione (ad esempio è il caso di usarla in un
+ blocco \texttt{\#ifdef WCOREDUMP ... \#endif}.}
-Lo standard POSIX.1 definisce una serie di macro di preprocessore da usare per
-analizzare lo stato di uscita. Esse sono definite sempre in
-\file{<sys/wait.h>} ed elencate in tab.~\ref{tab:proc_status_macro} (si tenga
-presente che queste macro prendono come parametro la variabile di tipo
-\ctyp{int} puntata da \param{status}).
+\footnotetext{è presente solo a partire dal kernel 2.6.10.}
Si tenga conto che nel caso di conclusione anomala il valore restituito da
\val{WTERMSIG} può essere confrontato con le costanti definite in
\file{signal.h} ed elencate in tab.~\ref{tab:sig_signal_list}, e stampato
usando le apposite funzioni trattate in sez.~\ref{sec:sig_strsignal}.
-Linux, seguendo un'estensione di BSD, supporta altre due funzioni per la
-lettura dello stato di terminazione di un processo, analoghe alle precedenti
-ma che prevedono un ulteriore argomento attraverso il quale il kernel può
-restituire al padre informazioni sulle risorse usate dal processo terminato e
-dai vari figli. Le due funzioni sono \funcd{wait3} e \funcd{wait4}, che
-diventano accessibili definendo la macro \macro{\_USE\_BSD}; i loro prototipi
-sono:
+A partire dal kernel 2.6.9, sempre in conformità allo standard POSIX.1-2001, è
+stata introdotta una nuova funzione di attesa che consente di avere un
+controllo molto più preciso sui possibili cambiamenti di stato dei processi
+figli e più dettagli sullo stato di uscita; la funzione è \funcd{waitid} ed il
+suo prototipo è:
+\begin{functions}
+ \headdecl{sys/types.h}
+
+ \headdecl{sys/wait.h}
+
+ \funcdecl{int waitid(idtype\_t idtype, id\_t id, siginfo\_t *infop, int
+ options)}
+
+ Attende la conclusione di un processo figlio.
+
+ \bodydesc{La funzione restituisce 0 in caso di successo e -1 per un errore,
+ nel qual caso \var{errno} assumerà i valori:
+ \begin{errlist}
+ \item[\errcode{EINTR}] se non è stata specificata l'opzione \const{WNOHANG} e
+ la funzione è stata interrotta da un segnale.
+ \item[\errcode{ECHILD}] il processo specificato da \param{pid} non esiste o
+ non è figlio del processo chiamante.
+ \item[\errcode{EINVAL}] si è specificato un valore non valido per
+ l'argomento \param{options}.
+ \end{errlist}}
+\end{functions}
+
+La funzione prevede che si specifichi quali processi si intendono osservare
+usando i due argomenti \param{idtype} ed \param{id}; il primo indica se si
+vuole porsi in attesa su un singolo processo, un gruppo di processi o un
+processo qualsiasi, e deve essere specificato secondo uno dei valori di
+tab.~\ref{tab:proc_waitid_idtype}; il secondo indica, a seconda del valore del
+primo, quale processo o quale gruppo di processi selezionare.
+
+
+\begin{table}[!htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|p{8cm}|}
+ \hline
+ \textbf{Macro} & \textbf{Descrizione}\\
+ \hline
+ \hline
+ \const{P\_PID} & Indica la richiesta di attendere per un processo figlio
+ il cui \acr{pid} corrisponda al valore dell'argomento
+ \param{id}.\\
+ \const{P\_PGID}& Indica la richiesta di attendere per un processo figlio
+ appartenente al \textit{process group} (vedi
+ sez.~\ref{sec:sess_proc_group}) il cui \acr{pgid}
+ corrisponda al valore dell'argomento \param{id}.\\
+ \const{P\_ALL} & Indica la richiesta di attendere per un processo figlio
+ generico, il valore dell'argomento \param{id} viene
+ ignorato.\\
+ \hline
+ \end{tabular}
+ \caption{Costanti per i valori dell'argomento \param{idtype} della funzione
+ \func{waitid}.}
+ \label{tab:proc_waitid_idtype}
+\end{table}
+
+Come per \func{waitpid} anche il comportamento di \func{waitid} viene
+controllato dall'argomento \param{options}, da specificare come maschera
+binaria dei valori riportati in tab.~\ref{tab:proc_waitid_options}. Benché
+alcuni di questi siano identici come significato ed effetto ai precedenti di
+tab.~\ref{tab:proc_waitpid_options}, ci sono delle differenze significative:
+in questo caso si dovrà specificare esplicitamente l'attesa della terminazione
+di un processo impostando l'opzione \const{WEXITED}, mentre il precedente
+\const{WUNTRACED} è sostituito da \const{WSTOPPED}. Infine è stata aggiunta
+l'opzione \const{WNOWAIT} che consente una lettura dello stato mantenendo il
+processo in attesa di ricezione, così che una successiva chiamata possa di
+nuovo riceverne lo stato.
+
+\begin{table}[!htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|p{8cm}|}
+ \hline
+ \textbf{Macro} & \textbf{Descrizione}\\
+ \hline
+ \hline
+ \const{WEXITED} & Ritorna quando un processo figlio è terminato.\\
+ \const{WNOHANG} & Ritorna immediatamente anche se non c'è niente da
+ notificare.\\
+ \const{WSTOPPED} & Ritorna quando un processo figlio è stato fermato.\\
+ \const{WCONTINUED}& Ritorna quando un processo figlio che era stato
+ fermato ha ripreso l'esecuzione.\\
+ \const{WNOWAIT} & Lascia il processo ancora in attesa di ricezione, così
+ che una successiva chiamata possa di nuovo riceverne
+ lo stato.\\
+ \hline
+ \end{tabular}
+ \caption{Costanti che identificano i bit dell'argomento \param{options}
+ della funzione \func{waitid}.}
+ \label{tab:proc_waitid_options}
+\end{table}
+
+La funzione \func{waitid} restituisce un valore nullo in caso di successo, e
+$-1$ in caso di errore; viene restituito un valore nullo anche se è stata
+specificata l'opzione \const{WNOHANG} e la funzione è ritornata immediatamente
+senza che nessun figlio sia terminato. Pertanto per verificare il motivo del
+ritorno della funzione occorre analizzare le informazioni che essa
+restituisce; queste, al contrario delle precedenti \func{wait} e
+\func{waitpid}, sono ritornate nella struttura di tipo \struct{siginfo\_t}
+(vedi fig.~\ref{fig:sig_siginfo_t}) all'indirizzo puntato dall'argomento
+\param{infop}.
+
+Tratteremo nei dettagli questa struttura ed il significato dei suoi vari campi
+in sez.~\ref{sec:sig_sigaction}, per quanto ci interessa qui basta dire che al
+ritorno di \func{waitid} verranno avvalorati i seguenti campi:
+\begin{basedescript}{\desclabelwidth{2.0cm}}
+\item[\var{si\_pid}] con il \acr{pid} del figlio.
+\item[\var{si\_uid}] con l'user-ID reale (vedi sez.~\ref{sec:proc_perms}) del
+ figlio.
+\item[\var{si\_signo}] con \const{SIGCHLD}.
+\item[\var{si\_status}] con lo stato di uscita del figlio o con il segnale che
+ lo ha terminato, fermato o riavviato.
+\item[\var{si\_code}] con uno fra \const{CLD\_EXITED}, \const{CLD\_KILLED},
+ \const{CLD\_STOPPED}, \const{CLD\_CONTINUED} (vedi tab.~\ref{xxx_si_code}).
+\end{basedescript}
+
+%TODO mettere riferimento alla tabella giusta (vedere man credentials e man
+% waitid)
+
+Infine Linux, seguendo un'estensione di BSD, supporta altre due funzioni per
+la lettura dello stato di terminazione di un processo, analoghe alle
+precedenti ma che prevedono un ulteriore argomento attraverso il quale il
+kernel può restituire al padre informazioni sulle risorse usate dal processo
+terminato e dai vari figli. Le due funzioni sono \funcd{wait3} e
+\funcd{wait4}, che diventano accessibili definendo la macro
+\macro{\_USE\_BSD}; i loro prototipi sono:
\begin{functions}
\headdecl{sys/times.h} \headdecl{sys/types.h} \headdecl{sys/wait.h}
\headdecl{sys/resource.h}
sez.~\ref{sec:sys_resource_use}) per ottenere le risorse di sistema usate da un
processo; la sua definizione è riportata in fig.~\ref{fig:sys_rusage_struct}.
-
-\subsection{Le funzioni \func{exec}}
+\subsection{La funzione \func{exec} e le funzioni di esecuzione dei programmi}
\label{sec:proc_exec}
Abbiamo già detto che una delle modalità principali con cui si utilizzano i
\item il tempo restante ad un allarme (vedi sez.~\ref{sec:sig_alarm_abort});
\item la directory radice e la directory di lavoro corrente (vedi
sez.~\ref{sec:file_work_dir});
-\item la maschera di creazione dei file (\var{umask}, vedi
+\item la maschera di creazione dei file \itindex{umask} (\textit{umask}, vedi
sez.~\ref{sec:file_perm_management}) ed i \textit{lock} sui file (vedi
sez.~\ref{sec:file_locking});
\item i segnali sospesi (\textit{pending}) e la maschera dei segnali (si veda
del programma per caricare le librerie necessarie ed effettuare il link
dell'eseguibile. Se il programma è in formato ELF per caricare le librerie
dinamiche viene usato l'interprete indicato nel segmento \const{PT\_INTERP},
-in genere questo è \file{/lib/ld-linux.so.1} per programmi collegati con le
-\acr{libc5}, e \file{/lib/ld-linux.so.2} per programmi collegati con le
+in genere questo è \sysfile{/lib/ld-linux.so.1} per programmi collegati con le
+\acr{libc5}, e \sysfile{/lib/ld-linux.so.2} per programmi collegati con le
\acr{glibc}.
Infine nel caso il file sia uno script esso deve iniziare con una linea nella
lunga restituisce un errore di \const{ENAMETOOLONG}, una comparazione dei
vari comportamenti si trova su
\href{http://www.in-ulm.de/~mascheck/various/shebang/}
- {\texttt{http://www.in-ulm.de/\tild mascheck/various/shebang/}}.}
+ {\textsf{http://www.in-ulm.de/\tild mascheck/various/shebang/}}.}
Con la famiglia delle \func{exec} si chiude il novero delle funzioni su cui è
basata la gestione dei processi in Unix: con \func{fork} si crea un nuovo
realtà già esistono estensioni di questo modello base, che lo rendono più
flessibile e controllabile, come le \itindex{capabilities}
\textit{capabilities} illustrate in sez.~\ref{sec:proc_capabilities}, le ACL
- per i file o il \itindex{Mandatory~Access~Control~(MAC)} \textit{Mandatory
- Access Control} di SELinux; inoltre basandosi sul lavoro effettuato con
+ per i file (vedi sez.~\ref{sec:file_ACL}) o il
+ \itindex{Mandatory~Access~Control~(MAC)} \textit{Mandatory Access Control}
+ di \index{SELinux} 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.
+ infrastruttura di sicurezza, i \itindex{Linux~Security~Modules}
+ \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.
Abbiamo già accennato come il sistema associ ad ogni utente e gruppo due
identificatori univoci, lo user-ID ed il group-ID; questi servono al kernel per
\hline
\hline
\acr{uid} & \textit{real} & \textsl{user-ID reale}
- & indica l'utente che ha lanciato il programma\\
+ & Indica l'utente che ha lanciato il programma.\\
\acr{gid} & '' &\textsl{group-ID reale}
- & indica il gruppo principale dell'utente che ha lanciato
- il programma \\
+ & Indica il gruppo principale dell'utente che ha lanciato
+ il programma.\\
\hline
\acr{euid} & \textit{effective} &\textsl{user-ID effettivo}
- & indica l'utente usato nel controllo di accesso \\
+ & Indica l'utente usato nel controllo di accesso.\\
\acr{egid} & '' & \textsl{group-ID effettivo}
- & indica il gruppo usato nel controllo di accesso \\
+ & Indica il gruppo usato nel controllo di accesso.\\
-- & -- & \textsl{group-ID supplementari}
- & indicano gli ulteriori gruppi cui l'utente appartiene \\
+ & Indicano gli ulteriori gruppi cui l'utente appartiene.\\
\hline
-- & \textit{saved} & \textsl{user-ID salvato}
- & è una copia dell'\acr{euid} iniziale\\
+ & È una copia dell'\acr{euid} iniziale.\\
-- & '' & \textsl{group-ID salvato}
- & è una copia dell'\acr{egid} iniziale \\
+ & È una copia dell'\acr{egid} iniziale.\\
\hline
\acr{fsuid} & \textit{filesystem} &\textsl{user-ID di filesystem}
- & indica l'utente effettivo per l'accesso al filesystem \\
+ & Indica l'utente effettivo per l'accesso al filesystem. \\
\acr{fsgid} & '' & \textsl{group-ID di filesystem}
- & indica il gruppo effettivo per l'accesso al filesystem \\
+ & Indica il gruppo effettivo per l'accesso al filesystem.\\
\hline
\end{tabular}
\caption{Identificatori di utente e gruppo associati a ciascun processo con
ed eventualmente tornare indietro.
Come esempio per chiarire l'uso di queste funzioni prendiamo quello con cui
-viene gestito l'accesso al file \file{/var/log/utmp}. In questo file viene
+viene gestito l'accesso al file \sysfile{/var/log/utmp}. In questo file viene
registrato chi sta usando il sistema al momento corrente; chiaramente non può
essere lasciato aperto in scrittura a qualunque utente, che potrebbe
falsificare la registrazione. Per questo motivo questo file (e l'analogo
-\file{/var/log/wtmp} su cui vengono registrati login e logout) appartengono ad
-un gruppo dedicato (\acr{utmp}) ed i programmi che devono accedervi (ad
+\sysfile{/var/log/wtmp} su cui vengono registrati login e logout) appartengono
+ad un gruppo dedicato (\acr{utmp}) ed i programmi che devono accedervi (ad
esempio tutti i programmi di terminale in X, o il programma \cmd{screen} che
crea terminali multipli su una console) appartengono a questo gruppo ed hanno
il bit \acr{sgid} impostato.
\textsl{group-ID salvato} &=& \textrm{\acr{utmp}}
\end{eqnarray*}
in questo modo, dato che il \textsl{group-ID effettivo} è quello giusto, il
-programma può accedere a \file{/var/log/utmp} in scrittura ed aggiornarlo. A
-questo punto il programma può eseguire una \code{setgid(getgid())} per
+programma può accedere a \sysfile{/var/log/utmp} in scrittura ed aggiornarlo.
+A questo punto il programma può eseguire una \code{setgid(getgid())} per
impostare il \textsl{group-ID effettivo} a quello dell'utente (e dato che il
\textsl{group-ID reale} corrisponde la funzione avrà successo), in questo modo
non sarà possibile lanciare dal terminale programmi che modificano detto file,
\end{eqnarray*}
e ogni processo lanciato dal terminale avrebbe comunque \acr{gid} come
\textsl{group-ID effettivo}. All'uscita dal terminale, per poter di nuovo
-aggiornare lo stato di \file{/var/log/utmp} il programma eseguirà una
+aggiornare lo stato di \sysfile{/var/log/utmp} il programma eseguirà una
\code{setgid(utmp)} (dove \var{utmp} è il valore numerico associato al gruppo
\acr{utmp}, ottenuto ad esempio con una precedente \func{getegid}), dato che
in questo caso il valore richiesto corrisponde al \textsl{group-ID salvato} la
\textsl{group-ID effettivo} &=& \textrm{\acr{utmp}} \\
\textsl{group-ID salvato} &=& \textrm{\acr{utmp} (invariato)}
\end{eqnarray*}
-consentendo l'accesso a \file{/var/log/utmp}.
+consentendo l'accesso a \sysfile{/var/log/utmp}.
Occorre però tenere conto che tutto questo non è possibile con un processo con
i privilegi di amministratore, in tal caso infatti l'esecuzione di una
\end{functions}
La funzione esegue la scansione del database dei gruppi (usualmente
-\file{/etc/groups}) cercando i gruppi di cui è membro l'utente \param{user}
+\conffile{/etc/group}) cercando i gruppi di cui è membro l'utente \param{user}
con cui costruisce una lista di gruppi supplementari, a cui aggiunge anche
\param{group}, infine imposta questa lista per il processo corrente usando
\func{setgroups}. Si tenga presente che sia \func{setgroups} che
ma non essendo implementata non ne tratteremo qui.} in modo da poter
stabilire quali capacità possono essere utilizzate quando viene messo in
esecuzione uno specifico programma; attualmente però questa funzionalità non è
-implementata.\footnote{per attualmente si intende fino al kernel 2.6.13, e
- finora non è disponibile al momento neanche presente nessuna realizzazione
- sperimentale delle specifiche POSIX.1e, anche se esistono dei patch di
- sicurezza del kernel, come LIDS (vedi
- \href{http://www.lids.org}{\texttt{http://www.lids.org/})} che realizzano
- qualcosa di simile.}
+implementata.\footnote{per attualmente si intende fino al kernel 2.6.23;
+ benché l'infrastruttura per crearla sia presente (vedi anche
+ sez.~\ref{sec:file_xattr}) finora non è disponibile nessuna realizzazione
+ delle specifiche POSIX.1e, esistono però dei patch di sicurezza del kernel,
+ come LIDS (vedi \href{http://www.lids.org}{\textsf{http://www.lids.org/})}
+ che realizzano qualcosa di simile.}
+
+% TODO verificare per process capability bounding set, vedi:
+% http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=3b7391de67da515c91f48aa371de77cb6cc5c07e
\begin{table}[!h!bt]
%
% POSIX-draft defined capabilities.
%
- \const{CAP\_CHOWN} & la capacità di cambiare proprietario e gruppo
+ \const{CAP\_CHOWN} & La capacità di cambiare proprietario e gruppo
proprietario di un file (vedi
sez.~\ref{sec:file_ownership_management}).\\
- \const{CAP\_DAC\_OVERRIDE}& la capacità di evitare il controllo dei
+ \const{CAP\_DAC\_OVERRIDE}& La capacità di evitare il controllo dei
permessi di lettura, scrittura ed esecuzione dei
file, (vedi sez.~\ref{sec:file_access_control})
caratteristici del modello classico del
\itindex{Discrectionary~Access~Control~(DAC)}
\textit{Discrectionary Access Control} (da cui
il nome DAC).\\
- \const{CAP\_DAC\_READ\_SEARCH}& la capacità di evitare il controllo dei
+ \const{CAP\_DAC\_READ\_SEARCH}& La capacità di evitare il controllo dei
permessi di lettura, scrittura ed esecuzione per
le directory (vedi
sez.~\ref{sec:file_access_control}).\\
- \const{CAP\_FOWNER} & la capacità di evitare il controllo che
+ \const{CAP\_FOWNER} & La capacità di evitare il controllo che
l'user-ID effettivo del processo (o meglio il
\textit{filesystem user-ID}, vedi
sez.~\ref{sec:proc_setuid}) coincida con
\func{open} e \func{fcntl} (vedi
sez.~\ref{sec:file_open} e
sez.~\ref{sec:file_fcntl}).\\
- \const{CAP\_FSETID} & la capacità di evitare la cancellazione
+ \const{CAP\_FSETID} & La capacità di evitare la cancellazione
automatica dei bit \itindex{suid~bit} \acr{suid}
e \itindex{sgid~bit} \acr{sgid} quando un file
per i quali sono impostati viene modificato da
quando questo è relativo ad un gruppo cui non si
appartiene (vedi
sez.~\ref{sec:file_perm_management}).\\
- \const{CAP\_KILL} & la capacità di mandare segnali a qualunque
+ \const{CAP\_KILL} & La capacità di mandare segnali a qualunque
processo (vedi sez.~\ref{sec:sig_kill_raise}).\\
- \const{CAP\_SETGID} & la capacità di manipolare i group ID dei
+ \const{CAP\_SETGID} & La capacità di manipolare i group ID dei
processi, sia il principale che i supplementari,
(vedi sez.~\ref{sec:proc_setgroups} che quelli
trasmessi tramite i socket \textit{unix domain}
(vedi sez.~\ref{sec:unix_socket}).\\
- \const{CAP\_SETUID} & la capacità di manipolare gli user ID del
+ \const{CAP\_SETUID} & La capacità di manipolare gli user ID del
processo (con \func{setuid}, \func{setreuid},
\func{setresuid}, \func{setfsuid}) e di
trasmettere un valore arbitrario
% Linux specific capabilities
%
\hline
- \const{CAP\_SETPCAP} & la capacità di impostare o rimuovere una capacità
+ \const{CAP\_SETPCAP} & La capacità di impostare o rimuovere una capacità
(limitatamente a quelle che il processo
chiamante ha nel suo insieme di capacità
permesse) da qualunque processo.\\
- \const{CAP\_LINUX\_IMMUTABLE}& la capacità di impostare gli attributi
+% TODO cambiata nel 2.4.24 rc1 ?
+ \const{CAP\_LINUX\_IMMUTABLE}& La capacità di impostare gli attributi
\textit{immutable} e \itindex{append~mode}
\textit{append only} per i file su un
filesystem che supporta questi
attributi estesi.\\
- \const{CAP\_NET\_BIND\_SERVICE}& la capacità di porre in ascolto server
+ \const{CAP\_NET\_BIND\_SERVICE}& La capacità di porre in ascolto server
su porte riservate (vedi
sez.~\ref{sec:TCP_func_bind}).\\
- \const{CAP\_NET\_BROADCAST}& la capacità di consentire l'uso di socket in
+ \const{CAP\_NET\_BROADCAST}& La capacità di consentire l'uso di socket in
\itindex{broadcast} \textit{broadcast} e
\itindex{multicast} \textit{multicast}.\\
- \const{CAP\_NET\_ADMIN} & la capacità di eseguire alcune operazioni
+ \const{CAP\_NET\_ADMIN} & La capacità di eseguire alcune operazioni
privilegiate sulla rete (impostare le opzioni
privilegiate dei socket, abilitare il
\itindex{multicast} \textit{multicasting},
impostare interfacce di rete e
tabella di instradamento).\\
- \const{CAP\_NET\_RAW} & la capacità di usare socket \texttt{RAW} e
+ \const{CAP\_NET\_RAW} & La capacità di usare socket \texttt{RAW} e
\texttt{PACKET} (quelli che permettono di creare
pacchetti nei protocolli di basso livello).\\
- \const{CAP\_IPC\_LOCK} & la capacità di effettuare il \textit{memory
+ \const{CAP\_IPC\_LOCK} & La capacità di effettuare il \textit{memory
locking} \itindex{memory~locking} con le
funzioni \func{mlock}, \func{mlockall},
\func{shmctl}, \func{mmap} (vedi
sez.~\ref{sec:proc_mem_lock} e
sez.~\ref{sec:file_memory_map}). \\
- \const{CAP\_IPC\_OWNER} & la capacità di evitare il controllo dei permessi
+ \const{CAP\_IPC\_OWNER} & La capacità di evitare il controllo dei permessi
per le operazioni sugli oggetti di
intercomunicazione fra processi (vedi
sez.~\ref{sec:ipc_sysv}).\\
- \const{CAP\_SYS\_MODULE}& la capacità di caricare e rimuovere moduli del
+ \const{CAP\_SYS\_MODULE}& La capacità di caricare e rimuovere moduli del
kernel. \\
- \const{CAP\_SYS\_RAWIO} & la capacità di eseguire operazioni sulle porte
+ \const{CAP\_SYS\_RAWIO} & La capacità di eseguire operazioni sulle porte
di I/O con \func{ioperm} e \func{iopl} (vedi
sez.~\ref{sec:file_io_port}).\\
- \const{CAP\_SYS\_CHROOT}& la capacità di eseguire la funzione
+ \const{CAP\_SYS\_CHROOT}& La capacità di eseguire la funzione
\func{chroot} (vedi
sez.~\ref{sec:file_chroot}).\\
- \const{CAP\_SYS\_PTRACE}& consente di tracciare qualunque processo con
+ \const{CAP\_SYS\_PTRACE}& Consente di tracciare qualunque processo con
\func{ptrace} (vedi
sez.~\ref{sec:xxx_ptrace}).\\
-% TODO documentatare ptrace
- \const{CAP\_SYS\_PACCT} & la capacità di usare le funzioni di
+ \const{CAP\_SYS\_PACCT} & La capacità di usare le funzioni di
\textit{accounting} dei processi (vedi
sez.~\ref{sec:sys_bsd_accounting}).\\
- \const{CAP\_SYS\_ADMIN} & la capacità di eseguire una serie di compiti
+ \const{CAP\_SYS\_ADMIN} & La capacità di eseguire una serie di compiti
amministrativi (come impostare le quote,
attivare e disattivare la swap, montare,
rimontare e smontare filesystem, ecc.). \\
- \const{CAP\_SYS\_BOOT} & la capacità di fare eseguire un riavvio del
+ \const{CAP\_SYS\_BOOT} & La capacità di fare eseguire un riavvio del
sistema.\\
- \const{CAP\_SYS\_NICE} & la capacità di modificare le priorità dei
+ \const{CAP\_SYS\_NICE} & La capacità di modificare le priorità dei
processi (vedi sez.~\ref{sec:proc_priority}). \\
- \const{CAP\_SYS\_RESOURCE}& la capacità di superare le limitazioni sulle
+ \const{CAP\_SYS\_RESOURCE}& La capacità di superare le limitazioni sulle
risorse, aumentare le quote disco, usare lo
spazio disco riservato all'amministratore.\\
- \const{CAP\_SYS\_TIME} & la capacità di modificare il tempo di sistema
+ \const{CAP\_SYS\_TIME} & La capacità di modificare il tempo di sistema
(vedi sez.~\ref{sec:sys_time}).\\
- \const{CAP\_SYS\_TTY\_CONFIG}& la capacità di simulare un \textit{hangup}
+ \const{CAP\_SYS\_TTY\_CONFIG}& La capacità di simulare un \textit{hangup}
della console, con la funzione
\func{vhangup}.\\
- \const{CAP\_MKNOD} & la capacità di creare file di dispositivo con la
+ \const{CAP\_MKNOD} & La capacità di creare file di dispositivo con la
funzione \func{mknod} (vedi
sez.~\ref{sec:file_mknod}).\footnotemark\\
- \const{CAP\_LEASE} & la capacità di creare dei \textit{file lease}
+ \const{CAP\_LEASE} & La capacità di creare dei \textit{file lease}
\index{file!lease} su di un file (vedi
sez.~\ref{sec:file_asyncronous_lease})
indipendentemente dalla proprietà dello
stesso.\footnotemark\\
- \const{CAP\_SETFCAP} & la capacità di impostare le
+ \const{CAP\_SETFCAP} & La capacità di impostare le
\textit{capabilities} di un file (non
supportata).\\
\hline
capacità in esso elencate.
Il \textit{capabilities bounding set} è un parametro di sistema, accessibile
-attraverso il contenuto del file \file{/proc/sys/kernel/cap-bound}, che per
+attraverso il contenuto del file \procfile{/proc/sys/kernel/cap-bound}, che per
questa sua caratteristica consente di impostare un limite generale alle
capacità che possono essere accordate ai vari processi. Questo valore può
essere impostato ad un valore arbitrario esclusivamente dal primo processo
% TODO documentare prctl ...
+% TODO: rivedere alla luce degli aggiornamenti del 2.6 (man sched_setscheduler)
+
\section{La gestione della priorità di esecuzione}
\label{sec:proc_priority}
\label{tab:proc_proc_states}
\end{table}
+% TODO nel 2.6.25 è stato aggiunto TASK_KILLABLE, da capire dova va messo.
+
Si deve quindi tenere presente che l'utilizzo della CPU è soltanto una delle
risorse che sono necessarie per l'esecuzione di un programma, e a seconda
dello scopo del programma non è detto neanche che sia la più importante (molti
vengono gestiti questi processi dipende dalla politica di scheduling che si è
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
+\item[\textsf{FIFO}] \textit{First In First Out}. Il processo viene eseguito
fintanto che non cede volontariamente la CPU (con \func{sched\_yield}), si
blocca, finisce o viene interrotto da un processo a priorità più alta. Se il
processo viene interrotto da uno a priorità più alta esso resterà in cima
più alta diverranno inattivi. Se invece lo si blocca volontariamente sarà
posto in coda alla lista (ed altri processi con la stessa priorità potranno
essere eseguiti).
-\item[\textit{RR}] \textit{Round Robin}. Il comportamento è del tutto analogo
+\item[\textsf{RR}] \textit{Round Robin}. Il comportamento è del tutto analogo
a quello precedente, con la sola differenza che ciascun processo viene
eseguito al massimo per un certo periodo di tempo (la cosiddetta
\textit{time slice}) dopo di che viene automaticamente posto in fondo alla
\textbf{Policy} & \textbf{Significato} \\
\hline
\hline
- \const{SCHED\_FIFO} & Scheduling real-time con politica \textit{FIFO} \\
+ \const{SCHED\_FIFO} & Scheduling real-time con politica \textit{FIFO}. \\
\const{SCHED\_RR} & Scheduling real-time con politica \textit{Round
- Robin} \\
- \const{SCHED\_OTHER}& Scheduling ordinario\\
+ Robin}. \\
+ \const{SCHED\_OTHER}& Scheduling ordinario.\\
+ \const{SCHED\_BATCH}& Scheduling ordinario con l'assunzione ulteriore di
+ lavoro \textit{CPU intensive}.\footnotemark\\
\hline
\end{tabular}
\caption{Valori dell'argomento \param{policy} per la funzione
\label{tab:proc_sched_policy}
\end{table}
+\footnotetext{introdotto con il kernel 2.6.16.}
+
Il valore della priorità è passato attraverso la struttura
\struct{sched\_param} (riportata in fig.~\ref{fig:sig_sched_param}), il cui
solo campo attualmente definito è \var{sched\_priority}, che nel caso delle
questa funzione ritorna sempre un valore di 150 millisecondi, e non importa
specificare il PID di un processo reale.
-
Come accennato ogni processo che usa lo scheduling real-time può rilasciare
volontariamente la CPU; questo viene fatto attraverso la funzione
\funcd{sched\_yield}, il cui prototipo è:
in modalità \textit{fifo}, per permettere l'esecuzione degli altri processi
con pari priorità quando la sezione più urgente è finita.
+% TODO: con il 2.6.23 il comportamento è stato leggermente modificato ed è
+% stato introdotto /proc/sys/kernel/sched_compat_yield da mettere a 1 per aver
+% la compatibilità con il precedente.
-\subsection{Il controllo dello \textit{scheduler} per i sistemi multiprocessore}
+\subsection{Il controllo dello \textit{scheduler} per i sistemi
+ multiprocessore}
\label{sec:proc_sched_multiprocess}
Infine con il supporto dei sistemi multiprocessore sono state introdotte delle
sono compiute nello stesso spazio di indirizzi del processo. Per questo, anche
il solo accesso o l'assegnazione di una variabile possono non essere più
operazioni atomiche (torneremo su questi aspetti in
-sez.~\ref{sec:sig_control}).
+sez.~\ref{sec:sig_adv_control}).
In questo caso il sistema provvede un tipo di dato, il \type{sig\_atomic\_t},
il cui accesso è assicurato essere atomico. In pratica comunque si può
% LocalWords: PACCT RESOURCE TTY CONFIG SETFCAP hdrp datap libcap lcap text tp
% LocalWords: get ncap caps CapInh CapPrm fffffeff CapEff getcap STAT dall'I
% LocalWords: inc PRIO SUSv PRGR prio SysV SunOS Ultrix sched timespec len sig
-% LocalWords: cpusetsize cpuset atomic
+% LocalWords: cpusetsize cpuset atomic tickless redirezione WCONTINUED stopped
+% LocalWords: waitid NOCLDSTOP ENOCHLD WIFCONTINUED ifdef endif idtype siginfo
+% LocalWords: infop ALL WEXITED WSTOPPED WNOWAIT signo CLD EXITED KILLED page
+% LocalWords: CONTINUED
%%% Local Variables:
%%% mode: latex