+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 \macro{LOG\_MASK(p)} dove
+\code{p} è una delle costanti di tab.~\ref{tab:sess_syslog_priority}. É
+inoltre disponibile anche la macro \macro{LOG\_UPTO(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} con la
+funzione \funcd{closelog}, il cui prototipo è:
+\begin{prototype}{syslog.h}{void closelog(void)}
+
+Chiude la connessione al \textit{syslog}.
+
+\bodydesc{La funzione non restituisce nulla.}
+\end{prototype}
+\noindent l'uso di questa funzione è comunque completamente opzionale.
+
+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 \func{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. 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]{15cm}
+ \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
+ \texttt{linux/kernel.h}).}
+ \label{fig:printk_priority}
+\end{figure}
+
+Dato che i messaggi generati da \func{printk} hanno un loro specifico formato
+tradizionalmente si usava un demone ausiliario, \cmd{klogd}, per leggerli,
+rimappare le priorità sui valori di tab.~\ref{tab:sess_syslog_priority} e
+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.
+
+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 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}.} se superano una certa priorità, 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 \procfile{/proc/sys/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{quello 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 nelle \acr{glibc} essa viene
+invocata tramite la funzione \funcd{klogctl},\footnote{nelle \acr{libc4} e
+ nelle \acr{libc5} la funzione invece era \func{SYS\_klog}.} il cui prototipo
+è:
+\begin{prototype}{sys/klog.h}{int klogctl(int op, char *buffer, int len)}
+
+Gestisce i messaggi di log del kernel.
+
+\bodydesc{La funzione restituisce in caso di successo un intero positivo o
+ nullo dipendente dall'operazione scelta e $-1$ in caso di errore, nel qual
+ caso \var{errno} assumerà i 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{ERESTARTSYS}] l'operazione è stata interrotta da un segnale.
+ \item[\errcode{EPERM}] non si hanno i privilegi richiesti per l'operazione
+ richiesta.
+ \item[\errcode{ENOSYS}] il supporto per \func{printk} non è stato compilato
+ nel kernel.
+ \end{errlist}
+ ed inoltre \errval{EBADF} ed \errval{ENOSYS}.
+}
+\end{prototype}
+
+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 leggerne. 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 possibili valori
+utilizzabili per \param{op}, con una breve spiegazione della relativa
+operazione e a 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 \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 blocca in attesa di dati e ritorna soltanto quando questi
+diventino 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}; 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, dopo aver fatto la
+lettura, di cancellare il buffer circolare, che risulterà vuoto ad una lettura
+successiva. Anche con queste operazioni \param{len} indica il numero di byte
+da leggere e \param{buffer} il buffer dover 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 \procfile{/proc/sys/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}