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