Correzioni alle figure e scritto un po' di chroot e tmpnam
[gapil.git] / system.tex
1 \chapter{La gestione del sistema}
2 \label{cha:system}
3
4 In questo capitolo si è raccolta le trattazione delle varie funzioni
5 concernenti la gestione generale del sistema che permettono di trattare le
6 varie informazioni ad esso connesse, i limiti sulle risorse, la gestione dei
7 tempi, degli errori e degli utenti ed in generale la gestione dei vari
8 parametri di configurazione dei vari componenti del sistema.
9
10
11 \section{La gestione della configurazione del sistema}
12 \label{sec:sys_config}
13
14
15 \subsection{Opzioni e configurazione del systema}
16 \label{sec:sys_sys_config}
17
18 La funzione \func{sysconf} ...
19
20 \subsection{La configurazione dei file}
21 \label{sec:sys_file_config}
22
23 La funzione \func{statfs} ...
24
25 La funzione \func{pathconf} ...
26
27
28 \section{La gestione delle risorse e dei limiti di sistema}
29 \label{sec:sys_limits}
30
31 In questa sezione esamimeremo le funzioni che permettono di gestire le varie
32 risorse associate ad un processo ed i relativi limiti, e quelle relatica al
33 sistema in quanto tale.
34
35 \var{tms\_utime}, \var{tms\_stime}, \var{tms\_cutime}, \var{tms\_uetime}
36
37
38
39 \section{La gestione dei tempi del sistema}
40 \label{sec:sys_time}
41
42 In questa sezione tratteremo le varie funzioni per la gestione delle
43 date e del tempo in un sistema unix-like, e quelle per convertire i vari
44 tempi nelle differenti rappresentazioni che vengono utilizzate.
45
46
47 \subsection{La misura del tempo in unix}
48 \label{sec:sys_unix_time}
49
50 Storicamente i sistemi unix-like hanno sempre mantenuto due distinti
51 valori per i tempi all'interno del sistema, essi sono rispettivamente
52 chiamati \textit{calendar time} e \textit{process time}, secondo le
53 definizioni:
54 \begin{itemize}
55 \item \textit{calendar time}: è il numero di secondi dalla mezzanotte del
56   primo gennaio 1970, in tempo universale coordinato (o UTC), data che viene
57   usualmente indicata con 00:00:00 Jan, 1 1970 (UTC) e chiamata \textit{the
58     Epoch}. Questo tempo viene anche chiamato anche GMT (Greenwich Mean Time)
59   dato che l'UTC corrisponde all'ora locale di Greenwich.  È il tempo su cui
60   viene mantenuto l'orologio del calcolatore, e viene usato ad esempio per
61   indicare le date di modifica dei file o quelle di avvio dei processi. Per
62   memorizzare questo tempo è stato riservato il tipo primitivo \type{time\_t}.
63 \item \textit{process time}: talvolta anche detto tempo di CPU. Viene misurato
64   in \textit{clock tick}, corrispondenti al numero di interruzioni effettuate
65   dal timer di sistema, e che per Linux avvengono ogni centesimo di
66   secondo\footnote{eccetto per la piattaforma alpha dove avvengono ogni
67     millesimo di secondo}. Il dato primitivo usato per questo tempo è
68   \type{clock\_t}, inoltre la costante \macro{HZ} restituisce la frequenza di
69   operazione del timer, e corrisponde dunque al numero di tick al secondo.  Lo
70   standard POSIX definisce allo stesso modo la costante \macro{CLK\_TCK});
71   questo valore può comunque essere ottenuto con \func{sysconf} (vedi
72   \secref{sec:sys_limits}).
73 \end{itemize}
74
75 In genere si usa il \textit{calendar time} per tenere le date dei file e le
76 informazioni analoghe che riguardano i tempi di ``orologio'', usati ad esempio
77 per i demoni che compiono lavori amministrativi ad ore definite, come
78 \cmd{cron}. Di solito questo vene convertito automaticamente dal valore in UTC
79 al tempo locale, utilizzando le opportune informazioni di localizzazione
80 (specificate in \file{/etc/timezone}). E da tenere presente che questo tempo è
81 mantenuto dal sistema e non corrisponde all'orologio hardware del calcolatore.
82
83 Il \textit{process time} di solito si esprime in secondi e viene usato appunto
84 per tenere conto dei tempi di esecuzione dei processi. Per ciascun processo il
85 kernel tiene tre di questi tempi: 
86 \begin{itemize*}
87 \item \textit{clock time}
88 \item \textit{user time}
89 \item \textit{system time}
90 \end{itemize*}
91 il primo è il tempo ``reale'' (viene anche chiamato \textit{wall clock time})
92 dall'avvio del processo, e misura il tempo trascorso fino alla sua
93 conclusione; chiaramente un tale tempo dipende anche dal carico del sistema e
94 da quanti altri processi stavano girando nello stesso periodo. Il secondo
95 tempo è quello che la CPU ha speso nell'esecuzione delle istruzioni del
96 processo in user space. Il terzo è il tempo impiegato dal kernel per eseguire
97 delle system call per conto del processo medesimo (tipo quello usato per
98 eseguire una \func{write} su un file). In genere la somma di user e system
99 time viene chiamato \textit{CPU time}. 
100
101
102
103
104
105 \section{La gestione degli errori}
106 \label{sec:sys_errors}
107
108 La gestione degli errori è in genere una materia complessa. Inoltre il modello
109 utilizzato dai sistema unix-like è basato sull'architettura a processi, e
110 presenta una serie di problemi nel caso lo si debba usare con i thread.
111 Esamineremo in questa sezione le sue caratteristiche principali.
112
113
114 \subsection{La variabile \var{errno}}
115 \label{sec:sys_errno}
116
117 Quasi tutte le funzioni delle librerie del C sono in grado di individuare e
118 riportare condizioni di errore, ed è una buona norma di programmazione
119 controllare sempre che le funzioni chiamate si siano concluse correttamente.
120
121 In genere le funzioni di libreria usano un valore speciale per indicare che
122 c'è stato un errore. Di solito questo valore è -1 o un puntatore nullo o la
123 costante \macro{EOF} (a seconda della funzione); ma questo valore segnala solo
124 che c'è stato un errore, non il tipo di errore. 
125
126 Per riportare il tipo di errore il sistema usa la variabile globale
127 \var{errno}\footnote{L'uso di una variabile globale può comportare alcuni
128   problemi (ad esempio nel caso dei thread) ma lo standard ISO C consente
129   anche di definire \var{errno} come un \textit{modifiable lvalue}, quindi si
130   può anche usare una macro, e questo è infatti il modo usato da Linux per
131   renderla locale ai singoli thread }, definita nell'header \file{errno.h}, la
132 variabile è in genere definita come \type{volatile} dato che può essere
133 cambiata in modo asincrono da un segnale (per una descrizione dei segnali si
134 veda \secref{cha:signals}), ma dato che un manipolatore di segnale scritto
135 bene salva e ripristina il valore della variabile, di questo non è necessario
136 preoccuparsi nella programmazione normale.
137
138 I valori che può assumere \var{errno} sono riportati in \capref{cha:errors},
139 nell'header \file{errno.h} sono anche definiti i nomi simbolici per le
140 costanti numeriche che identificano i vari errori; essi iniziano tutti per
141 \macro{E} e si possono considerare come nomi riservati. In seguito faremo
142 sempre rifermento a tali valori, quando descriveremo i possibili errori
143 restituiti dalle funzioni. Il programma di esempio \cmd{errcode} stampa il
144 codice relativo ad un valore numerico con l'opzione \cmd{-l}.
145
146 Il valore di \var{errno} viene sempre settato a zero all'avvio di un
147 programma, gran parte delle funzioni di libreria settano \var{errno} ad un
148 valore diverso da zero in caso di errore. Il valore è invece indefinito in
149 caso di successo, perché anche se una funzione ha successo, può chiamarne
150 altre al suo interno che falliscono, modificando così \var{errno}.
151
152 Pertanto un valore non nullo di \var{errno} non è sintomo di errore (potrebbe
153 essere il risultato di un errore precedente) e non lo si può usare per
154 determinare quando o se una chiamata a funzione è fallita.  La procedura da
155 seguire è sempre quella di controllare \var{errno} immediatamente dopo aver
156 verificato il fallimento della funzione attraverso il suo codice di ritorno.
157
158
159 \subsection{Le funzioni \func{strerror} e \func{perror}}
160 \label{sec:sys_strerror}
161
162 Benché gli errori siano identificati univocamente dal valore numerico di
163 \var{errno} le librerie provvedono alcune funzioni e variabili utili per
164 riportare in opportuni messaggi le condizioni di errore verificatesi.  La
165 prima funzione che si può usare per ricavare i messaggi di errore è
166 \func{strerror}, il cui prototipo è:
167 \begin{prototype}{string.h}{char * strerror(int errnum)} 
168   Ritorna una stringa (statica) che descrive l'errore il cui codice è passato
169   come parametro.
170 \end{prototype}
171
172 In generale \func{strerror} viene usata passando \var{errno} come parametro;
173 nel caso si specifichi un codice sbagliato verrà restituito un messaggio di
174 errore sconosciuto. La funzione utilizza una stringa statica che non deve
175 essere modificata dal programma e che è utilizzabile solo fino ad una chiamata
176 successiva a \func{strerror}; nel caso si usino i thread è
177 provvista\footnote{questa funzione è una estensione GNU, non fa parte dello
178   standard POSIX} una versione apposita:
179 \begin{prototype}{string.h}
180 {char * strerror\_r(int errnum, char * buff, size\_t size)} 
181   Analoga a \func{strerror} ma ritorna il messaggio in un buffer
182   specificato da \param{buff} di lunghezza massima (compreso il terminatore)
183   \param{size}.
184 \end{prototype}
185 \noindent
186 che utilizza un buffer che il singolo thread deve allocare, per evitare i
187 problemi connessi alla condivisione del buffer statico. Infine, per completare
188 la caratterizzazione dell'errore, si può usare anche la variabile
189 globale\footnote{anche questa è una estensione GNU}
190 \var{program\_invocation\_short\_name} che riporta il nome del programma
191 attualmente in esecuzione.
192
193 Una seconda funzione usata per riportare i codici di errore in maniera
194 automatizzata sullo standard error (vedi \secref{sec:file_std_descr}) è
195 \func{perror}, il cui prototipo è:
196 \begin{prototype}{stdio.h}{void perror (const char *message)} 
197   Stampa il messaggio di errore relativo al valore corrente di \var{errno}
198   sullo standard error; preceduto dalla stringa \var{message}.
199 \end{prototype}
200 i messaggi di errore stampati sono gli stessi di \func{strerror}, (riportati
201 in \capref{cha:errors}), e, usando il valore corrente di \var{errno}, si
202 riferiscono all'ultimo errore avvenuto. La stringa specificata con
203 \var{message} viene stampato prime del messaggio d'errore, seguita dai due
204 punti e da uno spazio, il messaggio è terminato con un a capo.
205
206 Il messaggio può essere riportato anche usando altre variabili globali
207 dichiarate in \file{errno.h}:
208 \begin{verbatim}
209    const char *sys_errlist[];
210    int sys_nerr;
211 \end{verbatim}
212 la prima contiene i puntatori alle stringhe di errore indicizzati da
213 \var{errno}; la seconda esprime il valore più alto per un codice di errore,
214 l'utilizzo di questa stringa è sostanzialmente equivalente a quello di
215 \func{strerror}.
216
217 In \nfig\ è riportata la sezione attinente del codice del programma
218 \cmd{errcode}, che può essere usato per stampare i messaggi di errore e le
219 costanti usate per identificare i singoli errori; il sorgente completo del
220 programma è allegato nel file \file{ErrCode.c} e contiene pure la gestione
221 delle opzioni e tutte le definizioni necessarie ad associare il valore
222 numerico alla costante simbolica. In particolare si è riportata la sezione che
223 converte la stringa passata come parametro in un intero (\texttt{\small
224   1--2}), controllando con i valori di ritorno di \func{strtol} che la
225 conversione sia avvenuta correttamente (\texttt{\small 4--10}), e poi stampa,
226 a seconda dell'opzione scelta il messaggio di errore (\texttt{\small 11--14})
227 o la macro (\texttt{\small 15--17}) associate a quel codice.
228
229 \begin{figure}[!htb]
230   \footnotesize
231   \begin{lstlisting}{}
232     /* convert string to number */
233     err = strtol(argv[optind], NULL, 10);
234     /* testing error condition on conversion */
235     if (err==LONG_MIN) {
236         perror("Underflow on error code");
237         return 1;
238     } else if (err==LONG_MIN) {
239         perror("Overflow on error code");
240         return 1;
241     }
242     /* conversion is fine */
243     if (message) {
244         printf("Error message for %d is %s\n", err, strerror(err));
245     }
246     if (label) {
247         printf("Error label for %d is %s\n", err, err_code[err]);
248     }
249   \end{lstlisting}
250   \caption{Codice per la stampa del messaggio di errore standard.}
251   \label{fig:sys_err_mess}
252 \end{figure}
253
254
255 \section{La gestione di utenti e gruppi}
256 \label{sec:sys_user_group}
257