+{La funzione ritorna il precedente valore della maschera dei messaggi e non
+ prevede errori.}
+\end{funcproto}
+
+La funzione restituisce il valore della maschera corrente, e se si passa un
+valore nullo per \param{mask} la maschera corrente non viene modificata; in
+questo modo si può leggere il valore della maschera corrente. Indicando un
+valore non nullo per \param{mask} la registrazione dei messaggi viene
+disabilitata per tutte quelle priorità che non rientrano nella maschera.
+
+In genere il valore viene impostato usando la macro
+\macrod{LOG\_MASK}\texttt{(p)} dove \code{p} è una delle costanti di
+tab.~\ref{tab:sess_syslog_priority}. É inoltre disponibile anche la macro
+\macrod{LOG\_UPTO}\texttt{(p)} che permette di specificare automaticamente
+tutte le priorità fino a quella indicata da \code{p}.
+
+Una volta che si sia certi che non si intende registrare più nessun messaggio
+si può chiudere esplicitamente la connessione al \textit{syslog} (l'uso di
+questa funzione è comunque completamente opzionale) con la funzione
+\funcd{closelog}, il cui prototipo è:
+
+\begin{funcproto}{
+\fhead{syslog.h}
+\fdecl{void closelog(void)}
+\fdesc{Chiude la connessione al \textit{syslog}.}
+}
+
+{La funzione non ritorna nulla.}
+\end{funcproto}
+
+
+Come si evince anche dalla presenza della facility \const{LOG\_KERN} in
+tab.~\ref{tab:sess_syslog_facility}, uno dei possibili utenti del servizio del
+\textit{syslog} è anche il kernel, che a sua volta può avere necessità di
+inviare messaggi verso l'\textit{user space}. I messaggi del kernel sono
+mantenuti in un apposito buffer circolare e generati all'interno del kernel
+tramite la funzione \texttt{printk}, analoga alla \func{printf} usata in
+\textit{user space}.\footnote{una trattazione eccellente dell'argomento si
+ trova nel quarto capitolo di \cite{LinDevDri}.}
+
+Come per i messaggi ordinari anche i messaggi del kernel hanno una priorità ma
+in questo caso non si può contare sulla coincidenza con le costanti di
+tab.~\ref{tab:sess_syslog_priority} dato che il codice del kernel viene
+mantenuto in maniera indipendente dalle librerie del C. Per questo motivo le
+varie priorità usate dal kernel sono associate ad un valore numerico che viene
+tradotto in una stringa preposta ad ogni messaggio, secondo i valori che si
+sono riportati in fig.~\ref{fig:printk_priority}
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{0.80\textwidth}
+ \includestruct{listati/printk_prio.c}
+ \end{minipage}
+ \normalsize
+ \caption{Definizione delle stringhe coi relativi valori numerici che
+ indicano le priorità dei messaggi del kernel (ripresa da
+ \file{include/linux/kernel.h}).}
+ \label{fig:printk_priority}
+\end{figure}
+
+Dato che i messaggi generati da \texttt{printk} hanno un loro specifico
+formato tradizionalmente si usava un demone ausiliario, \cmd{klogd}, per
+leggerli, rimappare le loro priorità sui valori di
+tab.~\ref{tab:sess_syslog_priority} ed inviarli al sistema del \textit{syslog}
+nella facility \const{LOG\_KERN}. Oggi i nuovi demoni più avanzati che
+realizzano il servizio (come \texttt{rsyslog} o \texttt{syslog-ng}) sono in
+grado di fare tutto questo da soli leggendoli direttamente senza necessità di
+un intermediario.
+
+Ma i messaggi del kernel non sono necessariamente connessi al sistema del
+\textit{syslog}; ad esempio possono anche essere letti direttamente dal buffer
+circolare con il comando \texttt{dmesg}. Inoltre è previsto che se superano
+una certa priorità essi vengano stampati direttamente sul terminale indicato
+come \textit{console} di sistema,\footnote{quello che viene indicato con il
+ parametro di avvio \texttt{console} del kernel, si consulti al riguardo
+ sez.~5.3.1 di \cite{AGL}.} in modo che sia possibile vederli anche in caso
+di blocco totale del sistema (nell'assunzione che la console sia collegata).
+
+In particolare la stampa dei messaggi sulla console è controllata dal
+contenuto del file \sysctlfiled{kernel/printk} (o con l'equivalente parametro
+di \func{sysctl}) che prevede quattro valori numerici interi: il primo,
+\textit{console\_loglevel}, indica la priorità corrente oltre la quale vengono
+stampati i messaggi sulla console, il secondo,
+\textit{default\_message\_loglevel}, la priorità di default assegnata ai
+messaggi che non ne hanno impostata una, il terzo,
+\textit{minimum\_console\_level}, il valore minimo che si può assegnare al
+primo valore,\footnote{che può essere usato con una delle operazioni di
+ gestione che vedremo a breve per ``\textsl{silenziare}'' il kernel.} ed il
+quarto, \textit{default\_console\_loglevel}, il valore di
+default.\footnote{anch'esso viene usato nelle operazioni di controllo per
+ tornare ad un valore predefinito.}
+
+Per la lettura dei messaggi del kernel e la gestione del relativo buffer
+circolare esiste una apposita \textit{system call} chiamata anch'essa
+ \texttt{syslog}, ma dato il conflitto di nomi questa viene rimappata su
+ un'altra funzione di libreria, in particolare nella \acr{glibc} essa viene
+ invocata tramite la funzione \funcd{klogctl},\footnote{nella \acr{libc4} e
+ nella \acr{libc5} la funzione invece era \code{SYS\_klog}.} il cui prototipo
+ è:
+
+\begin{funcproto}{
+\fhead{sys/klog.h}
+\fdecl{int klogctl(int op, char *buffer, int len)}
+\fdesc{Gestisce i messaggi di log del kernel.}
+}
+
+{La funzione ritorna un intero positivo o nullo dipendente dall'operazione
+ scelta 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{op} non ha un valore valido, o si
+ sono specificati valori non validi per gli altri argomenti quando questi
+ sono richiesti.
+ \item[\errcode{ENOSYS}] il supporto per \texttt{printk} non è stato compilato
+ nel kernel.
+ \item[\errcode{EPERM}] non si hanno i privilegi richiesti per l'operazione
+ richiesta.
+ \item[\errcode{ERESTARTSYS}] l'operazione è stata interrotta da un segnale.
+ \end{errlist}
+}
+\end{funcproto}
+
+La funzione prevede che si passi come primo argomento \param{op} un codice
+numerico che indica l'operazione richiesta, il secondo argomento deve essere,
+per le operazioni che compiono una lettura di dati, l'indirizzo del buffer su
+cui copiarli, ed il terzo quanti byte leggere. L'effettivo uso di questi due
+argomenti dipende comunque dall'operazione richiesta, ma essi devono essere
+comunque specificati, anche quando non servono, nel qual caso verranno
+semplicemente ignorati.
+
+\begin{table}[htb]
+ \footnotesize
+ \centering
+ \begin{tabular}[c]{|l|p{10cm}|}
+ \hline
+ \textbf{Valore}& \textbf{Significato}\\
+ \hline
+ \hline
+ \texttt{0} & apre il log (attualmente non fa niente), \param{buffer}
+ e \param{len} sono ignorati.\\
+ \texttt{1} & chiude il log (attualmente non fa niente), \param{buffer}
+ e \param{len} sono ignorati.\\
+ \texttt{2} & legge \param{len} byte nel buffer \param{buffer} dal log dei
+ messaggi.\\
+ \texttt{3} & legge \param{len} byte nel buffer \param{buffer} dal buffer
+ circolare dei messaggi.\\
+ \texttt{4} & legge \param{len} byte nel buffer \param{buffer} dal buffer
+ circolare dei messaggi e lo svuota.\\
+ \texttt{5} & svuota il buffer circolare dei messaggi, \param{buffer}
+ e \param{len} sono ignorati.\\
+ \texttt{6} & disabilita la stampa dei messaggi sulla console, \param{buffer}
+ e \param{len} sono ignorati.\\
+ \texttt{7} & abilita la stampa dei messaggi sulla console, \param{buffer}
+ e \param{len} sono ignorati.\\
+ \texttt{8} & imposta a \param{len} il livello dei messaggi stampati sulla
+ console, \param{buffer} è ignorato.\\
+ \texttt{9} & ritorna il numero di byte da leggere presenti sul buffer di
+ log, \param{buffer} e \param{len} sono ignorati (dal kernel
+ 2.4.10).\\
+ \texttt{10}& ritorna la dimensione del buffer di log, \param{buffer}
+ e \param{len} sono ignorati (dal kernel 2.6.6).\\
+\hline
+\end{tabular}
+\caption{Valori possibili per l'argomento \param{op} di \func{klogctl}.}
+\label{tab:klogctl_operation}
+\end{table}
+
+Si sono riportati in tab.~\ref{tab:klogctl_operation} i valori utilizzabili
+per \param{op}, con una breve spiegazione della relativa operazione e di come
+vengono usati gli altri due argomenti. Come si può notare la funzione è una
+sorta di interfaccia comune usata per eseguire operazioni completamente
+diverse fra loro.
+
+L'operazione corrispondente al valore 2 di \param{op} consente di leggere un
+messaggio dal cosiddetto \textit{log} del kernel. Eseguire questa operazione è
+equivalente ad eseguire una lettura dal file
+\procfile{/proc/kmsg},\footnote{in realtà è vero l'opposto, è questa funzione
+ che viene eseguita quando si legge da questo file.} se non vi sono messaggi
+la funzione si blocca in attesa di dati e ritorna soltanto quando questi
+diventano disponibili. In tal caso verranno letti ed
+estratti\footnote{estratti in quanti i dati del \textit{log} del kernel si
+ possono leggere una volta sola, se più processi eseguono l'operazione di
+ lettura soltanto uno riceverà i dati, a meno che completata la propria
+ operazione di lettura non restino altri messaggi pendenti che a questo punto
+ potrebbero essere letti da un altro processo in attesa.} dal log \param{len}
+byte che verranno scritti su \param{buffer}; in questo caso il valore di
+ritorno di \func{klogctl} corrisponderà al numero di byte ottenuti.
+
+Se invece si usa l'operazione 3 i dati vengono letti dal buffer circolare
+usato da \texttt{printk}, che mantiene tutti i messaggi stampati dal kernel
+fino al limite delle sue dimensioni, in questo caso i messaggi possono essere
+letti più volte. Usando invece l'operazione 4 si richiede di cancellare il
+buffer dopo la lettura, che così risulterà vuoto ad una lettura
+successiva. Anche con queste operazioni \param{len} indica il numero di byte
+da leggere e \param{buffer} l'indirizzo dove leggerli, e la funzione ritorna
+il numero di byte effettivamente letti. L'operazione 5 esegue soltanto la
+cancellazione del buffer circolare, \param{len} e \param{buffer} sono ignorati
+e la funzione ritorna un valore nullo.
+
+Le operazioni corrispondenti ai valori 6, 7 ed 8 consentono di modificare la
+priorità oltre la quale i messaggi vengono stampati direttamente sulla
+\textit{console} e fanno riferimento ai parametri del kernel gestiti con le
+variabili contenute in \sysctlfile{kernel/printk} di cui abbiamo
+parlato prima, ed in particolare con 6 si imposta come corrente il valore
+minimo della terza variabile (\textit{minimum\_console\_level}), ottenendo
+l'effetto di ridurre al minimo i messaggi che arrivano in console, mentre con
+7 si ripristina il valore di default.\footnote{secondo la documentazione
+ questo sarebbe quello indicato della quarta variabile,
+ \textit{default\_console\_loglevel} in genere pari a 7, ma alcune prove con
+ il programma \texttt{mydmesg} che si trova nei sorgenti allegati alla guida
+ rivelano che l'unico effetto di questa operazione è riportare il valore a
+ quello precedente se lo si è ridotto al minimo con l'operazione 6.} Per
+impostare direttamente un valore specifico infine si può usare 8, nel qual
+caso il valore numerico del livello da impostare deve essere specificato
+con \param{len}, che può assumere solo un valore fra 1 e 8.
+
+Infine le due operazioni 9 e 10 consentono di ottenere rispettivamente il
+numero di byte ancora non letti dal log del kernel, e la dimensione totale di
+questo. Per entrambe i dati sono restituiti come valore di ritorno, e gli
+argomento \param{buffer} e \param{len} sono ignorati.
+
+Si tenga presente che la modifica del livello minimo per cui i messaggi
+vengono stampati sulla console (operazioni 6, 7 e 8) e la cancellazione del
+buffer circolare di \texttt{printk} (operazioni 4 e 5) sono privilegiate; fino
+al kernel 2.6.30 era richiesta la capacità \const{CAP\_SYS\_ADMIN}, a partire
+dal 2.6.38 detto privilegio è stato assegnato ad una capacità aggiuntiva,
+\const{CAP\_SYSLOG}. Tutto questo è stato fatto per evitare che processi
+eseguiti all'interno di un sistema di virtualizzazione ``\textsl{leggera}''
+(come i \textit{Linux Container} di LXC) che necessitano di
+\const{CAP\_SYS\_ADMIN} per operare all'interno del proprio ambiente
+ristretto, potessero anche avere la capacità di influire sui log del kernel
+al di fuori di questo.
+
+\itindend{syslog}