Aggiornamento al 2010 delle note di copyright
[gapil.git] / prochand.tex
index 86666129a9d210a06189596934e8cb05403944d9..7fe061ffcb81b5d369b937932b4b05c5fa44438b 100644 (file)
@@ -1,6 +1,6 @@
 %% prochand.tex
 %%
-%% Copyright (C) 2000-2009 Simone Piccardi.  Permission is granted to
+%% Copyright (C) 2000-2010 Simone Piccardi.  Permission is granted to
 %% copy, distribute and/or modify this document under the terms of the GNU Free
 %% Documentation License, Version 1.1 or any later version published by the
 %% Free Software Foundation; with the Invariant Sections being "Un preambolo",
@@ -146,20 +146,21 @@ fig.~\ref{fig:proc_task_struct}.
 
 % TODO la task_struct è cambiata per qualche dettaglio vedi anche
 % http://www.ibm.com/developerworks/linux/library/l-linux-process-management/
+% TODO completare la parte su quando viene chiamato lo scheduler.
 
 Come accennato in sez.~\ref{sec:intro_unix_struct} è lo \itindex{scheduler}
 \textit{scheduler} che decide quale processo mettere in esecuzione; esso viene
 eseguito ad ogni system call ed ad ogni interrupt,\footnote{più in una serie
-  di altre occasioni.}
-% TODO completare questa parte su quando viene chiamato lo scheduler.
-(ma può essere anche attivato esplicitamente). Il timer di sistema provvede
-comunque a che esso sia invocato periodicamente; generando un interrupt
-periodico secondo la frequenza specificata dalla costante
-\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
-  \itindex{clock~tick} \textit{clock tick} (vedi
+  di altre occasioni.} ma può essere anche attivato esplicitamente. Il timer
+di sistema provvede comunque a che esso sia invocato periodicamente; generando
+un interrupt periodico secondo la frequenza specificata dalla costante
+\const{HZ},\footnote{fino al kernel 2.4 il valore di \const{HZ} era 100 su
+  tutte le architetture tranne l'alpha, per cui era 1000, nel 2.6 è stato
+  portato a 1000 su tutte; dal 2.6.13 lo si può impostare in fase di
+  compilazione del kernel, con un default di 250 e valori possibili di 100,
+  250, 1000 e dal 2.6.20 anche 300 (che è divisibile per le frequenze di
+  refresh della televisione); occorre fare 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,
@@ -171,7 +172,6 @@ valore 
   da parte del processore che può essere messo in stato di sospensione anche
   per lunghi periodi di tempo.}
 
-
 Ogni volta che viene eseguito, lo \itindex{scheduler} \textit{scheduler}
 effettua il calcolo delle priorità dei vari processi attivi (torneremo su
 questo in sez.~\ref{sec:proc_priority}) e stabilisce quale di essi debba
@@ -181,11 +181,11 @@ essere posto in esecuzione fino alla successiva invocazione.
 \subsection{Una panoramica sulle funzioni fondamentali}
 \label{sec:proc_handling_intro}
 
-In un sistema unix-like i processi vengono sempre creati da altri processi
-tramite la funzione \func{fork}; il nuovo processo (che viene chiamato
-\textsl{figlio}) creato dalla \func{fork} è una copia identica del processo
-processo originale (detto \textsl{padre}), ma ha un nuovo \acr{pid} e viene
-eseguito in maniera indipendente (le differenze fra padre e figlio sono
+Tradizionalmente in un sistema unix-like i processi vengono sempre creati da
+altri processi tramite la funzione \func{fork}; il nuovo processo (che viene
+chiamato \textsl{figlio}) creato dalla \func{fork} è una copia identica del
+processo processo originale (detto \textsl{padre}), ma ha un nuovo \acr{pid} e
+viene eseguito in maniera indipendente (le differenze fra padre e figlio sono
 affrontate in dettaglio in sez.~\ref{sec:proc_fork}).
 
 Se si vuole che il processo padre si fermi fino alla conclusione del processo
@@ -308,10 +308,18 @@ affrontato in dettaglio in sez.~\ref{sec:proc_perms}.
 \label{sec:proc_fork}
 
 La funzione \funcd{fork} è la funzione fondamentale della gestione dei
-processi: come si è detto l'unico modo di creare un nuovo processo è
-attraverso l'uso di questa funzione, essa quindi riveste un ruolo centrale
-tutte le volte che si devono scrivere programmi che usano il multitasking.  Il
-prototipo della funzione è:
+processi: come si è detto tradizionalmente l'unico modo di creare un nuovo
+processo era attraverso l'uso di questa funzione,\footnote{in realtà oggi la
+  system call usata più comunemente da Linux per creare nuovi processi è
+  \func{clone} (vedi \ref{sec:process_clone}) , anche perché a partire dalle
+  \acr{glibc} 2.3.3 non viene più usata la system call originale, ma la stessa
+  \func{fork} viene implementata tramite \func{clone}, cosa che consente una
+  migliore interazione coi \textit{thread}.} essa quindi riveste un ruolo
+centrale tutte le volte che si devono scrivere programmi che usano il
+multitasking.\footnote{oggi questa rilevanza, con la diffusione dell'uso dei
+  \textit{thread} che tratteremo al cap.~\ref{cha:threads}, è in parte minore,
+  ma \func{fork} resta comunque la funzione principale per la creazione di
+  processi.} Il prototipo della funzione è:
 \begin{functions}
   \headdecl{sys/types.h} 
   \headdecl{unistd.h} 
@@ -489,6 +497,9 @@ fosse stato creato solo per eseguire una \func{exec}, in tal caso infatti si
 invocherebbe un altro programma scartando completamente lo spazio degli
 indirizzi, rendendo superflua la copia della memoria modificata dal padre.
 
+% TODO spiegare l'ulteriore cambiamento in ponte con il 2.6.32, che fa girare
+% prima il padre per questioni di caching nella CPU
+
 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
@@ -596,7 +607,7 @@ file senza una qualche forma di sincronizzazione in quanto, come visto anche
 con il nostro esempio, le varie scritture risulteranno mescolate fra loro in
 una sequenza impredicibile. Per questo le modalità con cui in genere si usano
 i file dopo una \func{fork} sono sostanzialmente due:
-\begin{enumerate}
+\begin{enumerate*}
 \item Il processo padre aspetta la conclusione del figlio. In questo caso non
   è necessaria nessuna azione riguardo ai file, in quanto la sincronizzazione
   della posizione corrente dopo eventuali operazioni di lettura e scrittura
@@ -604,7 +615,7 @@ i file dopo una \func{fork} sono sostanzialmente due:
 \item L'esecuzione di padre e figlio procede indipendentemente. In questo caso
   ciascuno dei due processi deve chiudere i file che non gli servono una volta
   che la \func{fork} è stata eseguita, per evitare ogni forma di interferenza.
-\end{enumerate}
+\end{enumerate*}
 
 Oltre ai file aperti i processi figli ereditano dal padre una serie di altre
 proprietà; la lista dettagliata delle proprietà che padre e figlio hanno in
@@ -622,7 +633,7 @@ comune dopo l'esecuzione di una \func{fork} 
   ed il terminale di controllo (vedi sez.~\ref{sec:sess_proc_group});
 \item la directory di lavoro e la directory radice (vedi
   sez.~\ref{sec:file_work_dir} e sez.~\ref{sec:file_chroot});
-\item la maschera dei permessi di creazione (vedi
+\item la maschera dei permessi di creazione dei file (vedi
   sez.~\ref{sec:file_perm_management});
 \item la maschera dei segnali bloccati (vedi sez.~\ref{sec:sig_sigmask}) e le
   azioni installate (vedi sez.~\ref{sec:sig_gen_beha});
@@ -634,18 +645,34 @@ comune dopo l'esecuzione di una \func{fork} 
   sez.~\ref{sec:proc_real_time} e sez.~\ref{sec:proc_sched_multiprocess});
 \item le variabili di ambiente (vedi sez.~\ref{sec:proc_environ}).
 \end{itemize*}
-Le differenze fra padre e figlio dopo la \func{fork} invece sono:
+Le differenze fra padre e figlio dopo la \func{fork} invece sono:\footnote{a
+  parte le ultime quattro, relative a funzionalità specifiche di Linux, le
+  altre sono esplicitamente menzionate dallo standard POSIX.1-2001.}
 \begin{itemize*}
 \item il valore di ritorno di \func{fork};
-\item il \acr{pid} (\textit{process id});
+\item il \acr{pid} (\textit{process id}), assegnato ad un nuovo valore univoco;
 \item il \acr{ppid} (\textit{parent process id}), quello del figlio viene
   impostato al \acr{pid} del padre;
-\item i valori dei tempi di esecuzione della struttura \struct{tms} (vedi
-  sez.~\ref{sec:sys_cpu_times}) che nel figlio sono posti a zero;
-\item i \textit{lock} sui file (vedi sez.~\ref{sec:file_locking}), che non
-  vengono ereditati dal figlio;
-\item gli allarmi ed i segnali pendenti (vedi sez.~\ref{sec:sig_gen_beha}), che
-  per il figlio vengono cancellati.
+\item i valori dei tempi di esecuzione (vedi sez.~\ref{sec:sys_cpu_times}) e
+  delle risorse usate (vedi sez.~\ref{sec:sys_resource_use}), che nel figlio
+  sono posti a zero;
+\item i \textit{lock} sui file (vedi sez.~\ref{sec:file_locking}) e sulla
+  memoria (vedi sez.~\ref{sec:proc_mem_lock}), che non vengono ereditati dal
+  figlio;
+\item gli allarmi (vedi sez.~\ref{sec:sig_alarm_abort}) ed i segnali pendenti
+  (vedi sez.~\ref{sec:sig_gen_beha}), che per il figlio vengono cancellati.
+\item le operazioni di I/O asincrono in corso (vedi
+  sez.~\ref{sec:file_asyncronous_io}) che non vengono ereditate dal figlio;
+\item gli aggiustamenti fatti dal padre ai semafori con \func{semop} (vedi
+  sez.~\ref{sec:ipc_sysv_sem}).
+\item le notifiche sui cambiamenti delle directory con \textit{dnotify} (vedi
+  sez.~\ref{sec:sig_notification}), che non vengono ereditate dal figlio;
+\item le mappature di memoria marcate come \const{MADV\_DONTFORK} (vedi
+  sez.~\ref{sec:file_memory_map}) che non vengono ereditate dal figlio;
+\item l'impostazione con \func{prctl} (vedi sez.~\ref{sec:prctl_xxx}) che
+  notifica al figlio la terminazione del padre viene cancellata;
+\item il segnale di terminazione del figlio è sempre \const{SIGCHLD} anche
+  qualora nel padre fosse stato modificato (vedi sez.~\ref{sec:process_clone}). 
 \end{itemize*}
 
 Una seconda funzione storica usata per la creazione di un nuovo processo è
@@ -696,7 +723,7 @@ Qualunque sia la modalit
 comunque una serie di operazioni: chiude tutti i file aperti, rilascia la
 memoria che stava usando, e così via; l'elenco completo delle operazioni
 eseguite alla chiusura di un processo è il seguente:
-\begin{itemize}
+\begin{itemize*}
 \item tutti i file descriptor sono chiusi;
 \item viene memorizzato lo stato di terminazione del processo;
 \item ad ogni processo figlio viene assegnato un nuovo padre (in genere
@@ -711,7 +738,7 @@ eseguite alla chiusura di un processo 
     group} ciascun membro del gruppo viene bloccato, e poi gli vengono
   inviati in successione i segnali \const{SIGHUP} e \const{SIGCONT}
   (vedi ancora sez.~\ref{sec:sess_ctrl_term}).
-\end{itemize}
+\end{itemize*}
 
 Oltre queste operazioni è però necessario poter disporre di un meccanismo
 ulteriore che consenta di sapere come la terminazione è avvenuta: dato che in
@@ -948,19 +975,14 @@ sono riportate anche le costanti definite per indicare alcuni di essi.
 
 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
-  \itindex{thread} \textit{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.}
+deve essere specificato come maschera binaria dei flag riportati nella prima
+parte in tab.~\ref{tab:proc_waitpid_options} che possono essere combinati fra
+loro con un OR aritmetico. Nella seconda parte della stessa tabella si sono
+riportati anche alcuni valori non standard specifici di Linux, che consentono
+un controllo più dettagliato per i processi creati con la system call generica
+\func{clone} (vedi sez.~\ref{sec:process_clone}) usati principalmente per la
+gestione della terminazione dei \itindex{thread} \textit{thread} (vedi
+sez.~\ref{sec:thread_xxx}).
 
 \begin{table}[!htb]
   \centering
@@ -976,6 +998,14 @@ valore nullo anzich
     \const{WCONTINUED}& Ritorna anche quando un processo figlio che era stato
                         fermato ha ripreso l'esecuzione.\footnotemark \\
     \hline
+    \const{\_\_WCLONE}& Attende solo per i figli creati con \func{clone},
+                        vale a dire processi che non emettono nessun segnale
+                        o emettono un segnale diverso da \const{SIGCHL} alla
+                        terminazione. \\
+    \const{\_\_WALL}  & Attende per qualunque processo figlio. \\
+    \const{\_\_WNOTHREAD}& Non attende per i figli di altri \textit{thread}
+                        dello stesso gruppo. \\
+    \hline
   \end{tabular}
   \caption{Costanti che identificano i bit dell'argomento \param{options}
     della funzione \func{waitpid}.} 
@@ -984,6 +1014,13 @@ valore nullo anzich
 
 \footnotetext{disponibile solo a partire dal kernel 2.6.10.}
 
+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.}
+
 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
@@ -1032,34 +1069,6 @@ 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
@@ -1107,17 +1116,48 @@ presente che queste macro prendono come parametro la variabile di tipo
   \label{tab:proc_status_macro}
 \end{table}
 
-\footnotetext[18]{questa macro non è definita dallo standard POSIX.1-2001, ma è
+\footnotetext[20]{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}.}
 
 \footnotetext{è presente solo a partire dal kernel 2.6.10.}
 
+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 prevedono che gli si passi come parametro la
+variabile di tipo \ctyp{int} puntata dall'argomento \param{status} restituito
+da \func{wait} o \func{waitpid}.
+
 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}.
+\val{WTERMSIG} può essere confrontato con le costanti che identificano i
+segnali 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}.
 
 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
@@ -1147,13 +1187,12 @@ suo prototipo 
 \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
+usando i due argomenti \param{idtype} ed \param{id}; il primo indica se ci si
+vuole porre 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
@@ -1414,7 +1453,7 @@ indicato dall'argomento \param{path}, che viene interpretato come il
 
 \begin{figure}[htb]
   \centering
-  \includegraphics[width=15cm]{img/exec_rel}
+  \includegraphics[width=12cm]{img/exec_rel}
   \caption{La interrelazione fra le sei funzioni della famiglia \func{exec}.}
   \label{fig:proc_exec_relat}
 \end{figure}
@@ -1428,9 +1467,9 @@ sez.~\ref{sec:proc_environ}) del processo di partenza per costruire
 l'ambiente.
 
 Oltre a mantenere lo stesso \acr{pid}, il nuovo programma fatto partire da
-\func{exec} assume anche una serie di altre proprietà del processo chiamante;
-la lista completa è la seguente:
-\begin{itemize}
+\func{exec} mantiene la gran parte delle proprietà del processo chiamante; una
+lista delle più significative è la seguente:
+\begin{itemize*}
 \item il \textit{process id} (\acr{pid}) ed il \textit{parent process id}
   (\acr{ppid});
 \item l'\textsl{user-ID reale}, il \textit{group-ID reale} ed i
@@ -1444,43 +1483,99 @@ la lista completa 
 \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
-  sez.~\ref{sec:sig_sigmask});
 \item i limiti sulle risorse (vedi sez.~\ref{sec:sys_resource_limit});
-\item i valori delle variabili \var{tms\_utime}, \var{tms\_stime},
-  \var{tms\_cutime}, \var{tms\_ustime} (vedi sez.~\ref{sec:sys_cpu_times}).
-\end{itemize}
-
-Inoltre i segnali che sono stati impostati per essere ignorati nel processo
-chiamante mantengono la stessa impostazione pure nel nuovo programma, tutti
-gli altri segnali vengono impostati alla loro azione predefinita. Un caso
-speciale è il segnale \const{SIGCHLD} che, quando impostato a
-\const{SIG\_IGN}, può anche non essere reimpostato a \const{SIG\_DFL} (si veda
-sez.~\ref{sec:sig_gen_beha}).
-
-La gestione dei file aperti dipende dal valore che ha il flag di
-\itindex{close-on-exec} \textit{close-on-exec} (vedi anche
-sez.~\ref{sec:file_fcntl}) per ciascun file descriptor. I file per cui è
-impostato vengono chiusi, tutti gli altri file restano aperti. Questo
-significa che il comportamento predefinito è che i file restano aperti
-attraverso una \func{exec}, a meno di una chiamata esplicita a \func{fcntl}
-che imposti il suddetto flag.  Per le directory, lo standard POSIX.1 richiede
-che esse vengano chiuse attraverso una \func{exec}, in genere questo è fatto
-dalla funzione \func{opendir} (vedi sez.~\ref{sec:file_dir_read}) che effettua
-da sola l'impostazione del flag di \itindex{close-on-exec}
-\textit{close-on-exec} sulle directory che apre, in maniera trasparente
-all'utente.
-
-Abbiamo detto che l'\textsl{user-ID reale} ed il \textsl{group-ID reale}
-restano gli stessi all'esecuzione di \func{exec}; normalmente vale lo stesso
-anche per l'\textsl{user-ID effettivo} ed il \textsl{group-ID effettivo} (il
-significato di questi identificatori è trattato in
-sez.~\ref{sec:proc_access_id}), tranne quando il file di cui viene chiesta
-l'esecuzione ha o il \itindex{suid~bit} \acr{suid} bit o lo \itindex{sgid~bit}
-\acr{sgid} bit impostato, in questo caso l'\textsl{user-ID effettivo} ed il
-\textsl{group-ID effettivo} vengono impostati rispettivamente all'utente o al
-gruppo cui il file appartiene (per i dettagli di questo comportamento si veda
-sez.~\ref{sec:proc_perms}).
+\item i valori delle variabili \var{tms\_utime}, \var{tms\_stime};
+  \var{tms\_cutime}, \var{tms\_ustime} (vedi sez.~\ref{sec:sys_cpu_times});
+% TODO ===========Importante=============
+% TODO questo sotto è incerto, verificare
+% TODO ===========Importante=============
+\item la maschera dei segnali (si veda sez.~\ref{sec:sig_sigmask}).
+\end{itemize*}
+
+Una serie di proprietà del processo originale, che non avrebbe senso mantenere
+in un programma che esegue un codice completamente diverso in uno spazio di
+indirizzi totalmente indipendente e ricreato da zero, vengono perse con
+l'esecuzione di \func{exec}; lo standard POSIX.1-2001 prevede che le seguenti
+proprietà non vengano preservate:
+\begin{itemize*}
+\item l'insieme dei segnali pendenti (vedi sez.~\ref{sec:sig_gen_beha}), che
+  viene cancellato;
+\item gli eventuali stack alternativi per i segnali (vedi
+  sez.~\ref{sec:sig_specific_features});
+\item i \textit{directory stream} (vedi sez.~\ref{sec:file_dir_read}), che
+  vengono chiusi;
+\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 blocchi sulla memoria (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});
+\item i timer POSIX (vedi sez.~\ref{sec:sig_timer_adv}).
+\end{itemize*}
+
+I segnali che sono stati impostati per essere ignorati nel processo chiamante
+mantengono la stessa impostazione pure nel nuovo programma, ma tutti gli altri
+segnali, ed in particolare quelli per i quali è stato installato un gestore
+vengono impostati alla loro azione predefinita (vedi
+sez.~\ref{sec:sig_gen_beha}). Un caso speciale è il segnale \const{SIGCHLD}
+che, quando impostato a \const{SIG\_IGN}, potrebbe anche essere reimpostato a
+\const{SIG\_DFL}, anche se questo con Linux non avviene.\footnote{lo standard
+  POSIX.1-2001 prevede che questo comportamento sia deciso dalla singola
+  implementazione, quella di Linux è di non modificare l'impostazione
+  precedente.}
+
+Oltre alle precedenti che sono completamente generali e disponibili anche su
+altri sistemi unix-like, esistono altre proprietà dei processi, attinenti
+caratteristiche specifiche di Linux, che non vengono preservate
+nell'esecuzione della funzione \func{exec}, queste sono:
+\begin{itemize*}
+\item le operazione di I/O asincrono (vedi sez.~\ref{sec:file_asyncronous_io})
+  pendenti vengono cancellate;
+\item le \itindex{capabilities} \textit{capabilities} vengono modificate come
+  illustrato in sez.~\ref{sec:proc_capabilities};
+\item tutti i \itindex{thread} \textit{thread} tranne il chiamante (vedi
+  sez.~\ref{sec:thread_xxx}) sono cancellati e tutti gli oggetti ad essi
+  relativi (vedi sez.~\ref{sec:thread_xxx}) rimossi;
+\item viene impostato il flag \const{PR\_SET\_DUMPABLE} di \func{prctl} (vedi
+  sez.~\ref{sec:prctl_xxx}) a meno che il programma da eseguire non sia
+  \itindex{suid~bit} \acr{suid} o \itindex{sgid~bit} \acr{sgid} (vedi
+  sez.~\ref{sec:proc_access_id});
+\item il flag \const{PR\_SET\_KEEPCAPS} di \func{prctl} (vedi
+  sez.~\ref{sec:prctl_xxx}) viene cancellato;
+\item il nome del processo viene impostato al nome del file contenente il
+  programma messo in esecuzione;
+\item il segnale di terminazione viene reimpostato a \const{SIGCHLD};
+\item l'ambiente viene reinizializzato impostando le variabili attinenti alla
+  localizzazione al valore di default POSIX. 
+\end{itemize*}
+
+La gestione dei file aperti nel passaggio al nuovo programma lanciato con
+\func{exec} dipende dal valore che ha il flag di \itindex{close-on-exec}
+\textit{close-on-exec} (vedi anche sez.~\ref{sec:file_fcntl}) per ciascun file
+descriptor. I file per cui è impostato vengono chiusi, tutti gli altri file
+restano aperti. Questo significa che il comportamento predefinito è che i file
+restano aperti attraverso una \func{exec}, a meno di una chiamata esplicita a
+\func{fcntl} che imposti il suddetto flag.  Per le directory, lo standard
+POSIX.1 richiede che esse vengano chiuse attraverso una \func{exec}, in genere
+questo è fatto dalla funzione \func{opendir} (vedi
+sez.~\ref{sec:file_dir_read}) che effettua da sola l'impostazione del flag di
+\itindex{close-on-exec} \textit{close-on-exec} sulle directory che apre, in
+maniera trasparente all'utente.
+
+Il comportamento della funzione in relazione agli identificatori relativi al
+controllo di accesso verrà trattato in dettaglio in sez.~\ref{sec:proc_perms},
+qui è sufficiente anticipare (si faccia riferimento a
+sez.~\ref{sec:proc_access_id} per la definizione di questi identificatori)
+come l'\textsl{user-ID reale} ed il \textsl{group-ID reale} restano sempre gli
+stessi, mentre l'\textsl{user-ID salvato} ed il \textsl{group-ID salvato}
+vengono impostati rispettivamente all'\textsl{user-ID effettivo} ed il
+\textsl{group-ID effettivo}, questi ultimi normalmente non vengono modificati,
+a meno che il file di cui viene chiesta l'esecuzione non abbia o il
+\itindex{suid~bit} \acr{suid} bit o lo \itindex{sgid~bit} \acr{sgid} bit
+impostato, in questo caso l'\textsl{user-ID effettivo} ed il \textsl{group-ID
+  effettivo} vengono impostati rispettivamente all'utente o al gruppo cui il
+file appartiene.
 
 Se il file da eseguire è in formato \emph{a.out} e necessita di librerie
 condivise, viene lanciato il \textit{linker} dinamico \cmd{/lib/ld.so} prima
@@ -2085,14 +2180,16 @@ compila con il flag \cmd{-ansi}, 
 scrivere codice portabile.
 
  
-\section{La gestione della priorità di esecuzione}
+\section{La gestione della priorità dei processi}
 \label{sec:proc_priority}
 
 In questa sezione tratteremo più approfonditamente i meccanismi con il quale
 lo \itindex{scheduler} \textit{scheduler} assegna la CPU ai vari processi
 attivi.  In particolare prenderemo in esame i vari meccanismi con cui viene
 gestita l'assegnazione del tempo di CPU, ed illustreremo le varie funzioni di
-gestione.
+gestione. Tratteremo infine anche le altre priorità dei processi (come quelle
+per l'accesso a disco) divenute disponibili con i kernel più recenti.
+
 
 \subsection{I meccanismi di \textit{scheduling}}
 \label{sec:proc_sched}
@@ -2144,21 +2241,21 @@ fintanto che esso si trova in uno qualunque degli altri stati.
 \begin{table}[htb]
   \footnotesize
   \centering
-  \begin{tabular}[c]{|p{2.8cm}|c|p{10cm}|}
+  \begin{tabular}[c]{|p{2.4cm}|c|p{9cm}|}
     \hline
     \textbf{Stato} & \texttt{STAT} & \textbf{Descrizione} \\
     \hline
     \hline
     \textbf{Runnable}& \texttt{R} & Il processo è in esecuzione o è pronto ad
                                     essere eseguito (cioè è in attesa che gli
-                                    venga assegnata la CPU). \\
+                                    venga assegnata la CPU).\\
     \textbf{Sleep}   & \texttt{S} & Il processo  è in attesa di un
                                     risposta dal sistema, ma può essere 
-                                    interrotto da un segnale. \\
+                                    interrotto da un segnale.\\
     \textbf{Uninterrutible Sleep}& \texttt{D} & Il  processo è in
                                     attesa di un risposta dal sistema (in 
                                     genere per I/O), e non può essere
-                                    interrotto in nessuna circostanza. \\
+                                    interrotto in nessuna circostanza.\\
     \textbf{Stopped} & \texttt{T} & Il processo è stato fermato con un
                                     \const{SIGSTOP}, o è tracciato.\\
     \textbf{Zombie}\index{zombie} & \texttt{Z} & Il processo è terminato ma il
@@ -2971,14 +3068,206 @@ non avranno alcun risultato effettivo.
 \itindend{CPU~affinity}
 
 
-%TODO trattare le priorità di I/O
-% vedi man ioprio_set e Documentation/block/ioprio.txt
-
 \subsection{Le priorità per le operazioni di I/O}
 \label{sec:io_priority}
 
-Una delle 
+A lungo l'unica priorità usata per i processi è stata quella relativa
+all'assegnazione dell'uso del processore. Ma il processore non è l'unica
+risorsa che i processi devono contendersi, un'altra, altrettanto importante
+per le prestazioni, è quella dell'accesso a disco. Per questo motivo sono
+stati introdotti diversi \textit{I/O scheduler} in grado di distribuire in
+maniera opportuna questa risorsa ai vari processi. Fino al kernel 2.6.17 era
+possibile soltanto differenziare le politiche generali di gestione, scegliendo
+di usare un diverso \textit{I/O scheduler}; a partire da questa versione, con
+l'introduzione dello scheduler CFQ (\textit{Completely Fair Queuing}) è
+divenuto possibile, qualora si usi questo scheduler, impostare anche delle
+diverse priorità di accesso per i singoli processi.\footnote{al momento
+  (kernel 2.6.31), le priorità di I/O sono disponibili soltanto per questo
+  scheduler.}
+
+La scelta dello scheduler di I/O si può fare in maniera generica a livello di
+avvio del kernel assegnando il nome dello stesso al parametro
+\texttt{elevator}, mentre se ne può indicare uno per l'accesso al singolo
+disco scrivendo nel file \texttt{/sys/block/\textit{dev}/queue/scheduler}
+(dove \texttt{\textit{dev}} è il nome del dispositivo associato al disco); gli
+scheduler disponibili sono mostrati dal contenuto dello stesso file che
+riporta fra parentesi quadre quello attivo, il default in tutti i kernel
+recenti è proprio il \texttt{cfq},\footnote{nome con cui si indica appunto lo
+  scheduler \textit{Completely Fair Queuing}.} che supporta le priorità. Per i
+dettagli sulle caratteristiche specifiche degli altri scheduler, la cui
+discussione attiene a problematiche di ambito sistemistico, si consulti la
+documentazione nella directory \texttt{Documentation/block/} dei sorgenti del
+kernel.
+
+Una volta che si sia impostato lo scheduler CFQ ci sono due specifiche system
+call, specifiche di Linux, che consentono di leggere ed impostare le priorità
+di I/O.\footnote{se usate in corrispondenza ad uno scheduler diverso il loro
+  utilizzo non avrà alcun effetto.} Dato che non esiste una interfaccia
+diretta nelle \acr{glibc} per queste due funzioni occorrerà invocarle tramite
+la funzione \func{syscall} (come illustrato in
+sez.~\ref{sec:intro_syscall}). Le due funzioni sono \funcd{ioprio\_get} ed
+\funcd{ioprio\_set}; i rispettivi prototipi sono:
+\begin{functions}
+  \headdecl{linux/ioprio.h}
+  \funcdecl{int ioprio\_get(int which, int who)} 
+  \funcdecl{int ioprio\_set(int which, int who, int ioprio)} 
+
+  Rileva o imposta la priorità di I/O di un processo.
+  
+  \bodydesc{Le funzioni ritornano rispettivamente un intero positivo
+    (indicante la priorità) o 0 in caso di successo e $-1$ in caso di errore,
+    nel qual caso \var{errno} può assumere i valori:
+    \begin{errlist}
+    \item[\errcode{ESRCH}] non esiste il processo indicato.
+    \item[\errcode{EINVAL}] i valori di \param{which} e \param{who} non sono
+      validi. 
+    \item[\errcode{EPERM}] non si hanno i privilegi per eseguire
+      l'impostazione (solo per \func{ioprio\_set}). 
+  \end{errlist} }
+\end{functions}
 
+Le funzioni leggono o impostano la priorità di I/O sulla base dell'indicazione
+dei due argomenti \param{which} e \param{who} che hanno lo stesso significato
+già visto per gli omonimi argomenti di \func{getpriority} e
+\func{setpriority}. Anche in questo caso si deve specificare il valore
+di \param{which} tramite le opportune costanti riportate in
+tab.~\ref{tab:ioprio_args} che consentono di indicare un singolo processo, i
+processi di un \textit{process group} (tratteremo questo argomento in
+sez.~\ref{sec:sess_proc_group}) o tutti o processi di un utente.
+
+\begin{table}[htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|c|c|l|}
+    \hline
+    \param{which} & \param{who} & \textbf{Significato} \\
+    \hline
+    \hline
+    \const{IPRIO\_WHO\_PROCESS} & \type{pid\_t} & processo\\
+    \const{IPRIO\_WHO\_PRGR}    & \type{pid\_t} & \itindex{process~group}
+                                                  \textit{process group}\\ 
+    \const{IPRIO\_WHO\_USER}    & \type{uid\_t} & utente\\
+    \hline
+  \end{tabular}
+  \caption{Legenda del valore dell'argomento \param{which} e del tipo
+    dell'argomento \param{who} delle funzioni \func{ioprio\_get} e
+    \func{ioprio\_set} per le tre possibili scelte.}
+  \label{tab:ioprio_args}
+\end{table}
+
+In caso di successo \func{ioprio\_get} restituisce un intero positivo che
+esprime il valore della priorità di I/O, questo valore è una maschera binaria
+composta da due parti, una che esprime la \textsl{classe} di scheduling di I/O
+del processo, l'altra che esprime, quando la classe di scheduling lo prevede,
+la priorità del processo all'interno della classe stessa. Questo stesso
+formato viene utilizzato per indicare il valore della priorità da impostare
+con l'argomento \param{ioprio} di \func{ioprio\_set}.
+
+Per la gestione dei valori che esprimono le priorità di I/O sono state
+definite delle opportune macro di preprocessore, riportate in
+tab.~\ref{tab:IOsched_class_macro}. I valori delle priorità si ottengono o si
+impostano usando queste macro.  Le prime due si usano con il valore restituito
+da \func{ioprio\_get} e per ottenere rispettivamente la classe di
+scheduling\footnote{restituita dalla macro con i valori di
+  tab.~\ref{tab:IOsched_class}.} e l'eventuale valore della priorità. La terza
+macro viene invece usata per creare un valore di priorità da usare come
+argomento di \func{ioprio\_set} per eseguire una impostazione.
+
+\begin{table}[htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|p{8cm}|}
+    \hline
+    \textbf{Macro} & \textbf{Significato}\\
+    \hline
+    \hline
+    \macro{IOPRIO\_PRIO\_CLASS}\texttt{(\textit{value})}
+                                & dato il valore di una priorità come
+                                  restituito da \func{ioprio\_get} estrae il
+                                  valore della classe.\\
+    \macro{IOPRIO\_PRIO\_DATA}\texttt{(\textit{value})}
+                                & dato il valore di una priorità come
+                                  restituito da \func{ioprio\_get} estrae il
+                                  valore della priorità.\\
+    \macro{IOPRIO\_PRIO\_VALUE}\texttt{(\textit{class},\textit{prio})}
+                                & dato un valore di priorità ed una classe
+                                  ottiene il valore numerico da passare a
+                                  \func{ioprio\_set}.\\
+    \hline
+  \end{tabular}
+  \caption{Le macro per la gestione dei valori numerici .}
+  \label{tab:IOsched_class_macro}
+\end{table}
+
+Le classi di scheduling previste dallo scheduler CFQ sono tre, e ricalcano tre
+diverse modalità di distribuzione delle risorse analoghe a quelle già adottate
+anche nel funzionamento dello scheduler del processore. Ciascuna di esse è
+identificata tramite una opportuna costante, secondo quanto riportato in
+tab.~\ref{tab:IOsched_class}.
+
+La classe di priorità più bassa è \const{IOPRIO\_CLASS\_IDLE}; i processi in
+questa classe riescono ad accedere a disco soltanto quando nessun altro
+processo richiede l'accesso. Occorre pertanto usarla con molta attenzione,
+perché un processo in questa classe può venire completamente bloccato quando
+ci sono altri processi in una qualunque delle altre due classi che stanno
+accedendo al disco. Quando si usa questa classe non ha senso indicare un
+valore di priorità, dato che in questo caso non esiste nessuna gerarchia e la
+priorità è identica, la minima possibile, per tutti i processi.
+
+\begin{table}[htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|l|}
+    \hline
+    \textbf{Classe}  & \textbf{Significato} \\
+    \hline
+    \hline
+    \const{IOPRIO\_CLASS\_RT}  & Scheduling di I/O \textit{real time}.\\
+    \const{IOPRIO\_CLASS\_BE}  & Scheduling di I/O ordinario.\\ 
+    \const{IOPRIO\_CLASS\_IDLE}& Scheduling di I/O di priorità minima.\\
+    \hline
+  \end{tabular}
+  \caption{Costanti che identificano le classi di scheduling di I/O.}
+  \label{tab:IOsched_class}
+\end{table}
+
+La seconda classe di priorità di I/O è \const{IOPRIO\_CLASS\_BE} (il nome sta
+per \textit{best-effort}) che è quella usata ordinariamente da tutti
+processi. In questo caso esistono priorità diverse che consentono di
+assegnazione di una maggiore banda passante nell'accesso a disco ad un
+processo rispetto agli altri, con meccanismo simile a quello dei valori di
+\textit{nice} in cui si evita che un processo a priorità più alta possa
+bloccare indefinitamente quelli a priorità più bassa. In questo caso però le
+diverse priorità sono soltanto otto, indicate da un valore numerico fra 0 e 7
+e come per \textit{nice} anche in questo caso un valore più basso indica una
+priorità maggiore. 
+
+
+Infine la classe di priorità di I/O \textit{real-time}
+\const{IOPRIO\_CLASS\_RT} ricalca le omonime priorità di processore: un
+processo in questa classe ha sempre la precedenza nell'accesso a disco
+rispetto a tutti i processi delle altre classi e di un processo nella stessa
+classe ma con priorità inferiore, ed è pertanto in grado di bloccare
+completamente tutti gli altri. Anche in questo caso ci sono 8 priorità diverse
+con un valore numerico fra 0 e 7, con una priorità più elevata per valori più
+bassi.
+
+In generale nel funzionamento ordinario la priorità di I/O di un processo
+viene impostata in maniera automatica nella classe \const{IOPRIO\_CLASS\_BE}
+con un valore ottenuto a partire dal corrispondente valore di \textit{nice}
+tramite la formula: $\mathtt{\mathit{prio}}=(\mathtt{\mathit{nice}}+20)/5$. Un
+utente ordinario può modificare con \func{ioprio\_set} soltanto le priorità
+dei processi che gli appartengono,\footnote{per la modifica delle priorità di
+  altri processi occorrono privilegi amministrativi, ed in particolare la
+  capacità \const{CAP\_SYS\_NICE} (vedi sez.~\ref{sec:proc_capabilities}).}
+cioè quelli il cui user-ID reale corrisponde all'user-ID reale o effettivo del
+chiamante. Data la possibilità di ottenere un blocco totale dello stesso, solo
+l'amministratore\footnote{o un processo con la capacità
+  \const{CAP\_SYS\_ADMIN} (vedi sez.~\ref{sec:proc_capabilities}).} può
+impostare un processo ad una priorità di I/O nella classe
+\const{IOPRIO\_CLASS\_RT} o \const{IOPRIO\_CLASS\_IDLE}.
+
+%TODO verificare http://lwn.net/Articles/355987/
 
 %TODO trattare le funzionalità per il NUMA
 % vedi man numa e le pagine di manuale relative
@@ -3193,8 +3482,11 @@ varie funzioni di libreria, che sono identificate aggiungendo il suffisso
 % LocalWords:  CONTINUED sources forking Spawned successfully executing exiting
 % LocalWords:  next cat for COMMAND pts bash defunct TRAPPED DUMPED Killable PR
 % LocalWords:  SIGKILL static RLIMIT preemption PREEMPT VOLUNTARY IDLE RTPRIO
-% LocalWords:  Completely Fair compat Uniform
-
+% LocalWords:  Completely Fair compat Uniform CFQ Queuing elevator dev cfq RT
+% LocalWords:  Documentation block syscall ioprio IPRIO CLASS class best effort
+% LocalWords:  refresh semop dnotify MADV DONTFORK prctl WCLONE SIGCHL WALL
+% LocalWords:  WNOTHREAD DUMPABLE KEEPCAPS
 %%% Local Variables: 
 %%% mode: latex
 %%% TeX-master: "gapil"