X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=system.tex;h=313aceb9d83dabc013867276f8214210b95dc32a;hp=b8b745b86e4b4e7d6d87a042f665766552f166d0;hb=b2892e085134716ccc35f0f0d247ca40356a81ff;hpb=8e2e77dff8f3cffb28ddf982280dff6fc015eb19 diff --git a/system.tex b/system.tex index b8b745b..313aceb 100644 --- a/system.tex +++ b/system.tex @@ -20,7 +20,7 @@ quelle per la gestione ed il controllo dei filesystem, degli utenti, dei tempi e degli errori. -\section{La gestione di catteristiche e parametri del sistema} +\section{La gestione di caratteristiche e parametri del sistema} \label{sec:sys_characteristics} In questa sezione tratteremo le varie modalità con cui un programma può @@ -541,22 +541,32 @@ di questi parametri sono: \item il numero massimo di file aperti \end{itemize*} + + +\index{file!filesystem~\texttt {/proc}!definizione|(} + Dato che fin dall'inizio i parametri erano organizzati in una struttura albero, è parso naturale rimappare questa organizzazione utilizzando il -filesystem \file{/proc}. Questo è un filesystem virtuale, generato -direttamente dal kernel, che non fa riferimento a nessun dispositivo fisico, -ma presenta in forma di file i dati di alcune delle strutture interne del -kernel stesso. Il suo utilizzo principale, come denuncia il nome stesso, è -quello di fornire una interfaccia per ricavare i dati dei processi (venne -introdotto a questo scopo su BSD), ma nel corso del tempo il suo uso è stato -ampliato. - -In particolare l'albero dei valori di \func{sysctl} viene presentato in forma -di una gerarchia di file e directory a partire dalla directory -\file{/proc/sys}, cosicché è possibile accedere al valore di un parametro del -kernel tramite il \textit{pathname} ad un file sotto \file{/proc/sys} -semplicemente leggendone il contenuto, così come si può modificare un -parametro scrivendo sul file ad esso corrispondente. +filesystem \file{/proc}. Questo è un filesystem completamente virtuale, il cui +contenuto è generato direttamente dal kernel, che non fa riferimento a nessun +dispositivo fisico, ma presenta in forma di file e directory i dati di alcune +delle strutture interne del kernel stesso. Il suo utilizzo principale, come +denuncia il nome stesso, è quello di fornire una interfaccia per ottenere i +dati relativi ai processi (venne introdotto a questo scopo su BSD), ma nel +corso del tempo il suo uso è stato ampliato. + +All'interno di questo filesystem sono pertanto presenti una serie di file che +riflettono il contenuto dei parametri del kernel (molti dei quali accessibili +in sola lettura) e in altrettante directory, nominate secondo il relativo +\ids{PID}, vengono mantenute le informazioni relative a ciascun processo +attivo nel sistema. + +In particolare l'albero dei valori dei parametri di sistema impostabili con +\func{sysctl} viene presentato in forma di una gerarchia di file e directory a +partire dalla directory \file{/proc/sys}, cosicché è possibile accedere al +valore di un parametro del kernel tramite il \textit{pathname} ad un file +sotto \file{/proc/sys} semplicemente leggendone il contenuto, così come si può +modificare un parametro scrivendo sul file ad esso corrispondente. Il kernel si occupa di generare al volo il contenuto ed i nomi dei file corrispondenti ai vari parametri che sono presenti, e questo ha il grande @@ -565,13 +575,14 @@ di permettere la navigazione dell'albero in modo da riconoscere quali parametri sono presenti senza dover cercare un valore all'interno di una pagina di manuale. -Inizialmente l'uso del filesystem \file{/proc} serviva soltanto a replicare, -con altrettante corrispondenze ai file presenti in \file{/proc/sys}, i valori -dei parametri usati da \func{sysctl}, ma vista la assoluta naturalità -dell'interfaccia, e la sua maggiore efficienza, nelle versioni più recenti del -kernel questa è diventata la modalità canonica per modificare i parametri del -kernel, evitando di dover ricorrere all'uso di una \textit{system call} -specifica che prima o poi verrà eliminata. +Inizialmente l'uso del filesystem \file{/proc} serviva soltanto a replicare +l'accesso, con altrettante corrispondenze ai file presenti in +\file{/proc/sys}, ai parametri impostabili tradizionalmente con \func{sysctl}, +ma vista la assoluta naturalità dell'interfaccia, e la sua maggiore +efficienza, nelle versioni più recenti del kernel questa è diventata la +modalità canonica per modificare i parametri del kernel, evitando di dover +ricorrere all'uso di una \textit{system call} specifica che pur essendo ancora +presente, prima o poi verrà eliminata. Nonostante la semplificazione nella gestione ottenuta con l'uso di \file{/proc/sys} resta il problema generale di conoscere il significato di @@ -581,12 +592,12 @@ buona parte di quelli può importanti sono descritti dalla documentazione inclusa nei sorgenti del kernel, nella directory \file{Documentation/sysctl}. Ma oltre alle informazioni che sostituiscono quelle ottenibili dalla ormai -deprecata \func{sysctl} dentro \file{proc} sono disponibili moltissime altre -informazioni, fra cui ad esempio anche quelle fornite dalla funzione -\funcd{uname},\footnote{con Linux ci sono in realtà 3 \textit{system call} - diverse per le dimensioni delle stringe restituite, le prime due usano - rispettivamente delle lunghezze di 9 e 65 byte, la terza usa anch'essa 65 - byte, ma restituisce anche l'ultimo campo, \var{domainname}, con una +deprecata \func{sysctl} dentro \file{/proc} sono disponibili moltissime altre +informazioni, fra cui ad esempio anche quelle fornite dalla funzione di +sistema \funcd{uname},\footnote{con Linux ci sono in realtà 3 \textit{system + call} diverse per le dimensioni delle stringhe restituite, le prime due + usano rispettivamente delle lunghezze di 9 e 65 byte, la terza usa anch'essa + 65 byte, ma restituisce anche l'ultimo campo, \var{domainname}, con una lunghezza di 257 byte, la \acr{glibc} provvede a mascherare questi dettagli usando la versione più recente disponibile.} il cui prototipo è: @@ -622,8 +633,9 @@ due costanti per queste dimensioni, \const{\_UTSNAME\_LENGTH} per i campi standard e \const{\_UTSNAME\_DOMAIN\_LENGTH} per quello relativo al nome di dominio, altri sistemi usano nomi diversi come \const{SYS\_NMLN} o \const{\_SYS\_NMLN} o \const{UTSLEN} che possono avere valori diversi. Dato -che il buffer deve essere preallocata l'unico modo per farlo in maniera sicura -è allora usare come dimensione il valore ottenuto con \code{sizeof(utsname)}. +che il buffer per \struct{utsname} deve essere preallocato l'unico modo per +farlo in maniera sicura è allora usare come dimensione il valore ottenuto con +\code{sizeof(utsname)}. Le informazioni vengono restituite in ciascuno dei singoli campi di \struct{utsname} in forma di stringhe terminate dal carattere NUL. In @@ -634,10 +646,9 @@ particolare dette informazioni sono: \item il nome della release del kernel; \item il nome della versione del kernel; \item il tipo di hardware della macchina; -\item il nome del domino (il \textit{doaminname}). +\item il nome del domino (il \textit{domainname}); \end{itemize*} - -Ma l'ultima di queste informazioni è stata aggiunta di recente e non è +ma l'ultima di queste informazioni è stata aggiunta di recente e non è prevista dallo standard POSIX, per questo essa è accessibile, come mostrato in fig.~\ref{fig:sys_utsname}, solo se si è definita la macro \macro{\_GNU\_SOURCE}. @@ -647,10 +658,10 @@ Come accennato queste stesse informazioni, anche se a differenza di direttamente tramite il filesystem \file{/proc}, esse infatti sono mantenute rispettivamente nei file \sysctlrelfile{kernel}{ostype}, \sysctlrelfile{kernel}{hostname}, \sysctlrelfile{kernel}{osrelease}, -\sysctlrelfile{kernel}{version} e \sysctlrelfile{kernel}{domainname} di -\file{/proc/sys/kernel/}. - +\sysctlrelfile{kernel}{version} e \sysctlrelfile{kernel}{domainname} che si +trovano sotto la directory \file{/proc/sys/kernel/}. +\index{file!filesystem~\texttt {/proc}!definizione|)} @@ -658,10 +669,10 @@ rispettivamente nei file \sysctlrelfile{kernel}{ostype}, \label{sec:sys_management} In questa sezione prenderemo in esame le interfacce di programmazione messe a -disposizione per affrontare una serie di tematiche di gestione generale del -sistema come quelle relative alla gestione di utenti e gruppi, delle -informazioni relative ai collegamenti al sistema, dello spegnimento e del -riavvio di una macchina. +disposizione per affrontare una serie di tematiche attinenti la gestione +generale del sistema come quelle relative alla gestione di utenti e gruppi, al +trattamento delle informazioni relative ai collegamenti al sistema, alle +modalità per effettuare lo spegnimento o il riavvio di una macchina. \subsection{La gestione delle informazioni su utenti e gruppi} @@ -670,40 +681,44 @@ riavvio di una macchina. Tradizionalmente le informazioni utilizzate nella gestione di utenti e gruppi (password, corrispondenze fra nomi simbolici e \ids{UID} numerici, home directory, ecc.) venivano registrate all'interno dei due file di testo -\conffile{/etc/passwd} ed \conffile{/etc/group},\footnote{in realtà oltre a - questi nelle distribuzioni più recenti è stato introdotto il sistema delle - \textit{shadow password} che prevede anche i due file \conffile{/etc/shadow} - e \conffile{/etc/gshadow}, in cui sono state spostate le informazioni di - autenticazione (ed inserite alcune estensioni) per toglierle dagli altri - file che devono poter essere letti per poter effettuare l'associazione fra - username e \ids{UID}.} il cui formato è descritto dalle relative pagine del -manuale\footnote{nella quinta sezione, quella dei file di configurazione, - occorre cioè usare \cmd{man 5 passwd} dato che altrimenti si avrebbe la - pagina di manuale del comando \cmd{passwd}.} e tutte le funzioni che -richiedevano l'accesso a queste informazione andavano a leggere direttamente -il contenuto di questi file. - -Col tempo però questa impostazione ha incominciato a mostrare dei limiti: da +\conffile{/etc/passwd} ed \conffile{/etc/group}, il cui formato è descritto +dalle relative pagine del manuale\footnote{nella quinta sezione, quella dei + file di configurazione (esistono comandi corrispondenti), una trattazione + sistemistica dell'intero argomento coperto in questa sezione si consulti + sez.~4.3 di \cite{AGL}.} e tutte le funzioni che richiedevano l'accesso a +queste informazione andavano a leggere direttamente il contenuto di questi +file. + +In realtà oltre a questi due file da molto tempo gran parte dei sistemi +unix-like usano il cosiddetto sistema delle \textit{shadow password} che +prevede anche i due file \conffile{/etc/shadow} e \conffile{/etc/gshadow}, in +cui sono state spostate le informazioni di autenticazione (ed inserite alcune +estensioni di gestione avanzata) per toglierle dagli altri file che devono +poter essere letti da qualunque processo per poter effettuare l'associazione +fra username e \ids{UID}. + +Col tempo però questa impostazione ha incominciato a mostrare dei limiti. Da una parte il meccanismo classico di autenticazione è stato ampliato, ed oggi la maggior parte delle distribuzioni di GNU/Linux usa la libreria PAM (sigla che sta per \textit{Pluggable Authentication Method}) che fornisce una -interfaccia comune per i processi di autenticazione,\footnote{il - \textit{Pluggable Authentication Method} è un sistema modulare, in cui è - possibile utilizzare anche più meccanismi insieme, diventa così possibile - avere vari sistemi di riconoscimento (biometria, chiavi hardware, ecc.), - diversi formati per le password e diversi supporti per le informazioni, il - tutto in maniera trasparente per le applicazioni purché per ciascun - meccanismo si disponga della opportuna libreria che implementa l'interfaccia - di PAM.} svincolando completamente le singole applicazione dai dettagli del -come questa viene eseguita e di dove vengono mantenuti i dati relativi; -dall'altra con il diffondersi delle reti la necessità di centralizzare le -informazioni degli utenti e dei gruppi per insiemi di macchine, in modo da -mantenere coerenti i dati, ha portato anche alla necessità di poter recuperare -e memorizzare dette informazioni su supporti diversi, introducendo il sistema -del \itindex{Name~Service~Switch~(NSS)} \textit{Name Service Switch} che +interfaccia comune per i processi di autenticazione, svincolando completamente +le singole applicazioni dai dettagli del come questa viene eseguita e di dove +vengono mantenuti i dati relativi. Si tratta di un sistema modulare, in cui è +possibile utilizzare anche più meccanismi insieme, diventa così possibile +avere vari sistemi di riconoscimento (biometria, chiavi hardware, ecc.), +diversi formati per le password e diversi supporti per le informazioni. Il +tutto avviene in maniera trasparente per le applicazioni purché per ciascun +meccanismo si disponga della opportuna libreria che implementa l'interfaccia +di PAM. + +Dall'altra parte, il diffondersi delle reti e la necessità di centralizzare le +informazioni degli utenti e dei gruppi per insiemi di macchine e servizi +all'interno di una stessa organizzazione, in modo da mantenere coerenti i +dati, ha portato anche alla necessità di poter recuperare e memorizzare dette +informazioni su supporti diversi dai file citati, introducendo il sistema del +\itindex{Name~Service~Switch~(NSS)} \textit{Name Service Switch} che tratteremo brevemente più avanti (in sez.~\ref{sec:sock_resolver}) dato che la -maggior parte delle sua applicazioni sono relative alla risoluzioni di nomi di -rete. +sua applicazione è cruciale nella procedura di risoluzione di nomi di rete. In questo paragrafo ci limiteremo comunque a trattare le funzioni classiche per la lettura delle informazioni relative a utenti e gruppi tralasciando @@ -721,37 +736,39 @@ queste sono del tutto generiche e si appoggiano direttamente al \textit{Name sia il supporto su cui esse vengono mantenute. Per leggere le informazioni relative ad un utente si possono usare due funzioni, \funcd{getpwuid} e \funcd{getpwnam}, i cui prototipi sono: -\begin{functions} - \headdecl{pwd.h} - \headdecl{sys/types.h} - \funcdecl{struct passwd *getpwuid(uid\_t uid)} - - \funcdecl{struct passwd *getpwnam(const char *name)} - Restituiscono le informazioni relative all'utente specificato. - - \bodydesc{Le funzioni ritornano il puntatore alla struttura contenente le - informazioni in caso di successo e \val{NULL} nel caso non sia stato - trovato nessun utente corrispondente a quanto specificato.} -\end{functions} +\begin{funcproto}{ +\fhead{pwd.h} +\fhead{sys/types.h} +\fdecl{struct passwd *getpwuid(uid\_t uid)} +\fdecl{struct passwd *getpwnam(const char *name)} +\fdesc{Restituiscono le informazioni relative all'utente specificato.} +} + +{Le funzioni ritornano il puntatore alla struttura contenente le informazioni + in caso di successo e \val{NULL} nel caso non sia stato trovato nessun + utente corrispondente a quanto specificato, nel qual caso \var{errno} + assumerà il valore riportato dalle funzioni di sistema sottostanti.} +\end{funcproto} Le due funzioni forniscono le informazioni memorizzate nel registro degli -utenti (che nelle versioni più recenti possono essere ottenute attraverso PAM) -relative all'utente specificato attraverso il suo \ids{UID} o il nome di -login. Entrambe le funzioni restituiscono un puntatore ad una struttura di -tipo \struct{passwd} la cui definizione (anch'essa eseguita in -\headfile{pwd.h}) è riportata in fig.~\ref{fig:sys_passwd_struct}, dove è pure -brevemente illustrato il significato dei vari campi. +utenti (che nelle versioni più recenti per la parte di credenziali di +autenticazione vengono ottenute attraverso PAM) relative all'utente +specificato attraverso il suo \ids{UID} o il nome di login. Entrambe le +funzioni restituiscono un puntatore ad una struttura di tipo \struct{passwd} +la cui definizione (anch'essa eseguita in \headfile{pwd.h}) è riportata in +fig.~\ref{fig:sys_passwd_struct}, dove è pure brevemente illustrato il +significato dei vari campi. \begin{figure}[!htb] \footnotesize \centering - \begin{minipage}[c]{\textwidth} + \begin{minipage}[c]{0.8\textwidth} \includestruct{listati/passwd.h} \end{minipage} \normalsize - \caption{La struttura \structd{passwd} contenente le informazioni relative ad - un utente del sistema.} + \caption{La struttura \structd{passwd} contenente le informazioni relative + ad un utente del sistema.} \label{fig:sys_passwd_struct} \end{figure} @@ -762,22 +779,23 @@ fanno riferimento. Ovviamente questo implica che dette funzioni non possono essere \index{funzioni!rientranti} rientranti; per questo motivo ne esistono anche due versioni alternative (denotate dalla solita estensione \code{\_r}), i cui prototipi sono: -\begin{functions} - \headdecl{pwd.h} - - \headdecl{sys/types.h} - - \funcdecl{struct passwd *getpwuid\_r(uid\_t uid, struct passwd *password, - char *buffer, size\_t buflen, struct passwd **result)} - - \funcdecl{struct passwd *getpwnam\_r(const char *name, struct passwd - *password, char *buffer, size\_t buflen, struct passwd **result)} - Restituiscono le informazioni relative all'utente specificato. - - \bodydesc{Le funzioni ritornano 0 in caso di successo e un codice d'errore - altrimenti, nel qual caso \var{errno} sarà impostata opportunamente.} -\end{functions} +\begin{funcproto}{ +\fhead{pwd.h} +\fhead{sys/types.h} +\fdecl{struct passwd *getpwuid\_r(uid\_t uid, struct passwd *password, + char *buffer,\\ +\phantom{struct passwd *getpwuid\_r(}size\_t buflen, struct passwd **result)} +\fdecl{struct passwd *getpwnam\_r(const char *name, struct passwd + *password, char *buffer,\\ +\phantom{struct passwd *getpwnam\_r(}size\_t buflen, struct passwd **result)} +\fdesc{Restituiscono le informazioni relative all'utente specificato.} +} + +{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} assumerà il valore riportato dalle di sistema funzioni + sottostanti.} +\end{funcproto} In questo caso l'uso è molto più complesso, in quanto bisogna prima allocare la memoria necessaria a contenere le informazioni. In particolare i valori @@ -791,29 +809,55 @@ dati non possano essere contenuti nei byte specificati da \param{buflen}, la funzione fallirà restituendo \errcode{ERANGE} (e \param{result} sarà comunque impostato a \val{NULL}). +Sia queste versioni rientranti che precedenti gli errori eventualmente +riportati in \var{errno} in caso di fallimento dipendono dalla sottostanti +funzioni di sistema usate per ricavare le informazioni (si veda quanto +illustrato in sez.~\ref{sec:sys_errno}) per cui se lo si vuole utilizzare è +opportuno inizializzarlo a zero prima di invocare le funzioni per essere +sicuri di non avere un residuo di errore da una chiamata precedente. Il non +aver trovato l'utente richiesto infatti può essere dovuto a diversi motivi (a +partire dal fatto che non esista) per cui si possono ottenere i valori di +errore più vari a seconda dei casi. + Del tutto analoghe alle precedenti sono le funzioni \funcd{getgrnam} e -\funcd{getgrgid} (e le relative analoghe \index{funzioni!rientranti} -rientranti con la stessa estensione \code{\_r}) che permettono di leggere le -informazioni relative ai gruppi, i loro prototipi sono: -\begin{functions} - \headdecl{grp.h} - \headdecl{sys/types.h} +\funcd{getgrgid} che permettono di leggere le informazioni relative ai gruppi, +i loro prototipi sono: - \funcdecl{struct group *getgrgid(gid\_t gid)} - - \funcdecl{struct group *getgrnam(const char *name)} - - \funcdecl{struct group *getpwuid\_r(gid\_t gid, struct group *password, - char *buffer, size\_t buflen, struct group **result)} - - \funcdecl{struct group *getpwnam\_r(const char *name, struct group - *password, char *buffer, size\_t buflen, struct group **result)} +\begin{funcproto}{ +\fhead{grp.h} +\fhead{sys/types.h} +\fdecl{struct group *getgrgid(gid\_t gid)} +\fdecl{struct group *getgrnam(const char *name)} +\fdesc{Restituiscono le informazioni relative al gruppo specificato.} +} + +{Le funzioni ritornano il puntatore alla struttura contenente le informazioni + in caso di successo e \val{NULL} nel caso non sia stato trovato nessun + utente corrispondente a quanto specificato, nel qual caso \var{errno} + assumerà il valore riportato dalle funzioni di sistema sottostanti.} +\end{funcproto} + +Come per le precedenti per gli utenti esistono anche le analoghe versioni +\index{funzioni!rientranti} rientranti che di nuovo utilizzano la stessa +estensione \code{\_r}; i loro prototipi sono: + +\begin{funcproto}{ +\fhead{grp.h} +\fhead{sys/types.h} +\fdecl{int getgrgid\_r(gid\_t gid, struct group *grp, char *buf, + size\_t buflen,\\ +\phantom{int getgrgid\_r(}struct group **result)} +\fdecl{int getgrnam\_r(const char *name, struct group *grp, char *buf, + size\_t buflen,\\ +\phantom{int getgrnam\_r(}struct group **result)} +\fdesc{Restituiscono le informazioni relative al gruppo specificato.} +} + +{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} assumerà il valore riportato dalle funzioni di sistema + sottostanti.} +\end{funcproto} - Restituiscono le informazioni relative al gruppo specificato. - - \bodydesc{Le funzioni ritornano 0 in caso di successo e un codice d'errore - altrimenti, nel qual caso \var{errno} sarà impostata opportunamente.} -\end{functions} Il comportamento di tutte queste funzioni è assolutamente identico alle precedenti che leggono le informazioni sugli utenti, l'unica differenza è che @@ -824,7 +868,7 @@ fig.~\ref{fig:sys_group_struct}. \begin{figure}[!htb] \footnotesize \centering - \begin{minipage}[c]{\textwidth} + \begin{minipage}[c]{0.8\textwidth} \includestruct{listati/group.h} \end{minipage} \normalsize @@ -838,13 +882,13 @@ direttamente dal file delle password in \conffile{/etc/passwd} che tramite il sistema del \itindex{Name~Service~Switch~(NSS)} \textit{Name Service Switch} e sono completamente generiche. Si noti però che non c'è una funzione che permetta di impostare direttamente una password.\footnote{in realtà questo può - essere fatto ricorrendo a PAM, ma questo è un altro discorso.} Dato che -POSIX non prevede questa possibilità esiste un'altra interfaccia che lo fa, -derivata da SVID le cui funzioni sono riportate in -tab.~\ref{tab:sys_passwd_func}. Questa però funziona soltanto quando le -informazioni sono mantenute su un apposito file di \textsl{registro} di utenti -e gruppi, con il formato classico di \conffile{/etc/passwd} e -\conffile{/etc/group}. + essere fatto ricorrendo alle funzioni della libreria PAM, ma questo non è un + argomento che tratteremo qui.} Dato che POSIX non prevede questa possibilità +esiste un'altra interfaccia che lo fa, derivata da SVID le cui funzioni sono +riportate in tab.~\ref{tab:sys_passwd_func}. Questa interfaccia però funziona +soltanto quando le informazioni sono mantenute su un apposito file di +\textsl{registro} di utenti e gruppi, con il formato classico di +\conffile{/etc/passwd} e \conffile{/etc/group}. \begin{table}[htb] \footnotesize @@ -885,15 +929,17 @@ e gruppi, con il formato classico di \conffile{/etc/passwd} e % TODO mancano i prototipi di alcune delle funzioni -Dato che oramai la gran parte delle distribuzioni di GNU/Linux utilizzano -almeno le \textit{shadow password} (quindi con delle modifiche rispetto al -formato classico del file \conffile{/etc/passwd}), si tenga presente che le -funzioni di questa interfaccia che permettono di scrivere delle voci in un +Dato che oramai tutte le distribuzioni di GNU/Linux utilizzano le +\textit{shadow password} (quindi con delle modifiche rispetto al formato +classico del file \conffile{/etc/passwd}), si tenga presente che le funzioni +di questa interfaccia che permettono di scrivere delle voci in un \textsl{registro} degli utenti (cioè \func{putpwent} e \func{putgrent}) non hanno la capacità di farlo specificando tutti i contenuti necessari rispetto a -questa estensione. Per questo motivo l'uso di queste funzioni è deprecato, in -quanto comunque non funzionale, pertanto ci limiteremo a fornire soltanto -l'elenco di tab.~\ref{tab:sys_passwd_func}, senza nessuna spiegazione +questa estensione. + +Per questo motivo l'uso di queste funzioni è deprecato, in quanto comunque non +funzionale rispetto ad un sistema attuale, pertanto ci limiteremo a fornire +soltanto l'elenco di tab.~\ref{tab:sys_passwd_func}, senza nessuna spiegazione ulteriore. Chi volesse insistere ad usare questa interfaccia può fare riferimento alle pagine di manuale delle rispettive funzioni ed al manuale delle \acr{glibc} per i dettagli del funzionamento. @@ -903,26 +949,24 @@ delle \acr{glibc} per i dettagli del funzionamento. \subsection{Il registro della \textsl{contabilità} degli utenti} \label{sec:sys_accounting} -L'ultimo insieme di funzioni relative alla gestione del sistema che +Un altro insieme di funzioni relative alla gestione del sistema che esamineremo è quello che permette di accedere ai dati del registro della cosiddetta \textsl{contabilità} (o \textit{accounting}) degli utenti. In esso vengono mantenute una serie di informazioni storiche relative sia agli utenti -che si sono collegati al sistema, (tanto per quelli correntemente collegati, -che per la registrazione degli accessi precedenti), sia relative all'intero +che si sono collegati al sistema, tanto per quelli correntemente collegati, +che per la registrazione degli accessi precedenti, sia relative all'intero sistema, come il momento di lancio di processi da parte di \cmd{init}, il cambiamento dell'orologio di sistema, il cambiamento di runlevel o il riavvio della macchina. -I dati vengono usualmente\footnote{questa è la locazione specificata dal - \textit{Linux Filesystem Hierarchy Standard}, adottato dalla gran parte - delle distribuzioni.} memorizzati nei due file \file{/var/run/utmp} e -\file{/var/log/wtmp}.\footnote{non si confonda quest'ultimo con il simile - \file{/var/log/btmp} dove invece vengono memorizzati dal programma di login - tutti tentativi di accesso fallito.} Quando un utente si collega viene -aggiunta una voce a \file{/var/run/utmp} in cui viene memorizzato il nome di -login, il terminale da cui ci si collega, l'\ids{UID} della shell di login, -l'orario della connessione ed altre informazioni. La voce resta nel file fino -al logout, quando viene cancellata e spostata in \file{/var/log/wtmp}. +I dati vengono usualmente memorizzati nei due file \file{/var/run/utmp} e +\file{/var/log/wtmp}. che sono quelli previsti dal \textit{Linux Filesystem + Hierarchy Standard}, adottato dalla gran parte delle distribuzioni. Quando +un utente si collega viene aggiunta una voce a \file{/var/run/utmp} in cui +viene memorizzato il nome di login, il terminale da cui ci si collega, +l'\ids{UID} della shell di login, l'orario della connessione ed altre +informazioni. La voce resta nel file fino al logout, quando viene cancellata +e spostata in \file{/var/log/wtmp}. In questo modo il primo file viene utilizzato per registrare chi sta utilizzando il sistema al momento corrente, mentre il secondo mantiene la @@ -939,38 +983,39 @@ solo che in questo caso la struttura del registro della \textsl{contabilità} è molto più complessa, dato che contiene diversi tipi di informazione. Le prime tre funzioni, \funcd{setutent}, \funcd{endutent} e \funcd{utmpname} -servono rispettivamente a aprire e a chiudere il file che contiene il -registro, e a specificare su quale file esso viene mantenuto. I loro prototipi -sono: -\begin{functions} - \headdecl{utmp.h} - - \funcdecl{void utmpname(const char *file)} Specifica il file da usare come - registro. - - \funcdecl{void setutent(void)} Apre il file del registro, posizionandosi al - suo inizio. - - \funcdecl{void endutent(void)} Chiude il file del registro. - - \bodydesc{Le funzioni non ritornano codici di errore.} -\end{functions} -e si tenga presente che le funzioni non restituiscono nessun valore, pertanto -non è possibile accorgersi di eventuali errori (ad esempio se si è impostato -un nome di file sbagliato con \func{utmpname}). +servono rispettivamente a aprire e a chiudere il file che contiene il registro +della \textsl{contabilità} degli, e a specificare su quale file esso viene +mantenuto. I loro prototipi sono: + +\begin{funcproto}{ +\fhead{utmp.h} +\fdecl{void utmpname(const char *file)} +\fdesc{Specifica il file da usare come registro.} +\fdecl{void setutent(void)} +\fdesc{Apre il file del registro.} +\fdecl{void endutent(void)} +\fdesc{Chiude il file del registro.} +} + +{Le funzioni non ritornano nulla.} +\end{funcproto} + +Si tenga presente che le funzioni non restituiscono nessun valore, pertanto +non è possibile accorgersi di eventuali errori, ad esempio se si è impostato +un nome di file sbagliato con \func{utmpname}. Nel caso non si sia utilizzata \func{utmpname} per specificare un file di registro alternativo, sia \func{setutent} che \func{endutent} operano usando -il default che è \sysfile{/var/run/utmp}. Il nome di questo file, così come -una serie di altri valori di default per i \textit{pathname} di uso più -comune, viene mantenuto nei valori di una serie di costanti definite -includendo \headfile{paths.h}, in particolare quelle che ci interessano sono: +il default che è \sysfile{/var/run/utmp} il cui nome, così come una serie di +altri valori di default per i \textit{pathname} di uso più comune, viene +mantenuto nei valori di una serie di costanti definite includendo +\headfile{paths.h}, in particolare quelle che ci interessano sono: \begin{basedescript}{\desclabelwidth{2.0cm}} \item[\const{\_PATH\_UTMP}] specifica il file che contiene il registro per gli - utenti correntemente collegati; questo è il valore che viene usato se non si - è utilizzato \func{utmpname} per modificarlo. + utenti correntemente collegati, questo è il valore che viene usato se non si + è utilizzato \func{utmpname} per modificarlo; \item[\const{\_PATH\_WTMP}] specifica il file che contiene il registro per - l'archivio storico degli utenti collegati. + l'archivio storico degli utenti collegati; \end{basedescript} che nel caso di Linux hanno un valore corrispondente ai file \sysfile{/var/run/utmp} e \sysfile{/var/log/wtmp} citati in precedenza. @@ -978,37 +1023,40 @@ che nel caso di Linux hanno un valore corrispondente ai file Una volta aperto il file del registro degli utenti si può eseguire una scansione leggendo o scrivendo una voce con le funzioni \funcd{getutent}, \funcd{getutid}, \funcd{getutline} e \funcd{pututline}, i cui prototipi sono: -\begin{functions} - \headdecl{utmp.h} - \funcdecl{struct utmp *getutent(void)} - Legge una voce dalla posizione corrente nel registro. - - \funcdecl{struct utmp *getutid(struct utmp *ut)} Ricerca una voce sul - registro in base al contenuto di \param{ut}. - \funcdecl{struct utmp *getutline(struct utmp *ut)} - Ricerca nel registro la prima voce corrispondente ad un processo sulla linea - di terminale specificata tramite \param{ut}. +\begin{funcproto}{ +\fhead{utmp.h} +\fdecl{struct utmp *getutent(void)} +\fdesc{Legge una voce dalla posizione corrente nel registro.} +\fdecl{struct utmp *getutid(struct utmp *ut)} +\fdesc{Ricerca una voce sul registro.} +\fdecl{struct utmp *getutline(struct utmp *ut)} +\fdesc{Ricerca una voce sul registro attinente a un terminale.} +\fdecl{struct utmp *pututline(struct utmp *ut)} +\fdesc{Scrive una voce nel registro.} +} - \funcdecl{struct utmp *pututline(struct utmp *ut)} - Scrive una voce nel registro. - - \bodydesc{Le funzioni ritornano il puntatore ad una struttura \struct{utmp} - in caso di successo e \val{NULL} in caso di errore.} -\end{functions} +{Le funzioni ritornano il puntatore ad una struttura \struct{utmp} in caso di + successo e \val{NULL} in caso di errore, nel qual caso \var{errno} assumerà + il valore riportato dalle funzioni di sistema sottostanti.} +\end{funcproto} Tutte queste funzioni fanno riferimento ad una struttura di tipo \struct{utmp}, la cui definizione in Linux è riportata in fig.~\ref{fig:sys_utmp_struct}. Le prime tre funzioni servono per leggere una -voce dal registro; \func{getutent} legge semplicemente la prima voce -disponibile; le altre due permettono di eseguire una ricerca. - +voce dal registro: \func{getutent} legge semplicemente la prima voce +disponibile, le altre due permettono di eseguire una ricerca. Aprendo il +registro con \func{setutent} ci si posiziona al suo inizio, ogni chiamata di +queste funzioni eseguirà la lettura sulle voci seguenti, pertanto la posizione +sulla voce appena letta, in modo da consentire una scansione del file. Questo +vale anche per \func{getutid} e \func{getutline}, il che comporta che queste +funzioni effettuano comunque una ricerca ``\textsl{in avanti}''. \begin{figure}[!htb] \footnotesize \centering - \begin{minipage}[c]{\textwidth} + \begin{minipage}[c]{0.9\textwidth} \includestruct{listati/utmp.h} \end{minipage} \normalsize @@ -1056,84 +1104,321 @@ corrispondente al valore del campo \var{ut\_id} specificato in \param{ut}. La funzione \func{getutline} esegue la ricerca sulle voci che hanno \var{ut\_type} uguale a \const{LOGIN\_PROCESS} o \const{USER\_PROCESS}, restituendo la prima che corrisponde al valore di \var{ut\_line}, che -specifica il device\footnote{espresso senza il \file{/dev/} iniziale.} di -terminale che interessa. Lo stesso criterio di ricerca è usato da -\func{pututline} per trovare uno spazio dove inserire la voce specificata, -qualora non sia trovata la voce viene aggiunta in coda al registro. +specifica il dispositivo di terminale che interessa, da indicare senza il +\file{/dev/} iniziale. Lo stesso criterio di ricerca è usato da +\func{pututline} per trovare uno spazio dove inserire la voce specificata; +qualora questo spazio non venga trovato la voce viene aggiunta in coda al +registro. In generale occorre però tenere conto che queste funzioni non sono completamente standardizzate, e che in sistemi diversi possono esserci differenze; ad esempio \func{pututline} restituisce \code{void} in vari sistemi (compreso Linux, fino alle \acr{libc5}). Qui seguiremo la sintassi fornita dalle \acr{glibc}, ma gli standard POSIX 1003.1-2001 e XPG4.2 hanno -introdotto delle nuove strutture (e relativi file) di tipo \code{utmpx}, che -sono un sovrainsieme di \code{utmp}. - -Le \acr{glibc} utilizzano già una versione estesa di \code{utmp}, che rende -inutili queste nuove strutture; pertanto esse e le relative funzioni di -gestione (\funcm{getutxent}, \funcm{getutxid}, \funcm{getutxline}, -\funcm{pututxline}, \funcm{setutxent} e \funcm{endutxent}) sono ridefinite come -sinonimi delle funzioni appena viste. - -% TODO (verificare le funzioni di cui sopra ) - -Come visto in sez.~\ref{sec:sys_user_group}, l'uso di strutture allocate -staticamente rende le funzioni di lettura non \index{funzioni!rientranti} -rientranti; per questo motivo le \acr{glibc} forniscono anche delle versioni -\index{funzioni!rientranti} rientranti: \funcm{getutent\_r}, \funcm{getutid\_r}, -\funcm{getutline\_r}, che invece di restituire un puntatore restituiscono un -intero e prendono due argomenti aggiuntivi. Le funzioni si comportano -esattamente come le analoghe non \index{funzioni!rientranti} rientranti, solo -che restituiscono il risultato all'indirizzo specificato dal primo argomento -aggiuntivo (di tipo \code{struct utmp *buffer}) mentre il secondo (di tipo -\code{struct utmp **result)} viene usato per restituire il puntatore allo -stesso buffer. - -Infine le \acr{glibc} forniscono come estensione per la scrittura delle voci -in \file{wmtp} altre due funzioni, \funcd{updwtmp} e \funcd{logwtmp}, i cui -prototipi sono: -\begin{functions} - \headdecl{utmp.h} - - \funcdecl{void updwtmp(const char *wtmp\_file, const struct utmp *ut)} - Aggiunge la voce \param{ut} nel registro \file{wmtp}. - - \funcdecl{void logwtmp(const char *line, const char *name, const char - *host)} Aggiunge nel registro una voce con i valori specificati. -\end{functions} +introdotto delle nuove strutture (e relativi file) di tipo \struct{utmpx}, che +sono un sovrainsieme della \struct{utmp} usata tradizionalmente ed altrettante +funzioni che le usano al posto di quelle citate. + +Le \acr{glibc} utilizzavano già una versione estesa di \struct{utmp}, che +rende inutili queste nuove strutture, per questo su Linux \struct{utmpx} viene +definita esattamente come \struct{utmp}, con gli stessi campi di +fig.~\ref{fig:sys_utmp_struct}. Altrettanto dicasi per le nuove funzioni di +gestione previste dallo standard: \funcm{getutxent}, \funcm{getutxid}, +\funcm{getutxline}, \funcm{pututxline}, \funcm{setutxent} e \funcm{endutxent}. + +Tutte queste funzioni, definite con \struct{utmpx} dal file di dichiarazione +\headfile{utmpx.h}, su Linux sono ridefinite come sinonimi delle funzioni +appena viste, con argomento di tipo \struct{utmpx} anziché \struct{utmp} ed +hanno lo stesso identico comportamento. Per completezza viene definita anche +\funcm{utmpxname} che non è prevista da POSIX.1-2001. + +Come già visto in sez.~\ref{sec:sys_user_group}, l'uso di strutture allocate +staticamente rende le funzioni di lettura dei dati appena illustrate non +\index{funzioni!rientranti} rientranti. Per questo motivo le \acr{glibc} +forniscono anche delle versioni \index{funzioni!rientranti} rientranti: +\func{getutent\_r}, \func{getutid\_r}, \func{getutline\_r}, che invece di +restituire un puntatore restituiscono un intero e prendono due argomenti +aggiuntivi, i rispettivi prototipi sono: -La prima funzione permette l'aggiunta di una voce a \file{wmtp} specificando -direttamente una struttura \struct{utmp}, mentre la seconda utilizza gli -argomenti \param{line}, \param{name} e \param{host} per costruire la voce che -poi aggiunge chiamando \func{updwtmp}. +\begin{funcproto}{ +\fhead{utmp.h} +\fdecl{int *getutent\_r(struct utmp *buffer, struct utmp **result)} +\fdesc{Legge una voce dalla posizione corrente nel registro.} +\fdecl{int *getutid\_r(struct utmp *buffer, struct utmp **result, struct utmp + *ut)} +\fdesc{Ricerca una voce sul registro.} +\fdecl{int *getutline\_r(struct utmp *buffer, struct utmp **result, struct utmp + *ut)} +\fdesc{Ricerca una voce sul registro attinente a un terminale.} +} +{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} assumerà il valore riportato dalle funzioni di sistema + sottostanti.} +\end{funcproto} +Le funzioni si comportano esattamente come le precedenti analoghe non +\index{funzioni!rientranti} rientranti, solo che restituiscono il risultato +all'indirizzo specificato dal primo argomento aggiuntivo \param{buffer} mentre +il secondo, \param{result)} viene usato per restituire il puntatore al buffer +stesso. -% TODO documentare keyctl ???? -% (fare sezione dedicata ????) -%\subsection{La gestione delle chiavi crittografiche} -%\label{sec:keyctl_management} +Infine le \acr{glibc} forniscono altre due funzioni, \funcd{updwtmp} e +\funcd{logwtmp}, come estensione per scrivere direttamente delle voci nel file +sul registro storico \sysfile{/var/log/wtmp}; i rispettivi prototipi sono: + +\begin{funcproto}{ +\fhead{utmp.h} +\fdecl{void updwtmp(const char *wtmp\_file, const struct utmp *ut)} +\fdesc{Aggiunge una voce in coda al registro.} +\fdecl{void logwtmp(const char *line, const char *name, const char *host)} +\fdesc{Aggiunge nel registro una voce con i valori specificati.} +} + +{Le funzioni non restituiscono nulla.} +\end{funcproto} + +La prima funzione permette l'aggiunta di una voce in coda al file del registro +storico, indicato dal primo argomento, specificando direttamente una struttura +\struct{utmp}. La seconda invece utilizza gli argomenti \param{line}, +\param{name} e \param{host} per costruire la voce che poi aggiunge chiamando +\func{updwtmp}. + +Queste funzioni non sono previste da POSIX.1-2001, anche se sono presenti in +altri sistemi (ad esempio Solaris e NetBSD), per mantenere una coerenza con le +altre funzioni definite nello standard che usano la struttura \struct{utmpx} +la \acr{glibc} definisce anche una funzione \funcm{updwtmpx}, che come in +precedenza è identica a \func{updwtmp} con la sola differenza di richiedere +l'uso di \headfile{utmpx.h} e di una struttura \struct{utmpx} come secondo +argomento. \subsection{La gestione dello spegnimento e del riavvio} \label{sec:sys_reboot} -(da fare) +Una delle operazioni di gestione generale del sistema è quella che attiene +alle modalità con cui se ne può gestire lo spegnimento ed il riavvio. Perché +questo avvenga in maniera corretta, in particolare per le parti che comportano +lo spegnimento effettivo della macchina, occorre che il kernel effettui le +opportune operazioni interagendo con il BIOS ed i dispositivi che controllano +l'erogazione della potenza. + +La funzione di sistema che controlla lo spegnimento ed il riavvio (ed altri +aspetti della relativa procedura) è \funcd{reboot},\footnote{la funzione + illustrata è quella fornita dalla \acr{glibc} che maschera i dettagli di + basso livello della \textit{system call} la quale richiede attualmente tre + argomenti; fino al kernel 2.1.30 la \textit{system call} richiedeva un + ulteriore quarto argomento, i primi due indicano dei \textit{magic number} + interi che possono assumere solo alcuni valori predefiniti, il terzo un + comando, corrispondente all'unico argomento della funzione della \acr{glibc} + ed il quarto argomento aggiuntivo, ora ignorato, un puntatore generico ad + ulteriori dati.} il cui prototipo è: -% TODO trattare reboot, kexec_load, ... +\begin{funcproto}{ +\fhead{unistd.h} +\fhead{sys/reboot.h} +\fdecl{int reboot(int cmd)} +\fdesc{Controlla il riavvio o l'arresto della macchina.} +} + +{La funzione non ritorna o ritorna $0$ in caso di successo e $-1$ per un + errore, nel qual caso \var{errno} assumerà uno dei valori: + \begin{errlist} + \item[\errcode{EFAULT}] c'è un indirizzo non valido nel passaggio degli + argomenti con il comando \const{LINUX\_REBOOT\_CMD\_RESTART2} (obsoleto). + \item[\errcode{EINVAL}] si sono specificati valori non validi per gli + argomenti. + \item[\errcode{EPERM}] il chiamante non ha i privilegi di amministratore (la + \textit{capability} \const{CAP\_SYS\_BOOT}). + \end{errlist} +} +\end{funcproto} + +La funzione, oltre al riavvio ed allo spegnimento, consente anche di +controllare l'uso della combinazione di tasti tradizionalmente usata come +scorciatoia da tastiera per richiedere il riavvio (\texttt{Ctrl-Alt-Del}, +denominata in breve nella documentazione CAD) ed i suoi effetti specifici +dipendono dalla architettura hardware. Se si è richiesto un riavvio o uno +spegnimento in caso di successo la funzione, non esistendo più il programma, +ovviamente non ritorna, pertanto bisogna avere cura di aver effettuato tutte +le operazioni preliminari allo spegnimento prima di eseguirla. + +Il comportamento della funzione viene controllato dall'argomento \param{cmd} +e deve assumere indicato con una delle costanti seguente elenco, che +illustra i comandi attualmente disponibili: + +\begin{basedescript}{\desclabelwidth{2.cm}\desclabelstyle{\nextlinelabel}} +\item[\const{LINUX\_REBOOT\_CMD\_CAD\_OFF}] Disabilita l'uso diretto della + combinazione \texttt{Ctrl-Alt-Del}, la cui pressione si traduce nell'invio + del segnale \const{SIGINT} a \texttt{init} (o più in generale al processo + con \ids{PID} 1) il cui effetto dipende dalla configurazione di + quest'ultimo. +\item[\const{LINUX\_REBOOT\_CMD\_CAD\_ON}] Attiva l'uso diretto della + combinazione \texttt{Ctrl-Alt-Del}, la cui pressione si traduce + nell'esecuzione dell'azione che si avrebbe avuto chiamando \func{reboot} con + il comando \const{LINUX\_REBOOT\_CMD\_RESTART}. +\item[\const{LINUX\_REBOOT\_CMD\_HALT}] Viene inviato sulla console il + messaggio ``\textit{System halted.}'' l'esecuzione viene bloccata + immediatamente ed il controllo passato al monitor nella ROM (se esiste e + l'architettura lo consente). Se non si è eseguita una sincronizzazione dei + dati su disco con \func{sync} questi saranno perduti. +\item[\const{LINUX\_REBOOT\_CMD\_KEXEC}] viene eseguito direttamente il nuovo + kernel che è stato opportunamente caricato in memoria da una + \func{kexec\_load} (che tratteremo a breve) eseguita in precedenza. La + funzionalità è disponibile solo a partire dal kernel 2.6.13 e se il kernel + corrente è stato compilato includendo il relativo supporto.\footnote{deve + essere stata abilitata l'opzione di compilazione \texttt{CONFIG\_KEXEC}.} + Questo meccanismo consente di eseguire una sorta di riavvio rapido che evita + di dover ripassare dalla inizializzazione da parte del BIOS ed il lancio del + kernel attraverso un bootloader. Se non si è eseguita una sincronizzazione + dei dati su disco con \func{sync} questi saranno perduti. +\item[\const{LINUX\_REBOOT\_CMD\_POWER\_OFF}] Viene inviato sulla console il + messaggio ``\textit{Power down.}'' l'esecuzione viene bloccata + immediatamente e la macchina, se possibile, viene spenta. Se non si è + eseguita una sincronizzazione dei dati su disco con \func{sync} questi + saranno perduti. +\item[\const{LINUX\_REBOOT\_CMD\_RESTART}] Viene inviato sulla console il + messaggio ``\textit{Restarting system.}'' ed avviata immediatamente la + procedura di riavvio ordinaria. Se non si è eseguita una sincronizzazione + dei dati su disco con \func{sync} questi saranno perduti. +\item[\const{LINUX\_REBOOT\_CMD\_RESTART2}] Viene inviato sulla console il + messaggio ``\textit{Restarting system with command '\%s'.}'' ed avviata + immediatamente la procedura di riavvio usando il comando fornito + nell'argomento \param{arg} che viene stampato al posto di \textit{'\%s'} + (veniva usato per lanciare un altro programma al posto di \cmd{init}). Nelle + versioni recenti questo argomento viene ignorato ed il riavvio può essere + controllato dall'argomento di avvio del kernel \texttt{reboot=...} Se non + si è eseguita una sincronizzazione dei dati su disco con \func{sync} questi + saranno perduti. +\end{basedescript} + + +Come appena illustrato usando il comando \const{LINUX\_REBOOT\_CMD\_KEXEC} si +può eseguire un riavvio immediato pre-caricando una immagine del kernel, che +verrà eseguita direttamente. Questo meccanismo consente di evitare la +reinizializzazione della macchina da parte del BIOS, ed oltre a velocizzare un +eventuale riavvio, ha il vantaggio poter accedere allo stato corrente della +macchina e della memoria, per cui viene usato spesso per installare un kernel +di emergenza da eseguire in caso di crollo del sistema per recuperare il +maggior numero di informazioni possibili. + +La funzione di sistema che consente di caricare questa immagine del kernel è +\funcd{kexec\_load}, la funzione non viene definita nella \acr{glibc} e deve +pertanto essere invocata con \func{syscall}, il suo prototipo è: + +\begin{funcproto}{ +\fhead{linux/kexec.h} +\fdecl{long kexec\_load(unsigned long entry, unsigned long nr\_segments, +struct kexec\_segment\\ +\phantom{long kexec\_load(}*segments, unsigned long flags)} + +\fdesc{Carica un kernel per un riavvio immediato.} +} + +{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} assumerà uno dei valori: + \begin{errlist} + \item[\errcode{EBUSY}] c'è già un caricamento in corso, o un altro kernel è + già in uso. + \item[\errcode{EINVAL}] il valore di \param{flags} non è valido o si è + indicato un valore eccessivo per \param{nr\_segments}. + \item[\errcode{EPERM}] il chiamante non ha i privilegi di amministratore (la + \textit{capability} \const{CAP\_SYS\_BOOT}). + \end{errlist} +} +\end{funcproto} + +Il primo argomento indica l'indirizzo fisico di esecuzione del nuovo kernel +questo viene caricato usando un vettore di strutture \struct{kexec\_segment} +(la cui definizione è riportata in fig.~\ref{fig:kexec_segment}) che +contengono i singoli segmenti dell'immagine. I primi due campi indicano +indirizzo e dimensione del segmento di memoria in \textit{user space}, i +secondi indirizzo e dimensione in \textit{kernel space}. +\begin{figure}[!htb] + \footnotesize + \centering + \begin{minipage}[c]{0.8\textwidth} + \includestruct{listati/kexec_segment.h} + \end{minipage} + \normalsize + \caption{La struttura \structd{kexec\_segment} per il caricamento di un + segmento di immagine del kernel.} + \label{fig:kexec_segment} +\end{figure} + +L'argomento \param{flags} è una maschera binaria contenente i flag che +consentono di indicare le modalità con cui dovrà essere eseguito il nuovo +kernel. La parte meno significativa viene usata per impostare l'architettura +di esecuzione. Il valore \const{KEXEC\_ARCH\_DEFAULT} indica l'architettura +corrente, ma se ne può specificare anche una diversa, con i valori della +seconda parte di tab.~\ref{tab:kexec_load_flags}, e questa verrà usato posto +che sia effettivamente eseguibile sul proprio processore. + +\begin{table}[htb] + \footnotesize + \centering + \begin{tabular}[c]{|l|p{8cm}|} + \hline + \textbf{Valore} & \textbf{Significato}\\ + \hline + \hline + \const{KEXEC\_ON\_CRASH} & Il kernel caricato sarà eseguito + automaticamente in caso di crollo del + sistema.\\ + \const{KEXEC\_PRESERVE\_CONTEXT}& Viene preservato lo stato dei programmi + e dei dispositivi prima dell'esecuzione + del nuovo kernel. Viene usato + principalmente per l'ibernazione del + sistema ed ha senso solo se si è + indicato un numero di segmento maggiore + di zero.\\ + \hline + \const{KEXEC\_ARCH\_DEFAULT} & Il kernel caricato verrà eseguito nella + architettura corrente. \\ + \texttt{KEXEC\_ARCH\_XXX} & Il kernel caricato verrà eseguito nella + architettura indicata (con \texttt{XXX} + che può essere: \texttt{386}, + \texttt{X86\_64}, \texttt{PPC}, + \texttt{PPC64}, \texttt{IA\_64}, + \texttt{ARM}, \texttt{S390}, + \texttt{SH}\texttt{MIPS} + e \texttt{MIPS\_LE}).\\ +% \const{} & \\ + \hline + \end{tabular} + \caption{Valori per l'argomento \param{flags} di \func{kexec\_load}.} + \label{tab:kexec_load_flags} +\end{table} + +I due valori più importanti sono però quelli della parte più significativa +(riportati nella prima sezione di tab.~\ref{tab:kexec_load_flags}). Il primo, +\const{KEXEC\_ON\_CRASH}, consente di impostare l'esecuzione automatica del +nuovo kernel caricato in caso di crollo del sistema, e viene usato quando si +carica un kernel di emergenza da utilizzare per poter raccogliere informazioni +diagnostiche che altrimenti verrebbero perdute non essendo il kernel ordinario +più in grado di essere eseguito in maniera coerente. Il secondo valore, +\const{KEXEC\_PRESERVE\_CONTEXT}, indica invece di preservare lo stato dei +programmi e dei dispositivi, e viene in genere usato per realizzare la +cosiddetta ibernazione in RAM. + +% TODO documentare keyctl ???? +% (fare sezione dedicata ????) +%\subsection{La gestione delle chiavi crittografiche} +%\label{sec:keyctl_management} + \section{Il controllo dell'uso delle risorse} \label{sec:sys_res_limits} -Dopo aver esaminato le funzioni che permettono di controllare le varie -caratteristiche, capacità e limiti del sistema a livello globale, in questa -sezione tratteremo le varie funzioni che vengono usate per quantificare le -risorse (CPU, memoria, ecc.) utilizzate da ogni singolo processo e quelle che -permettono di imporre a ciascuno di essi vincoli e limiti di -utilizzo. +Dopo aver esaminato in sez.~\ref{sec:sys_management} le funzioni che +permettono di controllare le varie caratteristiche, capacità e limiti del +sistema a livello globale, in questa sezione tratteremo le varie funzioni che +vengono usate per quantificare le risorse (CPU, memoria, ecc.) utilizzate da +ogni singolo processo e quelle che permettono di imporre a ciascuno di essi +vincoli e limiti di utilizzo. \subsection{L'uso delle risorse} @@ -1142,12 +1427,14 @@ utilizzo. Come abbiamo accennato in sez.~\ref{sec:proc_wait} le informazioni riguardo l'utilizzo delle risorse da parte di un processo è mantenuto in una struttura di tipo \struct{rusage}, la cui definizione (che si trova in -\headfile{sys/resource.h}) è riportata in fig.~\ref{fig:sys_rusage_struct}. +\headfile{sys/resource.h}) è riportata in fig.~\ref{fig:sys_rusage_struct}. Si +ricordi che questa è una delle informazioni preservate attraverso una +\func{exec}. \begin{figure}[!htb] \footnotesize \centering - \begin{minipage}[c]{\textwidth} + \begin{minipage}[c]{0.8\textwidth} \includestruct{listati/rusage.h} \end{minipage} \normalsize @@ -1158,23 +1445,16 @@ di tipo \struct{rusage}, la cui definizione (che si trova in La definizione della struttura in fig.~\ref{fig:sys_rusage_struct} è ripresa da BSD 4.3,\footnote{questo non ha a nulla a che fare con il cosiddetto - \textit{BSD accounting} (vedi sez. \ref{sec:sys_bsd_accounting}) che si trova - nelle opzioni di compilazione del kernel (e di norma è disabilitato) che - serve per mantenere una contabilità delle risorse usate da ciascun processo - in maniera molto più dettagliata.} ma attualmente (con i kernel della serie -2.4.x e 2.6.x) i soli campi che sono mantenuti sono: \var{ru\_utime}, -\var{ru\_stime}, \var{ru\_minflt}, \var{ru\_majflt}, e \var{ru\_nswap}. I -primi due indicano rispettivamente il tempo impiegato dal processo -nell'eseguire le istruzioni in user space, e quello impiegato dal kernel nelle -system call eseguite per conto del processo. - -Gli altri tre campi servono a quantificare l'uso della memoria -virtuale\index{memoria~virtuale} e corrispondono rispettivamente al numero di -\itindex{page~fault} \textit{page fault} (vedi sez.~\ref{sec:proc_mem_gen}) -avvenuti senza richiedere I/O su disco (i cosiddetti \textit{minor page - fault}), a quelli che invece han richiesto I/O su disco (detti invece -\textit{major page fault}) ed al numero di volte che il processo è stato -completamente tolto dalla memoria per essere inserito nello swap. + \textit{BSD accounting} (vedi sez. \ref{sec:sys_bsd_accounting}) che si + trova nelle opzioni di compilazione del kernel (e di norma è disabilitato) + che serve per mantenere una contabilità delle risorse usate da ciascun + processo in maniera molto più dettagliata.} ma attualmente solo alcuni dei +campi definiti sono effettivamente mantenuti. Con i kernel della serie 2.4 i +soli campi che sono mantenuti sono: \var{ru\_utime}, \var{ru\_stime}, +\var{ru\_minflt} e \var{ru\_majflt}. Con i kernel della serie 2.6 si +aggiungono anche \var{ru\_nvcsw} e \var{ru\_nivcsw}, a partire dal 2.6.22 +anche \var{ru\_inblock} e \var{ru\_oublock} e dal 2.6.32 anche +\var{ru\_maxrss}. In genere includere esplicitamente \file{} non è più strettamente necessario, ma aumenta la portabilità, e serve comunque quando, come nella @@ -1182,31 +1462,100 @@ maggior parte dei casi, si debba accedere ai campi di \struct{rusage} relativi ai tempi di utilizzo del processore, che sono definiti come strutture di tipo \struct{timeval} (vedi fig.~\ref{fig:sys_timeval_struct}). -Questa è la stessa struttura utilizzata da \func{wait4} (si ricordi quando -visto in sez.~\ref{sec:proc_wait}) per ricavare la quantità di risorse -impiegate dal processo di cui si è letto lo stato di terminazione, ma essa può -anche essere letta direttamente utilizzando la funzione \funcd{getrusage}, il -cui prototipo è: -\begin{functions} - \headdecl{sys/time.h} - \headdecl{sys/resource.h} - \headdecl{unistd.h} - - \funcdecl{int getrusage(int who, struct rusage *usage)} - Legge la quantità di risorse usate da un processo. +La struttura \struct{rusage} è la struttura utilizzata da \func{wait4} (si +ricordi quando visto in sez.~\ref{sec:proc_wait}) per ricavare la quantità di +risorse impiegate dal processo di cui si è letto lo stato di terminazione, ma +essa può anche essere letta direttamente utilizzando la funzione di sistema +\funcd{getrusage}, il cui prototipo è: +\begin{funcproto}{ +\fhead{sys/time.h} +\fhead{sys/resource.h} +\fhead{unistd.h} +\fdecl{int getrusage(int who, struct rusage *usage)} - \bodydesc{La funzione ritorna 0 in caso di successo e -1 in caso di errore, - nel qual caso \var{errno} può essere \errval{EINVAL} o \errval{EFAULT}.} -\end{functions} +\fdesc{Legge la quantità di risorse usate da un processo.} +} + +{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} assumerà uno dei valori: + \begin{errlist} + \item[\errcode{EINVAL}] l'argomento \param{who} non è valido + \end{errlist} + ed inoltre \errval{EFAULT} nel suo significato generico. +} +\end{funcproto} + +La funzione ritorna i valori per l'uso delle risorse nella struttura +\struct{rusage} puntata dall'argomento \param{usage}. L'argomento \param{who} +permette di specificare il soggetto di cui si vuole leggere l'uso delle +risorse; esso può assumere solo i valori illustrati in +tab.~\ref{tab:getrusage_who}, di questi \const{RUSAGE\_THREAD} è specifico di +Linux ed è disponibile solo a partire dal kernel 2.6.26. La funzione è stata +recepita nello standard POSIX.1-2001, che però indica come campi di +\struct{rusage} soltanto \var{ru\_utime} e \var{ru\_stime}. + +\begin{table}[htb] + \footnotesize + \centering + \begin{tabular}[c]{|l|p{8cm}|} + \hline + \textbf{Valore} & \textbf{Significato}\\ + \hline + \hline + \const{RUSAGE\_SELF} & ritorna l'uso delle risorse del processo + corrente, che in caso di uso dei + \textit{thread} ammonta alla somma delle + risorse utilizzate da tutti i \textit{thread} + del processo.\\ + \const{RUSAGE\_CHILDREN} & ritorna l'uso delle risorse dell'insieme dei + processi figli di cui è ricevuto lo stato di + terminazione, che a loro volta comprendono + quelle dei loro figli e così via.\\ + \const{RUSAGE\_THREAD} & ritorna l'uso delle risorse del \textit{thread} + chiamante.\\ + \hline + \end{tabular} + \caption{Valori per l'argomento \param{who} di \func{getrusage}.} + \label{tab:getrusage_who} +\end{table} -L'argomento \param{who} permette di specificare il processo di cui si vuole -leggere l'uso delle risorse; esso può assumere solo i due valori -\const{RUSAGE\_SELF} per indicare il processo corrente e -\const{RUSAGE\_CHILDREN} per indicare l'insieme dei processi figli di cui si è -ricevuto lo stato di terminazione. +I campi più utilizzati sono comunque \var{ru\_utime} e \var{ru\_stime} che +indicano rispettivamente il tempo impiegato dal processo nell'eseguire le +istruzioni in user space, e quello impiegato dal kernel nelle \textit{system + call} eseguite per conto del processo. I campi \var{ru\_minflt} e +\var{ru\_majflt} servono a quantificare l'uso della memoria +virtuale\index{memoria~virtuale} e corrispondono rispettivamente al numero di +\itindex{page~fault} \textit{page fault} (vedi sez.~\ref{sec:proc_mem_gen}) +avvenuti senza richiedere I/O su disco (i cosiddetti \textit{minor page + fault}), a quelli che invece han richiesto I/O su disco (detti invece +\textit{major page fault}).% mentre \var{ru\_nswap} ed al numero di volte che +% il processo è stato completamente tolto dalla memoria per essere inserito +% nello swap. +% TODO verificare \var{ru\_nswap} non citato nelle pagine di manuali recenti e +% dato per non utilizzato. + +I campi \var{ru\_nvcsw} e \var{ru\_nivcsw} indicano il numero di volte che un +processo ha subito un \textit{context switch} da parte dello +\textit{scheduler} rispettivamente nel caso un cui questo avviene prima +dell'esaurimento della propria \textit{time-slice} (in genere a causa di una +\textit{system call} bloccante), o per averla esaurita o essere stato +interrotto da un processo a priorità maggiore. I campi \var{ru\_inblock} e +\var{ru\_oublock} indicano invece il numero di volte che è stata eseguita una +attività di I/O su un filesystem (rispettivamente in lettura e scrittura) ed +infine \var{ru\_maxrss} indica il valore più alto della +\itindex{Resident~Set~Size~(RSS)} \textit{Resident Set Size} raggiunto dal +processo stesso o, nel caso sia stato usato \const{RUSAGE\_CHILDREN}, da uno +dei suoi figli. + +Si tenga conto che per un errore di implementazione nei i kernel precedenti il +2.6.9, nonostante questo fosse esplicitamente proibito dallo standard POSIX.1, +l'uso di \const{RUSAGE\_CHILDREN} comportava l'inserimento dell'ammontare +delle risorse usate dai processi figli anche quando si era impostata una +azione di \const{SIG\_IGN} per il segnale \const{SIGCHLD} (per i segnali si +veda cap.~\ref{cha:signals}). Il comportamento è stato corretto per aderire +allo standard a partire dal kernel 2.6.9. -% TODO previsto in futuro \const{RUSAGE\_THREAD}, verificare. \subsection{Limiti sulle risorse} \label{sec:sys_resource_limit} @@ -1214,9 +1563,9 @@ ricevuto lo stato di terminazione. Come accennato nell'introduzione il kernel mette a disposizione delle funzionalità che permettono non solo di mantenere dati statistici relativi all'uso delle risorse, ma anche di imporre dei limiti precisi sul loro -utilizzo da parte dei vari processi o degli utenti. +utilizzo da parte sia dei singoli processi che degli utenti. -Per far questo esistono una serie di risorse e ad ogni processo vengono +Per far questo sono definite una serie di risorse e ad ogni processo vengono associati due diversi limiti per ciascuna di esse; questi sono il \textsl{limite corrente} (o \textit{current limit}) che esprime un valore massimo che il processo non può superare ad un certo momento, ed il @@ -1227,183 +1576,53 @@ essere aumentato dal processo stesso durante l'esecuzione, ciò può però esser fatto solo fino al valore del secondo, che per questo viene detto \textit{hard limit}. -%TODO: tabella troppo grossa, trasformare in lista +In generale il superamento di un limite corrente comporta o l'emissione di uno +specifico segnale o il fallimento della \textit{system call} che lo ha +provocato. A questo comportamento generico fanno eccezione \const{RLIMIT\_CPU} +in cui si ha in comportamento diverso per il superamento dei due limiti e +\const{RLIMIT\_CORE} che influenza soltanto la dimensione o l'eventuale +creazione dei file di \itindex{core~dump} \textit{core dump} (vedi +sez.~\ref{sec:sig_standard}). -\begin{table}[htb] - \footnotesize - \centering - \begin{tabular}[c]{|l|p{12cm}|} - \hline - \textbf{Valore} & \textbf{Significato}\\ - \hline - \hline - \const{RLIMIT\_AS} & La dimensione massima della memoria virtuale di - un processo, il cosiddetto \textit{Address - Space}, (vedi sez.~\ref{sec:proc_mem_gen}). Se - il limite viene superato dall'uso di funzioni - come \func{brk}, \func{mremap} o \func{mmap} - esse falliranno con un errore di - \errcode{ENOMEM}, mentre se il superamento viene - causato dalla crescita dello \itindex{stack} - \textit{stack} il processo riceverà un segnale di - \signal{SIGSEGV}.\\ - \const{RLIMIT\_CORE} & La massima dimensione per di un file di - \itindex{core~dump} \textit{core dump} (vedi - sez.~\ref{sec:sig_prog_error}) creato nella - terminazione di un processo; file di dimensioni - maggiori verranno troncati a questo valore, - mentre con un valore si bloccherà la creazione - dei \itindex{core~dump} \textit{core dump}.\\ - \const{RLIMIT\_CPU} & Il massimo tempo di CPU (vedi - sez.~\ref{sec:sys_cpu_times}) che il processo può - usare. Il superamento del limite corrente - comporta l'emissione di un segnale di - \signal{SIGXCPU}, la cui azione predefinita (vedi - sez.~\ref{sec:sig_classification}) è terminare - il processo, una volta al secondo fino al - raggiungimento del limite massimo. Il - superamento del limite massimo - comporta l'emissione di un segnale di - \signal{SIGKILL}.\footnotemark\\ - \const{RLIMIT\_DATA} & La massima dimensione del \index{segmento!dati} - segmento dati di un - processo (vedi sez.~\ref{sec:proc_mem_layout}). - Il tentativo di allocare più memoria di quanto - indicato dal limite corrente causa il fallimento - della funzione di allocazione (\func{brk} o - \func{sbrk}) con un errore di \errcode{ENOMEM}.\\ - \const{RLIMIT\_FSIZE} & La massima dimensione di un file che un processo - può creare. Se il processo cerca di scrivere - oltre questa dimensione riceverà un segnale di - \signal{SIGXFSZ}, che di norma termina il - processo; se questo viene intercettato la - system call che ha causato l'errore fallirà con - un errore di \errcode{EFBIG}.\\ - \const{RLIMIT\_LOCKS}& È un limite presente solo nelle prime versioni - del kernel 2.4 sul numero massimo di - \itindex{file~locking} \textit{file lock} (vedi - sez.~\ref{sec:file_locking}) che un - processo poteva effettuare.\\ - \const{RLIMIT\_MEMLOCK}& L'ammontare massimo di memoria che può essere - bloccata in RAM da un processo (vedi - sez.~\ref{sec:proc_mem_lock}). Dal kernel 2.6.9 - questo limite comprende anche la memoria che può - essere bloccata da ciascun utente nell'uso della - memoria condivisa (vedi - sez.~\ref{sec:ipc_sysv_shm}) che viene - contabilizzata separatamente ma sulla quale - viene applicato questo stesso limite.\\ -% TODO trattare i seguenti... -% \const{RLIMIT\_MSGQUEUE}& Il numero massimo di \\ -% \const{RLIMIT\_NICE}& Il numero massimo di \\ -% \const{RLIMIT\_RTPRIO}& Il numero massimo di \\ -% aggiungere i limiti che mancano come RLIMIT_RTTIME introdotto con il 2.6.25 -% vedi file include/asm-generic/resource.h - \const{RLIMIT\_NOFILE} & Il numero massimo di file che il processo può - aprire. L'apertura di un ulteriore file farà - fallire la funzione (\func{open}, \func{dup} o - \func{pipe}) con un errore \errcode{EMFILE}.\\ - \const{RLIMIT\_NPROC} & Il numero massimo di processi che possono essere - creati sullo stesso user id real. Se il limite - viene raggiunto \func{fork} fallirà con un - \errcode{EAGAIN}.\\ - \const{RLIMIT\_SIGPENDING}& Il numero massimo di segnali che possono - essere mantenuti in coda per ciascun utente, - considerando sia i segnali normali che real-time - (vedi sez.~\ref{sec:sig_real_time}). Il limite è - attivo solo per \func{sigqueue}, con \func{kill} - si potrà sempre inviare un segnale che non sia - già presente su una coda.\footnotemark\\ - \const{RLIMIT\_STACK} & La massima dimensione dello \itindex{stack} - \textit{stack} del processo. Se il processo - esegue operazioni che estendano lo - \textit{stack} oltre questa dimensione - riceverà un segnale di \signal{SIGSEGV}.\\ -% TODO dal 2.6.23 il significato è cambiato, vedi anche man execve - \const{RLIMIT\_RSS} & L'ammontare massimo di pagine di memoria dato al - \index{segmento!testo} testo del processo. Il - limite è solo una indicazione per il kernel, - qualora ci fosse un surplus di memoria questa - verrebbe assegnata.\\ -% TODO: aggiungere a \const{RLIMIT\_STACK} i dati di execve: -% Questi fino al kernel 2.6.23 erano fissi e costituiti da -% 32 pagine di memoria (corrispondenti per la gran parte delle architetture a -% 128kb di dati). Dal 2.6.23 su molte architettire il limite viene stabilito in -% base al valore della risorsa \const{RLIMIT\_STACK} (vedi -% sez.~\ref{sec:sys_resource_limit}), ad un quarto dello spazio da essa -% indicato). Dal 2.6.25 viene comunque garantito uno spazio base di 32 pagine. - -% TODO integrare con la roba di madvise -% TODO integrare con le ultime aggiunte, vedi pagina di manuale - \hline - \end{tabular} - \caption{Valori possibili dell'argomento \param{resource} delle funzioni - \func{getrlimit} e \func{setrlimit}.} - \label{tab:sys_rlimit_values} -\end{table} +Per permettere di leggere e di impostare i limiti di utilizzo delle risorse da +parte di un processo sono previste due funzioni di sistema, \funcd{getrlimit} +e \funcd{setrlimit}, i cui prototipi sono: -\footnotetext[18]{questo è quanto avviene per i kernel dalla serie 2.2 fino ad - oggi (la 2.6.x); altri kernel possono avere comportamenti diversi per quanto - avviene quando viene superato il \textit{soft limit}; perciò per avere - operazioni portabili è sempre opportuno intercettare il primo - \signal{SIGXCPU} e terminare in maniera ordinata il processo.} - -\footnotetext{il limite su questa risorsa è stato introdotto con il kernel - 2.6.8.} - -% TODO trattare prlimit64 introdotta con il 2.6.36 che dovrebbe sostituire -% setrlimit - - -In generale il superamento di un limite corrente\footnote{di norma quanto - riportato in tab.~\ref{tab:sys_rlimit_values} fa riferimento a quanto - avviene al superamento del limite corrente, con l'eccezione - \const{RLIMIT\_CPU} in cui si ha in comportamento diverso per il superamento - dei due limiti.} comporta o l'emissione di un segnale o il fallimento della -system call che lo ha provocato;\footnote{si nuovo c'è una eccezione per - \const{RLIMIT\_CORE} che influenza soltanto la dimensione (o l'eventuale - creazione) dei file di \itindex{core~dump} \textit{core dump}.} per -permettere di leggere e di impostare i limiti di utilizzo delle risorse da -parte di un processo sono previste due funzioni, \funcd{getrlimit} e -\funcd{setrlimit}, i cui prototipi sono: -\begin{functions} - \headdecl{sys/time.h} - \headdecl{sys/resource.h} - \headdecl{unistd.h} - - \funcdecl{int getrlimit(int resource, struct rlimit *rlim)} +\begin{funcproto}{ +\fhead{sys/time.h} +\fhead{sys/resource.h} +\fhead{unistd.h} +\fdecl{int getrlimit(int resource, struct rlimit *rlim)} +\fdesc{Legge i limiti di una risorsa.} +\fdecl{int setrlimit(int resource, const struct rlimit *rlim)} +\fdesc{Imposta i limiti di una risorsa.} +} - Legge il limite corrente per la risorsa \param{resource}. - - \funcdecl{int setrlimit(int resource, const struct rlimit *rlim)} - - Imposta il limite per la risorsa \param{resource}. - - \bodydesc{Le funzioni ritornano 0 in caso di successo e -1 in caso di - errore, nel qual caso \var{errno} assumerà uno dei valori: - \begin{errlist} - \item[\errcode{EINVAL}] i valori per \param{resource} non sono validi. +{Le funzioni ritornano $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} assumerà uno dei valori: + \begin{errlist} + \item[\errcode{EINVAL}] i valori per \param{resource} non sono validi o + nell'impostazione si è specificato \var{rlim->rlim\_cur} maggiore di + \var{rlim->rlim\_max}. \item[\errcode{EPERM}] un processo senza i privilegi di amministratore ha cercato di innalzare i propri limiti. - \end{errlist} - ed \errval{EFAULT}.} -\end{functions} - + \end{errlist} + ed inoltre \errval{EFAULT} nel suo significato generico. +} +\end{funcproto} -Entrambe le funzioni permettono di specificare, attraverso l'argomento -\param{resource}, su quale risorsa si vuole operare: i possibili valori di -questo argomento sono elencati in tab.~\ref{tab:sys_rlimit_values}. L'acceso -(rispettivamente in lettura e scrittura) ai valori effettivi dei limiti viene -poi effettuato attraverso la struttura \struct{rlimit} puntata da +Entrambe le funzioni permettono di specificare attraverso l'argomento +\param{resource} su quale risorsa si vuole operare. L'accesso (rispettivamente +in lettura e scrittura) ai valori effettivi dei limiti viene poi effettuato +attraverso la struttura \struct{rlimit} puntata da \param{rlim}, la cui definizione è riportata in fig.~\ref{fig:sys_rlimit_struct}, ed i cui campi corrispondono appunto a limite corrente e limite massimo. - \begin{figure}[!htb] \footnotesize \centering - \begin{minipage}[c]{\textwidth} + \begin{minipage}[c]{0.8\textwidth} \includestruct{listati/rlimit.h} \end{minipage} \normalsize @@ -1412,18 +1631,239 @@ limite corrente e limite massimo. \label{fig:sys_rlimit_struct} \end{figure} +Come accennato processo ordinario può alzare il proprio limite corrente fino +al valore del limite massimo, può anche ridurre, irreversibilmente, il valore +di quest'ultimo. Nello specificare un limite, oltre a fornire dei valori +specifici, si può anche usare la costante \const{RLIM\_INFINITY} che permette +di sbloccare completamente l'uso di una risorsa. Si ricordi però che solo un +processo con i privilegi di amministratore\footnote{per essere precisi in + questo caso quello che serve è la \itindex{capabilities} \textit{capability} + \const{CAP\_SYS\_RESOURCE} (vedi sez.~\ref{sec:proc_capabilities}).} può +innalzare un limite al di sopra del valore corrente del limite massimo ed +usare un valore qualsiasi per entrambi i limiti. + +Ciascuna risorsa su cui si possono applicare dei limiti è identificata da uno +specifico valore dell'argomento \param{resource}, i valori possibili per +questo argomento, ed il significato della risorsa corrispondente, dei +rispettivi limiti e gli effetti causati dal superamento degli stessi sono +riportati nel seguente elenco: + +\begin{basedescript}{\desclabelwidth{2.2cm}}%\desclabelstyle{\nextlinelabel}} +\item[\const{RLIMIT\_AS}] Questa risorsa indica, in byte, la dimensione + massima consentita per la memoria virtuale di un processo, il cosiddetto + \textit{Address Space}, (vedi sez.~\ref{sec:proc_mem_gen}). Se il limite + viene superato dall'uso di funzioni come \func{brk}, \func{mremap} o + \func{mmap} esse falliranno con un errore di \errcode{ENOMEM}, mentre se il + superamento viene causato dalla crescita dello \itindex{stack} + \textit{stack} il processo riceverà un segnale di \signal{SIGSEGV}. Dato che + il valore usato è un intero di tipo \ctyp{long} nelle macchine a 32 bit + questo può assumere un valore massimo di 2Gb (anche se la memoria + disponibile può essere maggiore), in tal caso il limite massimo indicabile + resta 2Gb, altrimenti la risorsa si dà per non limitata. + +\item[\const{RLIMIT\_CORE}] Questa risorsa indica, in byte, la massima + dimensione per un file di \itindex{core~dump} \textit{core dump} (vedi + sez.~\ref{sec:sig_standard}) creato nella terminazione di un processo. File + di dimensioni maggiori verranno troncati a questo valore, mentre con un + valore nullo si bloccherà la creazione dei \itindex{core~dump} \textit{core + dump}. + +\item[\const{RLIMIT\_CPU}] Questa risorsa indica, in secondi, il massimo tempo + di CPU (vedi sez.~\ref{sec:sys_cpu_times}) che il processo può usare. Il + superamento del limite corrente comporta l'emissione di un segnale di + \signal{SIGXCPU}, la cui azione predefinita (vedi + sez.~\ref{sec:sig_classification}) è terminare il processo. Il segnale però + può essere intercettato e ignorato, in tal caso esso verrà riemesso una + volta al secondo fino al raggiungimento del limite massimo. Il superamento + del limite massimo comporta comunque l'emissione di un segnale di + \signal{SIGKILL}. Si tenga presente che questo è il comportamento presente + su Linux dai kernel della serie 2.2 ad oggi, altri kernel possono avere + comportamenti diversi per quanto avviene quando viene superato il + \textit{soft limit}, pertanto per avere operazioni portabili è suggerito di + intercettare sempre \signal{SIGXCPU} e terminare in maniera ordinata il + processo con la prima ricezione. + +\item[\const{RLIMIT\_DATA}] Questa risorsa indica, in byte, la massima + dimensione del \index{segmento!dati} segmento dati di un processo (vedi + sez.~\ref{sec:proc_mem_layout}). Il tentativo di allocare più memoria di + quanto indicato dal limite corrente causa il fallimento della funzione di + allocazione eseguita (\func{brk} o \func{sbrk}) con un errore di + \errcode{ENOMEM}. + +\item[\const{RLIMIT\_FSIZE}] Questa risorsa indica, in byte, la massima + dimensione di un file che un processo può usare. Se il processo cerca di + scrivere o di estendere il file oltre questa dimensione riceverà un segnale + di \signal{SIGXFSZ}, che di norma termina il processo. Se questo segnale + viene intercettato la \textit{system call} che ha causato l'errore fallirà + con un errore di \errcode{EFBIG}. + +\item[\const{RLIMIT\_LOCKS}] Questa risorsa indica il numero massimo di + \itindex{file~locking} \textit{file lock} (vedi sez.~\ref{sec:file_locking}) + e di \textit{file lease} (vedi sez.~\ref{sec:file_asyncronous_lease}) che un + processo poteva effettuare. È un limite presente solo nelle prime versioni + del kernel 2.4, pertanto non deve essere più utilizzato. + +\item[\const{RLIMIT\_MEMLOCK}] Questa risorsa indica, in byte, l'ammontare + massimo di memoria che può essere bloccata in RAM da un processo (vedi + sez.~\ref{sec:proc_mem_lock}). Dato che il \itindex{memory~locking} + \textit{memory locking} viene effettuato sulle pagine di memoria, il valore + indicato viene automaticamente arrotondato al primo multiplo successivo + della dimensione di una pagina di memoria. Il limite comporta il fallimento + delle \textit{system call} che eseguono il \textit{memory locking} + (\func{mlock}, \func{mlockall} ed anche, vedi + sez.~\ref{sec:file_memory_map}, \func{mmap} con l'operazione + \const{MAP\_LOCKED}). + + Dal kernel 2.6.9 questo limite comprende anche la memoria che può essere + bloccata da ciascun utente nell'uso della memoria condivisa (vedi + sez.~\ref{sec:ipc_sysv_shm}) con \func{shmctl}, che viene contabilizzata + separatamente ma sulla quale viene applicato questo stesso limite. In + precedenza invece questo limite veniva applicato sulla memoria condivisa per + processi con privilegi amministrativi, il limite su questi è stato rimosso e + la semantica della risorsa cambiata. + + +\item[\const{RLIMIT\_MSGQUEUE}] Questa risorsa indica il numero massimo di + byte che possono essere utilizzati da un utente, identificato con + l'\ids{UID} reale del processo chiamante, per le code di messaggi POSIX + (vedi sez.~\ref{sec:ipc_posix_mq}). Per ciascuna coda che viene creata viene + calcolata un'occupazione pari a: +\includecodesnip{listati/mq_occupation.c} +dove \var{attr} è la struttura \struct{mq\_attr} (vedi +fig.~\ref{fig:ipc_mq_attr}) usata nella creazione della coda. Il primo addendo +consente di evitare la creazione di una coda con un numero illimitato di +messaggi vuoti che comunque richiede delle risorse di gestione. Questa risorsa +è stata introdotta con il kernel 2.6.8. + +\item[\const{RLIMIT\_NICE}] Questa risorsa indica il numero massimo a cui può + essere il portato il valore di \textit{nice} (vedi + sez.~\ref{sec:proc_sched_stand}). Dato che non possono essere usati numeri + negativi per specificare un limite, il valore di \textit{nice} viene + calcolato come \code{20-rlim\_cur}. Questa risorsa è stata introdotta con il + kernel 2.6.12. + +\item[\const{RLIMIT\_NOFILE}] Questa risorsa indica il numero massimo di file + che un processo può aprire. Il tentativo di creazione di un ulteriore file + descriptor farà fallire la funzione (\func{open}, \func{dup}, \func{pipe}, + ecc.) con un errore \errcode{EMFILE}. + +\item[\const{RLIMIT\_NPROC}] Questa risorsa indica il numero massimo di + processi che possono essere creati dallo stesso utente, che viene + identificato con l'\ids{UID} reale (vedi sez.~\ref{sec:proc_access_id}) del + processo chiamante. Se il limite viene raggiunto \func{fork} fallirà con un + \errcode{EAGAIN}. + +\item[\const{RLIMIT\_RSS}] Questa risorsa indica, in pagine di memoria, la + dimensione massima della memoria residente (il cosiddetto RSS + \itindex{Resident~Set~Size~(RSS)} \textit{Resident Set Size}) cioè + l'ammontare della memoria associata al processo che risiede effettivamente + in RAM e non a quella eventualmente portata sulla \textit{swap} o non ancora + caricata dal filesystem per il \index{segmento!testo} segmento testo del + programma. Ha effetto solo sulle chiamate a \func{madvise} con + \const{MADV\_WILLNEED} (vedi sez.~\ref{sec:file_memory_map}). Presente solo + sui i kernel precedenti il 2.4.30. + +\item[\const{RLIMIT\_RTPRIO}] Questa risorsa indica il valore massimo della + priorità statica che un processo può assegnarsi o assegnare con + \func{sched\_setscheduler} e \func{sched\_setparam} (vedi + sez.~\ref{sec:proc_real_time}). Il limite è stato introdotto a partire dal + kernel 2.6.12 (ma per un bug è effettivo solo a partire dal 2.6.13). In + precedenza solo i processi con privilegi amministrativi potevano avere una + priorità statica ed utilizzare una politica di \textit{scheduling} di tipo + \textit{real-time}. + +\item[\const{RLIMIT\_RTTIME}] Questa risorsa indica, in microsecondi, il tempo + massimo di CPU che un processo eseguito con una priorità statica può + consumare. Il superamento del limite corrente comporta l'emissione di un + segnale di \signal{SIGXCPU}, e quello del limite massimo di \signal{SIGKILL} + con le stesse regole viste \const{RLIMIT\_CPU}: se \signal{SIGXCPU} viene + intercettato ed ignorato il segnale verrà riemesso ogni secondo fino al + superamento del limite massimo. Questo limite è stato introdotto con il + kernel 2.6.25 per impedire che un processo \textit{real-time} possa bloccare + il sistema. + +% TODO trattare i seguenti... +% aggiungere i limiti che mancano come RLIMIT_RTTIME introdotto con il 2.6.25 +% vedi file include/asm-generic/resource.h + + +\item[\const{RLIMIT\_SIGPENDING}] Questa risorsa indica il numero massimo di + segnali che possono essere mantenuti in coda per ciascun utente, + identificato per \ids{UID} reale. Il limite comprende sia i segnali normali + che quelli \textit{real-time} (vedi sez.~\ref{sec:sig_real_time}) ed è + attivo solo per \func{sigqueue}, con \func{kill} si potrà sempre inviare un + segnale che non sia già presente su una coda. Questo limite è stato + introdotto con il kernel 2.6.8. + +\item[\const{RLIMIT\_STACK}] Questa risorsa indica, in byte, la massima + dimensione dello \itindex{stack} \textit{stack} del processo. Se il processo + esegue operazioni che estendano lo \textit{stack} oltre questa dimensione + riceverà un segnale di \signal{SIGSEGV}. + + A partire dal kernel 2.6.23 questo stesso limite viene applicato per la gran + parte delle architetture anche ai dati che possono essere passati come + argomenti e variabili di ambiente ad un programma posto in esecuzione con + \func{execve}, nella misura di un quarto del valore indicato per lo + \textit{stack}. Questo valore in precedenza era fisso e pari a 32 pagine di + memoria, corrispondenti per la gran parte delle architetture a 128kb di + dati, dal 2.6.25, per evitare problemi di compatibilità quando + \const{RLIMIT\_STACK} è molto basso, viene comunque garantito uno spazio + base di 32 pagine qualunque sia l'architettura. + +\end{basedescript} + +Si tenga conto infine che tutti i limiti eventualmente presenti su un processo +vengono ereditati dai figli da esso creati attraverso una \func{fork} (vedi +sez.~\ref{sec:proc_fork}) e mantenuti invariati per i programmi messi in +esecuzione attraverso una \func{exec} (vedi sez.~\ref{sec:proc_exec}). + +Si noti come le due funzioni \func{getrlimit} e \func{setrlimit} consentano di +operare solo sul processo corrente. Per questo motivo a partire dal kernel +2.6.36 (e dalla \acr{glibc} 2.13) è stata introdotta un'altra funzione di +sistema \funcd{prlimit} il cui scopo è quello di estendere e sostituire le +precedenti. Il suo prototipo è: + +\begin{funcproto}{ +\fhead{sys/resource.h} +\fdecl{int prlimit(pid\_t pid, int resource, const struct rlimit *new\_limit,\\ +\phantom{int prlimit(}struct rlimit *old\_limit} +\fdesc{Legge e imposta i limiti di una risorsa.} +} + +{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual + caso \var{errno} assumerà uno dei valori: + \begin{errlist} + \item[\errcode{EINVAL}] i valori per \param{resource} non sono validi o + nell'impostazione si è specificato \var{rlim->rlim\_cur} maggiore di + \var{rlim->rlim\_max}. + \item[\errcode{EPERM}] un processo senza i privilegi di amministratore ha + cercato di innalzare i propri limiti o si è cercato di modificare i limiti + di un processo di un altro utente. + \item [\errcode{ESRCH}] il process \param{pid} non esiste. + \end{errlist} + ed inoltre \errval{EFAULT} nel suo significato generico. +} +\end{funcproto} + +La funzione è specifica di Linux e non portabile; per essere usata richiede +che sia stata definita la macro \macro{\_GNU\_SOURCE}. Il primo argomento +indica il \ids{PID} del processo di cui si vogliono cambiare i limiti e si può +usare un valore nullo per indicare il processo chiamante. Per modificare i +limiti di un altro processo, a meno di non avere privilegi +amministrativi,\footnote{anche in questo caso la \itindex{capabilities} + \textit{capability} necessaria è \const{CAP\_SYS\_RESOURCE} (vedi + sez.~\ref{sec:proc_capabilities}).} l'\ids{UID} ed il \ids{GID} reale del +chiamante devono coincidere con \ids{UID} e \ids{GID} del processo indicato +per i tre gruppi reale, effettivo e salvato. + +Se \param{new\_limit} non è \val{NULL} verrà usato come puntatore alla +struttura \struct{rlimit} contenente i valori dei nuovi limiti da impostare, +mentre se \param{old\_limit} non è \val{NULL} verranno letti i valori correnti +del limiti nella struttura \struct{rlimit} da esso puntata. In questo modo è +possibile sia leggere che scrivere, anche in contemporanea, i valori dei +limiti. Il significato dell'argomento \param{resource} resta identico rispetto +a \func{getrlimit} e \func{setrlimit}, così come i restanti requisiti. -Nello specificare un limite, oltre a fornire dei valori specifici, si può -anche usare la costante \const{RLIM\_INFINITY} che permette di sbloccare l'uso -di una risorsa; ma si ricordi che solo un processo con i privilegi di -amministratore\footnote{per essere precisi in questo caso quello che serve è - la \itindex{capabilities} \textit{capability} \const{CAP\_SYS\_RESOURCE} - (vedi sez.~\ref{sec:proc_capabilities}).} può innalzare un limite al di -sopra del valore corrente del limite massimo ed usare un valore qualsiasi per -entrambi i limiti. Si tenga conto infine che tutti i limiti vengono ereditati -dal processo padre attraverso una \func{fork} (vedi sez.~\ref{sec:proc_fork}) -e mantenuti per gli altri programmi eseguiti attraverso una \func{exec} (vedi -sez.~\ref{sec:proc_exec}). \subsection{Le risorse di memoria e processore} @@ -1432,29 +1872,42 @@ sez.~\ref{sec:proc_exec}). La gestione della memoria è già stata affrontata in dettaglio in sez.~\ref{sec:proc_memory}; abbiamo visto allora che il kernel provvede il meccanismo della \index{memoria~virtuale} memoria virtuale attraverso la -divisione della memoria fisica in pagine. - -In genere tutto ciò è del tutto trasparente al singolo processo, ma in certi -casi, come per l'I/O mappato in memoria (vedi sez.~\ref{sec:file_memory_map}) -che usa lo stesso meccanismo per accedere ai file, è necessario conoscere le -dimensioni delle pagine usate dal kernel. Lo stesso vale quando si vuole -gestire in maniera ottimale l'interazione della memoria che si sta allocando -con il meccanismo della \index{paginazione} paginazione. - -Di solito la dimensione delle pagine di memoria è fissata dall'architettura -hardware, per cui il suo valore di norma veniva mantenuto in una costante che -bastava utilizzare in fase di compilazione, ma oggi, con la presenza di alcune -architetture (ad esempio Sun Sparc) che permettono di variare questa -dimensione, per non dover ricompilare i programmi per ogni possibile modello e -scelta di dimensioni, è necessario poter utilizzare una funzione. +divisione della memoria fisica in pagine. In genere tutto ciò è del tutto +trasparente al singolo processo, ma in certi casi, come per l'I/O mappato in +memoria (vedi sez.~\ref{sec:file_memory_map}) che usa lo stesso meccanismo per +accedere ai file, è necessario conoscere le dimensioni delle pagine usate dal +kernel. Lo stesso vale quando si vuole gestire in maniera ottimale +l'interazione della memoria che si sta allocando con il meccanismo della +\index{paginazione} paginazione. + +Un tempo la dimensione delle pagine di memoria era fissata una volta per tutte +dall'architettura hardware, per cui il relativo valore veniva mantenuto in una +costante che bastava utilizzare in fase di compilazione. Oggi invece molte +architetture permettono di variare questa dimensione (ad esempio sui PC +recenti si possono usare pagine di 4kb e di 4 Mb) per cui per non dover +ricompilare i programmi per ogni possibile caso e relativa scelta di +dimensioni, è necessario poter utilizzare una funzione. Dato che si tratta di una caratteristica generale del sistema, questa dimensione può essere ottenuta come tutte le altre attraverso una chiamata a -\func{sysconf}, \footnote{nel caso specifico si dovrebbe utilizzare il - parametro \const{\_SC\_PAGESIZE}.} ma in BSD 4.2 è stata introdotta una -apposita funzione, \funcd{getpagesize}, che restituisce la dimensione delle -pagine di memoria; il suo prototipo è: -\begin{prototype}{unistd.h}{int getpagesize(void)} +\func{sysconf} (nel caso specifico si dovrebbe utilizzare il parametro +\const{\_SC\_PAGESIZE}) ma in BSD 4.2 è stata introdotta una apposita funzione +di sistema \funcd{getpagesize} che restituisce la dimensione delle pagine di +memoria. La funzione è disponibile anche su Linux ed il suo prototipo è: + +\begin{funcproto}{ +\fhead{unistd.h} +\fdecl{int getpagesize(void)} +\fdesc{Legge la dimensione delle pagine di memoria.} +} + +{La funzione ritorna la dimensione di una pagina in byte, e non sono previsti + errori.} +\end{funcproto} + + +\begin{prototype}{unistd.h} +{int getpagesize(void)} Legge le dimensioni delle pagine di memoria. \bodydesc{La funzione ritorna la dimensione di una pagina in byte, e non @@ -1463,11 +1916,11 @@ pagine di memoria; il suo prototipo è: La funzione è prevista in SVr4, BSD 4.4 e SUSv2, anche se questo ultimo standard la etichetta come obsoleta, mentre lo standard POSIX 1003.1-2001 la -ha eliminata. In Linux è implementata come una system call nelle architetture -in cui essa è necessaria, ed in genere restituisce il valore del simbolo -\const{PAGE\_SIZE} del kernel, che dipende dalla architettura hardware, anche -se le versioni delle librerie del C precedenti le \acr{glibc} 2.1 -implementavano questa funzione restituendo sempre un valore statico. +ha eliminata. In Linux è implementata come una \textit{system call} nelle +architetture in cui essa è necessaria, ed in genere restituisce il valore del +simbolo \const{PAGE\_SIZE} del kernel, che dipende dalla architettura +hardware, anche se le versioni delle librerie del C precedenti le \acr{glibc} +2.1 implementavano questa funzione restituendo sempre un valore statico. % TODO verificare meglio la faccenda di const{PAGE\_SIZE} @@ -1651,9 +2104,9 @@ processo il kernel calcola tre tempi diversi: sez.~\ref{sec:sys_resource_use}. \item[\textit{system time}] il tempo effettivo che il processore ha impiegato - per eseguire codice delle system call nel kernel per conto del processo. È - quello riportato nella risorsa \var{ru\_stime} di \struct{rusage} vista in - sez.~\ref{sec:sys_resource_use}. + per eseguire codice delle \textit{system call} nel kernel per conto del + processo. È quello riportato nella risorsa \var{ru\_stime} di + \struct{rusage} vista in sez.~\ref{sec:sys_resource_use}. \end{basedescript} In genere la somma di \textit{user time} e \textit{system time} indica il @@ -1822,7 +2275,7 @@ Come nel caso di \func{stime} anche \func{settimeofday} (la cosa continua a valere per qualunque funzione che vada a modificare l'orologio di sistema, quindi anche per quelle che tratteremo in seguito) può essere utilizzata solo da un processo coi privilegi di amministratore.\footnote{più precisamente la - capabitity \const{CAP\_SYS\_TIME}.} + capability \const{CAP\_SYS\_TIME}.} Il secondo argomento di entrambe le funzioni è una struttura \struct{timezone}, che storicamente veniva utilizzata per specificare appunto @@ -2451,7 +2904,7 @@ linea non vengano ripetuti. % LocalWords: SHRT short USHRT int UINT LONG long ULONG LLONG ULLONG POSIX ARG % LocalWords: Stevens exec CHILD STREAM stream TZNAME timezone NGROUPS SSIZE % LocalWords: ssize LISTIO JOB CONTROL job control IDS VERSION YYYYMML bits bc -% LocalWords: dall'header posix lim nell'header glibc run unistd name errno +% LocalWords: dall'header posix lim nell'header glibc run unistd name errno SC % LocalWords: NGROUP CLK TCK clock tick process PATH pathname BUF CANON path % LocalWords: pathconf fpathconf descriptor fd uname sys struct utsname info % LocalWords: EFAULT fig SOURCE NUL LENGTH DOMAIN NMLN UTSLEN system call proc @@ -2459,7 +2912,7 @@ linea non vengano ripetuti. % LocalWords: newlen ENOTDIR EINVAL ENOMEM linux array oldvalue paging stack % LocalWords: TCP shell Documentation ostype hostname osrelease version mount % LocalWords: const source filesystemtype mountflags ENODEV ENOTBLK block read -% LocalWords: device EBUSY only EACCES NODEV ENXIO major +% LocalWords: device EBUSY only EACCES NODEV ENXIO major RTSIG syscall PID NSS % LocalWords: number EMFILE dummy ENAMETOOLONG ENOENT ELOOP virtual devfs MGC % LocalWords: magic MSK RDONLY NOSUID suid sgid NOEXEC SYNCHRONOUS REMOUNT MNT % LocalWords: MANDLOCK mandatory locking WRITE APPEND append IMMUTABLE NOATIME @@ -2478,26 +2931,32 @@ linea non vengano ripetuti. % LocalWords: SIGSEGV SIGXCPU SIGKILL sbrk FSIZE SIGXFSZ EFBIG LOCKS lock dup % LocalWords: MEMLOCK NOFILE NPROC fork EAGAIN SIGPENDING sigqueue kill RSS tv % LocalWords: resource getrlimit setrlimit rlimit rlim INFINITY capabilities -% LocalWords: capability CAP l'I Sun Sparc PAGESIZE getpagesize SVr SUSv get +% LocalWords: capability CAP Sun Sparc PAGESIZE getpagesize SVr SUSv get IGN % LocalWords: phys pages avphys NPROCESSORS CONF ONLN getloadavg stdlib double -% LocalWords: loadavg nelem scheduler CONFIG ACCT acct filename EUSER +% LocalWords: loadavg nelem scheduler CONFIG ACCT acct filename EUSER sizeof % LocalWords: ENFILE EROFS PACCT AcctCtrl cap calendar UTC Jan the Epoch GMT % LocalWords: Greenwich Mean l'UTC timer CLOCKS SEC cron wall elapsed times tz -% LocalWords: tms cutime cstime waitpid gettimeofday settimeofday timex -% LocalWords: timespec adjtime olddelta adjtimex David Mills RFC NTP ntp +% LocalWords: tms cutime cstime waitpid gettimeofday settimeofday timex NetBSD +% LocalWords: timespec adjtime olddelta adjtimex David Mills RFC NTP ntp cmd % LocalWords: nell'RFC ADJ FREQUENCY frequency MAXERROR maxerror ESTERROR PLL % LocalWords: esterror TIMECONST constant SINGLESHOT MOD INS insert leap OOP % LocalWords: second delete progress has occurred BAD broken tm gmtoff asctime % LocalWords: ctime timep gmtime localtime mktime tzname tzset daylight format % LocalWords: strftime thread EOF modifiable lvalue app errcode strerror LC at -% LocalWords: perror string errnum MESSAGES error message ErrCode strtol log +% LocalWords: perror string errnum MESSAGES error message strtol log % LocalWords: program invocation argv printf print progname exit count fname -% LocalWords: lineno one standardese Di page Wed Wednesday Apr April PM AM - +% LocalWords: lineno one standardese Di page Wed Wednesday Apr April PM AM CAD +% LocalWords: CEST utmpxname Solaris updwtmpx reboot RESTART Ctrl OFF SIGINT +% LocalWords: HALT halted sync KEXEC kexec load bootloader POWER Power with nr +% LocalWords: Restarting command arg entry segments segment ARCH CRASH CONTEXT +% LocalWords: PRESERVE PPC IA ARM SH MIPS nvcsw nivcsw inblock oublock maxrss +% LocalWords: context switch slice Resident SIG SIGCHLD cur Gb lease mlock +% LocalWords: memory mlockall MAP LOCKED shmctl MSGQUEUE attr NICE nice MADV +% LocalWords: madvise WILLNEED RTPRIO sched setscheduler setparam scheduling +% LocalWords: RTTIME execve kb prlimit pid new old ESRCH EUSERS %%% Local Variables: %%% mode: latex %%% TeX-master: "gapil" %%% End: -% LocalWords: CEST