X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=system.tex;h=8b117142910ddc8788ecc267081272fbd9fcd01a;hp=01930a0c182364ce5e07db72c671b1ace60f7668;hb=b08cbbc5abd1579c0a94d357d5ded1fe902044a0;hpb=2c682ba44f85eb183ddf75760b38bf048f89de53 diff --git a/system.tex b/system.tex index 01930a0..8b11714 100644 --- a/system.tex +++ b/system.tex @@ -1,4 +1,4 @@ -fo \chapter{La gestione del sistema, delle risorse, e degli errori} +\chapter{La gestione del sistema, delle risorse, e degli errori} \label{cha:system} In questo capitolo tratteremo varie interfacce che attengono agli aspetti più @@ -1617,7 +1617,7 @@ informazioni riguardo la memoria; i loro prototipi sono: Legge il numero di pagine di memoria disponibili nel sistema. - \bodydesc{Le funzioni restituiscono il numero di pagine, } + \bodydesc{Le funzioni restituiscono un numero di pagine.} \end{functions} Queste funzioni sono equivalenti all'uso della funzione \func{sysconf} @@ -1804,8 +1804,9 @@ ricevuto lo stato di terminazione, e lo stesso vale per \var{tms\_cstime}. Si tenga conto che l'aggiornamento di \var{tms\_cutime} e \var{tms\_cstime} viene eseguito solo quando una chiamata a \func{wait} o \func{waitpid} è -ritornata. Per questo motivo se un figlio termina prima di altri suoi figli, -questi ``nipoti'' non potranno essere considerati nel calcolo di questi tempi. +ritornata. Per questo motivo se un processo figlio termina prima di ricevere +lo stato di teminazione di tutti i suoi figli, questi processi ``nipoti'' non +verranno considerati nel calcolo di questi tempi. @@ -1815,45 +1816,70 @@ questi ``nipoti'' non potranno essere considerati nel calcolo di questi tempi. Come anticipato in \secref{sec:sys_unix_time} il \textit{calendar time} è mantenuto dal kernel in una variabile di tipo \type{time\_t}, che usualmente corrisponde ad un tipo nativo (in Linux è un intero a 32 bit). Il valore -corrente del \textit{calendar time} può essere ottenuto con la funzione -\func{time} che lo restituisce in nel suddetto formato; il suo prototipo è: +corrente del \textit{calendar time}, che indicheremo come \textsl{tempo di + sistema}, può essere ottenuto con la funzione \func{time} che lo restituisce +in nel suddetto formato; il suo prototipo è: \begin{prototype}{time.h}{time\_t time(time\_t *t)} Legge il valore corrente del \textit{calendar time}. - \bodydesc{La funzione ritorna valore del \textit{calendar time} in caso di - successo e -1 in caso di errore, che può essere solo \macro{EFAULT}.} + \bodydesc{La funzione ritorna il valore del \textit{calendar time} in caso + di successo e -1 in caso di errore, che può essere solo \macro{EFAULT}.} \end{prototype} -\noindent dove \param{t}, se non nullo, è l'indirizzo su cui salvare il valore -di ritorno. +\noindent dove \param{t}, se non nullo, deve essere l'indirizzo di una +variabile su cui duplicare il valore di ritorno. Analoga a \func{time} è la funzione \func{stime} che serve per effettuare -l'operazione inversa, e cioè per settare l'orologio di sistema; il suo -prototipo è: +l'operazione inversa, e cioè per settare il tempo di sistema qualora questo +sia necessario; il suo prototipo è: \begin{prototype}{time.h}{int stime(time\_t *t)} Setta a \param{t} il valore corrente del \textit{calendar time}. \bodydesc{La funzione ritorna 0 in caso di successo e -1 in caso di errore, - che può essere \macro{EFAULT} o \macro{EPERM}.} + che può essere \macro{EFAULT} o \macro{EPERM}.} \end{prototype} +\noindent dato che modificare l'ora ha un impatto su tutto il sistema +il cambiamento dell'orologio è una operazione privilegiata e questa funzione +può essere usata solo da un processo con i privilegi di amministratore, +altrimenti la chiamata fallirà con un errore di \macro{EPERM}. + +Data la scarsa precisione nell'uso di \type{time\_t} (che ha una risoluzione +massima di un secondo) quando si devono effettuare operazioni sui tempi di +norma l'uso delle funzioni precedenti è sconsigliato, ed esse sono di solito +sostituite da \func{gettimeofday} e \func{settimeofday},\footnote{le due + funzioni \func{time} e \func{stime} sono più antiche e derivano da SVr4, + \func{gettimeofday} e \func{settimeofday} sono state introdotte da BSD, ed + in BSD4.3 sono indicate come sostitute delle precedenti.} mentre i cui +prototipi sono: +\begin{functions} + \headdecl{sys/time.h} + \headdecl{time.h} + + \funcdecl{int gettimeofday(struct timeval *tv, struct timezone *tz)} -Dato che modificare l'ora ha un impatto su tutto il sistema, la funzione può -essere usata solo dall'ammninistratore. - - -Dato che il tempo misurato in termini di\type{time\_t} ha comunque una -risoluzione massima di un secondo le \acr{glibc} provvedono delle -rappresentazioni alternative che consentono di indicare intervalli o tempi con -precisioni maggiori del secondo, queste sono realizzate attraverso le -strutture \var{timeval} e \var{timespec}, le cui definizioni sono riportate in -\figref{fig:sys_timeval_struct}, che consentono rispettivamente precisioni del -microsecondo e del nanosecondo\footnote{la precisione è solo astratta, - l'orologio di sistema normalmente non è in grado di misuare dei tempi con - precisioni simili.}. + Legge il tempo corrente del sistema. + + \funcdecl{int settimeofday(const struct timeval *tv, const struct timezone + *tz)} + + Setta il tempo di sistema. + + \bodydesc{Entrambe le funzioni restituiscono 0 in caso di successo e -1 in + caso di errore, nel qual caso \var{errno} può assumere il valori + \macro{EINVAL} \macro{EFAULT} e per \func{settimeofday} anche + \macro{EPERM}.} +\end{functions} +Queste funzioni utilizzano una struttura di tipo \var{timeval}, la cui +definizione, insieme a quella della analoga \var{timespec}, è riportata in +\figref{fig:sys_timeval_struct}. Le \acr{glibc} infatti provvedono queste due +rappresentazioni alternative del \textit{calendar time} che rispetto a +\type{time\_t} consentono rispettivamente precisioni del microsecondo e del +nanosecondo.\footnote{la precisione è solo teorica, la precisione reale della + misura del tempo dell'orologio di sistema non dipende dall'uso di queste + strutture.} \begin{figure}[!htb] - \footnotesize - \centering + \footnotesize \centering \begin{minipage}[c]{15cm} \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{} struct timeval @@ -1868,19 +1894,165 @@ struct timespec { \end{lstlisting} \end{minipage} \normalsize - \caption{Le strutture \var{timeval} e \var{timespec} per il calendar time.} + \caption{Le strutture \var{timeval} e \var{timespec} usate per una + rappresentazione ad alta risoluzione del \textit{calendar time}.} \label{fig:sys_timeval_struct} \end{figure} -Data la scarsa precisione nell'uso di \type{time\_t} per le operazioni sui -tempi di norma l'uso delle funzioni precedenti è di norma sconsigliato, ed -esse sono di solito sostituite da \func{gettimeofday} e \func{settimeofday} +Come nel caso di \func{stime} anche \func{settimeofday} (e qualunque funzione +vada a modificare l'orologio di sistema, come quelle che tratteremo in +seguito) può essere utilizzata solo da un processo coi privilegi di +amministratore. Il secondo parametro di entrambe le funzioni è una struttura +\var{timezone}, che storicamente veniva utilizzata per specificare appunto la +\textit{timezone}, cioè l'insieme del fuso orario e delle convenzioni per +l'ora legale che permettevano il passaggio dal tempo universale all'ora +locale. Questo parametro è obsoleto e in Linux non è mai stato utilizzato e +non è supportato né dalle vecchie \textsl{libc5}, né dalle \textsl{glibc}: +pertanto deve essere sempre settato a \macro{NULL}. + +Modificare l'orologio di sistema con queste funzioni è comunque problematico, +in quanto esse effettuano un cambiamento immediato. Ad esempio se si porta +avanti l'orologio si possono perdere delle esecuzioni di \cmd{cron} +programmate nell'intervallo che si è saltato. Per questo motivo la modalità +più corretta per settare l'ora è quella di usare la funzione \func{adjtime}, +il cui prototipo è: +\begin{prototype}{sys/time.h} +{int adjtime(const struct timeval *delta, struct timeval *olddelta)} + + Aggiusta del valore \param{delta} l'orologio di sistema. + + \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di + errore, nel qual caso \var{errno} assumerà il valore \macro{EPERM}.} +\end{prototype} + +Questa funzione permette di avere un aggiustamento graduale del tempo di +sistema in modo che esso sia sempre monotonicamente crescente. Il valore di +\param{delta} esprime il valore di cui si vuole spostare l'orologio; se è +positivo l'orologio sarà accelerato per un certo tempo in modo da guadagnare +il tempo richiesto, altrimenti sarà rallentato. Il secondo parametro viene +usato, se non nullo, per ricevere il valore dell'ultimo aggiustamento +effettuto. + +Linux poi prevede un'altra funzione, \func{adjtimex}, che consente un +aggiustamento molto più dettagliato, permettendo ad esempio anche di +modificare anche la velocità dell'orologio di sistema. La funzione utilizza il +meccanismo di David L. Mills, descritto nell'RFC~1305, che è alla base del +protocollo NTP; la funzione è specifica di Linux e non deve essere usata se la +portabilità è un requisito, le \acr{glibc} provvedono anhe un suo omonimo +\func{ntp\_adjtime}. Il suo prototipo è: +\begin{prototype}{sys/timex.h} +{int adjtimex(struct timex *buf)} + + Aggiusta del valore \param{delta} l'orologio di sistema. + + \bodydesc{La funzione restituisce lo stato dell'orologio (un valore $>0$) in + caso di successo e -1 in caso di errore, nel qual caso \var{errno} + assumerà il valore \macro{EPERM}.} +\end{prototype} + +La funzione richiede una struttura di tipo \var{timex}, la cui definizione, +così come effettuata in \file{sys/timex.h}, è riportata in +\figref{fig:sys_timex_struct}. L'azione della funzione dipende dal valore del +campo \var{mode}, che specifica quale parametro dell'orologio di sistema, +specificato in un opportuno campo di \var{timex}, deve essere settato. Un +valore nullo serve per leggere i parametri correnti; i valori diversi da zero +devono essere specificati come OR binario delle costanti riportate in +\secref{tab:sys_timex_mode}. + +\begin{figure}[!htb] + \footnotesize \centering + \begin{minipage}[c]{15cm} + \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{} +struct timex { + unsigned int modes; /* mode selector */ + long int offset; /* time offset (usec) */ + long int freq; /* frequency offset (scaled ppm) */ + long int maxerror; /* maximum error (usec) */ + long int esterror; /* estimated error (usec) */ + int status; /* clock command/status */ + long int constant; /* pll time constant */ + long int precision; /* clock precision (usec) (read only) */ + long int tolerance; /* clock frequency tolerance (ppm) (read only) */ + struct timeval time; /* (read only) */ + long int tick; /* (modified) usecs between clock ticks */ + long int ppsfreq; /* pps frequency (scaled ppm) (ro) */ + long int jitter; /* pps jitter (us) (ro) */ + int shift; /* interval duration (s) (shift) (ro) */ + long int stabil; /* pps stability (scaled ppm) (ro) */ + long int jitcnt; /* jitter limit exceeded (ro) */ + long int calcnt; /* calibration intervals (ro) */ + long int errcnt; /* calibration errors (ro) */ + long int stbcnt; /* stability limit exceeded (ro) */ +}; + \end{lstlisting} + \end{minipage} + \normalsize + \caption{La struttura \var{timex} per il controllo dell'orologio di sistema.} + \label{fig:sys_timex_struct} +\end{figure} + +La trattazione completa di questa funzione necessita di una lettura +approfondita del meccanismo descritto nell'RFC~1305, ci limitiamo a descrivere +in \tabref{tab:sys_timex_mode} i principali valori utilizzabili, un elenco più +dettagliato del significato dei vari campi può essere ritrovato in +\cite{glibc}. +\begin{table}[htb] + \footnotesize + \centering + \begin{tabular}[c]{|l|c| p{10cm}|} + \hline + \textbf{Nome} & \textbf{Valore} & \textbf{Significato}\\ + \hline + \hline + \macro{ADJ\_OFFSET} & 0x0001 & Setta la differenza fra il tempo + reale e l'orologio di sistema, che + deve essere indicata in microsecondi + nel campo \var{offset} di + \var{timex}.\\ + \macro{ADJ\_FREQUENCY} & 0x0002 & Setta la differenze in frequenza + fra il tempo reale e l'orologio di + sistema, che deve essere indicata + in parti per milione nel campo + \var{frequency} di \var{timex}.\\ + \macro{ADJ\_MAXERROR} & 0x0004 & Setta il valore massimo dell'errore + sul tempo, espresso in microsecondi + nel campo \var{maxerror} di + \var{timex}.\\ + \macro{ADJ\_ESTERROR} & 0x0008 & Setta la stima dell'errore + sul tempo, espresso in microsecondi + nel campo \var{esterror} di + \var{timex}.\\ + \macro{ADJ\_STATUS} & 0x0010 & Setta alcuni + valori di stato interni usati dal + sistema nella gestione + dell'orologio specificati nel campo + \var{status} di \var{timex}.\\ + \macro{ADJ\_TIMECONST} & 0x0020 & Setta la larghezza di banda del PLL + implementato dal kernel, + specificato nel campo + \var{constant} di \var{timex}.\\ + \macro{ADJ\_TICK} & 0x4000 & Setta il valore dei tick del timer + in microsecondi, espresso nel campo + \var{tick} di \var{timex}.\\ + \macro{ADJ\_OFFSET\_SINGLESHOT}&0x8001&Setta uno spostamento una tantum + dell'orologio secondo il valore del + campo \var{offset} simulando il + comportamento di \func{adjtime}.\\ + \hline + \end{tabular} + \caption{Costanti per l'assegnazione del valore del campo \var{mode} della + struttura \var{timex}.} + \label{tab:sys_timex_mode} +\end{table} +La funzione ritorna un valore positivo che esprime lo stato dell'orologio di +sistema; questo può -\subsection{Le \textit{timezone} e la gestione delle date.} -\label{sec:sys_time_base} + +\subsection{La gestione delle date.} +\label{sec:sys_date}