X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=session.tex;h=b2115ac173a167856399ca84616c0d6cc062f59e;hp=67e5129ad880b8598639bf6be5ac9be6a4a4fdfa;hb=a9751f84301783eca219219c5bb3691de9985933;hpb=d3cbe0a3984b7189d086ccb631d5b3b1955e223c diff --git a/session.tex b/session.tex index 67e5129..b2115ac 100644 --- a/session.tex +++ b/session.tex @@ -224,12 +224,12 @@ processo da una sessione ad un altra; infatti l'unico modo di far cambiare sessione ad un processo è quello di crearne una nuova con l'uso di \func{setsid}; il suo prototipo è: \begin{prototype}{unistd.h}{pid\_t setsid(void)} - Crea una nuova sessione sul processo corrente settandone \acr{sid} e + Crea una nuova sessione sul processo corrente impostandone \acr{sid} e \acr{pgid}. \bodydesc{La funzione ritorna il valore del nuovo \acr{sid}, e -1 in caso di errore, il solo errore possibile è \macro{EPERM}, che si ha quando il - \acr{pgid} e \acr{pid} del processo concidono.} + \acr{pgid} e \acr{pid} del processo coincidono.} \end{prototype} La funzione imposta il \acr{pgid} ed il \acr{sid} del processo corrente al @@ -299,7 +299,7 @@ sessione. In genere (a meno di redirezioni) nelle sessioni di lavoro questo terminale è associato ai file standard (di input, output ed error) dei processi nella -sessione, ma solo quelli che fanno parte del cosiddetto ragruppamento di +sessione, ma solo quelli che fanno parte del cosiddetto raggruppamento di \textit{foreground}, possono leggere e scrivere in certo istante. Per impostare il raggruppamento di \textit{foreground} di un terminale si usa la funzione \func{tcsetpgrp}, il cui prototipo è: @@ -340,7 +340,7 @@ condizioni di errore.\footnote{la shell in genere notifica comunque un \func{waitpid}.} Se però si bloccano o ignorano i due segnali citati, le funzioni di lettura e scrittura falliranno con un errore di \macro{EIO}. -Un processo può contollare qual'è il gruppo di \textit{foreground} associato +Un processo può controllare qual'è il gruppo di \textit{foreground} associato ad un terminale con la funzione \func{tcgetpgrp}, il cui prototipo è: \begin{functions} \headdecl{unistd.h} \headdecl{termios.h} @@ -367,7 +367,7 @@ proprio terminale di controllo. Questo consente anche a processi che possono aver rediretto l'output di accedere al terminale di controllo, pur non disponendo più del file descriptor originario; un caso tipico è il programma \cmd{crypt} che accetta la redirezione sullo standard input di un file da -decrittare, ma deve poi leggere la password dal terminale. +decifrare, ma deve poi leggere la password dal terminale. Un'altra caratteristica del terminale di controllo usata nel job control è che utilizzando su di esso le combinazioni di tasti speciali (\cmd{C-z}, @@ -455,7 +455,7 @@ ad una seriale o virtuale, come quelli associati a schermo e tastiera o ad una connessione di rete. Dato che i concetti base sono gli stessi, e dato che alla fine le differenze sono\footnote{in generale nel caso di login via rete o di terminali lanciati dall'interfaccia grafica cambia anche il processo da cui - ha origine l'esecuzione della shell.} nel device cui il kernel associa i + ha origine l'esecuzione della shell.} nel dispositivo cui il kernel associa i file standard (vedi \secref{sec:file_std_descr}) per l'I/O, tratteremo solo il caso classico del terminale. @@ -494,7 +494,7 @@ dispositivo. Storicamente i primi terminali erano appunto terminali di telescriventi (\textit{teletype}), da cui deriva sia il nome dell'interfaccia, \textit{tty}, che quello dei relativi file di dispositivo, che sono sempre della forma \texttt{/dev/tty*}.\footnote{questo vale anche per i terminali - vitruali associati alle connessioni di rete con \cmd{telnet} o \cmd{ssh}.} + virtuali associati alle connessioni di rete con \cmd{telnet} o \cmd{ssh}.} Per controllare un terminale si usa di solito il programma \cmd{getty} (od una delle sue varianti), che permette di mettersi in ascolto su uno di questi @@ -511,7 +511,7 @@ amministratore e con un ambiente vuoto; \cmd{getty} si cura di chiamare \func{setsid} per creare una nuova sessione ed un nuovo process group, e di aprire il terminale (che così diventa il terminale di controllo della sessione) in lettura sullo standard input ed in scrittura sullo standard -output e sullo standard error; inoltre effettuarà, qualora servano, ulteriori +output e sullo standard error; inoltre effettuerà, qualora servano, ulteriori settaggi.\footnote{ad esempio, come qualcuno si sarà accorto scrivendo un nome di login in maiuscolo, può effettuare la conversione automatica dell'input in minuscolo, ponendosi in una modalità speciale che non distingue fra i due @@ -554,12 +554,14 @@ A questo punto \cmd{login} provveder iniziali, come la stampa di messaggi di benvenuto o il controllo della posta) ad eseguire con un'altra \func{exec} la shell, che si troverà con un ambiente già pronto con i file standard di \secref{sec:file_std_descr} impostati sul -terminale, e pronta, nel ruolo di leader di sessione e processo di controllo -per il terminale, a gestire l'esecuzione dei comandi come illustrato in -\secref{sec:sess_job_control_overview}. Dato che il processo padre resta -sempre \cmd{init} quest'ultimo potrà provvedere, ricevendo un \macro{SIGCHLD} -all'uscita della shell, a rilanciare \cmd{getty} sul terminale per ripetere da -capo tutto il procedimento. +terminale, e pronta, nel ruolo di leader di sessione e di processo di +controllo per il terminale, a gestire l'esecuzione dei comandi come illustrato +in \secref{sec:sess_job_control_overview}. + +Dato che il processo padre resta sempre \cmd{init} quest'ultimo potrà +provvedere, ricevendo un \macro{SIGCHLD} all'uscita della shell quando la +sessione di lavoro è terminata, a rilanciare \cmd{getty} sul terminale per +ripetere da capo tutto il procedimento. @@ -568,17 +570,275 @@ capo tutto il procedimento. Come sottolineato fin da \secref{sec:intro_base_concept}, in un sistema unix-like tutte le operazioni sono eseguite tramite processi, comprese quelle -operazioni di sistema (come l'esecuzione di comandi periodici, o la consegna -della posta, ed in generale tutti i programmi di servizio) che non hanno a che -fare con la gestione diretta dei comandi dell'utente. +operazioni di sistema (come l'esecuzione dei comandi periodici, o la consegna +della posta, ed in generale tutti i programmi di servizio) che non hanno +niente a che fare con la gestione diretta dei comandi dell'utente. + +Questi programmi, che devono essere eseguiti in modalità non interattiva e +senza nessun intervento dell'utente, sono normalmente chiamati +\textsl{demoni}, (o \textit{daemons}), nome ispirato dagli omonimi spiritelli +che svolgevano compiti vari, di cui parlava Socrate (che sosteneva di averne +uno al suo servizio).\footnote{NdT. ricontrollare, i miei ricordi di filosofia + sono piuttosto datati.} + +Se però si lancia un programma demone dalla riga di comando in un sistema che +supporta, come Linux, il \textit{job control} esso verrà comunque associato ad +un terminale di controllo e mantenuto all'interno di una sessione, e anche se +può essere mandato in background e non eseguire più nessun I/O su terminale, +si avranno comunque tutte le conseguenze che abbiamo appena visto in +\secref{sec:sess_ctrl_term} (in particolare l'invio dei segnali in +corrispondenza dell'uscita del leader di sessione). + +Per questo motivo un programma che deve funzionare come demone deve sempre +prendere autonomamente i provvedimenti opportuni (come distaccarsi dal +terminale e dalla sessione) ad impedire eventuali interferenze da parte del +sistema del \textit{job contol}; questi sono riassunti in una lista di +prescrizioni\footnote{ad esempio sia Stevens in \cite{APUE}, che la + \textit{Unix Programming FAQ} \cite{UnixFAQ} ne riportano di sostanzialmente + identiche.} da seguire quando si scrive un demone. + +Pertanto, quando si lancia un programma che deve essere eseguito come demone +occorrerà predisporlo in modo che esso compia le seguenti azioni: +\begin{enumerate} +\item Eseguire una \func{fork} e terminare immediatamente il processo padre + proseguendo l'esecuzione nel figlio. In questo modo si ha la certezza che + il figlio non è un \textit{process group leader}, (avrà il \acr{pgid} del + padre, ma un \acr{pid} diverso) e si può chiamare \func{setsid} con + successo. Inoltre la shell considererà terminato il comando all'uscita del + padre. +\item Eseguire \func{setsid} per creare una nuova sessione ed un nuovo + raggruppamento di cui il processo diventa automaticamente il leader, che + però non ha associato nessun terminale di controllo. +\item Assicurarsi che al processo non venga associato in seguito nessun nuovo + terminale di controllo; questo può essere fatto sia avendo cura di usare + sempre l'opzione \macro{O\_NOCTTY} nell'aprire i file di terminale, che + eseguendo una ulteriore \func{fork} uscendo nel padre e proseguendo nel + figlio. In questo caso, non essendo più quest'ultimo un leader di sessione + non potrà ottenere automaticamente un terminale di controllo. +\item Eseguire una \func{chdir} per impostare la directory di lavoro del + processo (su \file{/} o su una directory che contenga dei file necessari per + il programma), per evitare che la directory da cui si è lanciato il processo + resti in uso e non sia possibile rimuoverla o smontare il filesystem che la + contiene. +\item Impostare la maschera dei permessi (di solito con \code{umask(0)}) in + modo da non essere dipendenti dal valore ereditato da chi ha lanciato + originariamente il processo. +\item Chiudere tutti i file aperti che non servono più (in generale tutti); in + particolare vanno chiusi i file standard che di norma sono ancora associati + al terminale (un'altra opzione è quella di redirigerli verso + \file{/dev/null}). +\end{enumerate} + + +In Linux buona parte di queste azioni possono venire eseguite invocando la +funzione \func{daemon}, introdotta per la prima volta in BSD4.4; il suo +prototipo è: +\begin{prototype}{unistd.h}{int daemon(int nochdir, int noclose)} + Esegue le operazioni che distaccano il processo dal terminale di controllo e + lo fanno girare come demone. + + \bodydesc{La funzione restituisce (nel nuovo processo) 0 in caso di + successo, e -1 in caso di errore, nel qual caso \var{errno} assumerà i + valori impostati dalle sottostanti \func{fork} e \func{setsid}.} +\end{prototype} + +La funzione esegue una \func{fork}, per uscire subito, con \func{\_exit}, nel +padre, mentre l'esecuzione prosegue nel figlio che esegue subito una +\func{setsid}. In questo modo si compiono automaticamente i passi 1 e 2 della +precedente lista. Se \param{nochdir} è nullo la funzione imposta anche la +directory di lavoro su \file{/}, se \param{noclose} è nullo i file standard +vengono rediretti su \file{/dev/null} (corrispondenti ai passi 4 e 6); in caso +di valori non nulli non viene eseguita nessuna altra azione. + +Dato che un programma demone non può più accedere al terminale, si pone il +problema di come fare per la notifica di eventuali errori, non potendosi più +utilizzare lo standard error; per il normale I/O infatti ciascun demone avrà +le sue modalità di interazione col sistema e gli utenti a seconda dei compiti +e delle funzionalità che sono sono previste; ma gli errori devono normalmente +essere notificati all'amministratore del sistema. + +Una soluzione può essere quella di scrivere gli eventuali messaggi su uno +specifico file (cosa che a volte viene fatta comunque) ma questo comporta il +grande svantaggio che l'amministratore dovrà tenere sotto controllo un file +diverso per ciascun demone, e che possono anche generarsi conflitti di nomi. +Per questo in BSD4.2 venne introdotto un servizio di sistema, il +\textit{syslog}, che oggi si trova su tutti i sistemi Unix, e che permettesse +ai demoni di inviare messaggi all'amministratore in una maniera +standardizzata. + +Il servizio prevede vari meccanismi di notifica, e, come ogni altro servizio +in un sistema unix-like, viene gestito attraverso un apposito programma, +\cmd{syslogd}, che è anch'esso un \textsl{demone}. In generale i messaggi di +errore vengono raccolti dal file speciale \file{/dev/log}, un \textit{socket} +locale (vedi \secref{sec:sock_sa_local}) dedicato a questo scopo, o via rete, +con un \textit{socket} UDP, o da un apposito demone, \cmd{klogd}, che estrae i +messaggi del kernel.\footnote{i messaggi del kernel sono tenuti in un buffer + circolare e scritti tramite la funzione \func{printk}, analoga alla + \func{printf} usata in user space; una trattazione eccellente dell'argomento + si trova in \cite{LinDevDri}, nel quarto capitolo.} + +Il servizio permette poi di trattare i vari messaggi classificandoli +attraverso due indici; il primo, chiamato \textit{facility}, indica quale +categoria di demone ha emesso il messaggio, ed è organizzato in sottosistemi +(kernel, posta elettronica, demoni di stampa, ecc.), il secondo, chiamato +\textit{priority}, identifica l'importanza del messaggio. Il sistema di +\textit{syslog} provvede poi a riportare i messaggi all'amministratore +attraverso differenti meccanismi come: +\begin{itemize*} +\item scrivere sulla console. +\item inviare via mail ad uno specifico utente. +\item scrivere su un file (comunemente detto \textit{log file}). +\item inviare ad un altro demone (anche via rete). +\item scartare. +\end{itemize*} +secondo le modalità che questo preferisce e che possono essere impostate +attraverso il file di configurazione \file{/etc/syslog.conf} (maggiori +dettagli si possono trovare sulle pagine di manuale per questo file e per +\cmd{syslogd}). + +Le \acr{glibc} definiscono una serie di funzioni standard con cui un processo +può accedere in maniera generica al servizio di syslog, che però funzionano +solo localmente; se si vogliono inviare i messaggi ad un'altro sistema occorre +farlo esplicitamente con un socket UDP, o utilizzare le capacità di reinvio +del servizio. + +La prima funzione definita dall'interfaccia è \func{openlog}, che apre una +connessione al servizio di \textit{syslog}; essa in generale non è necessaria +per l'uso del servizio, ma permette di impostare alcuni valori che controllano +gli effetti delle chiamate successive; il suo prototipo è: +\begin{prototype}{syslog.h}{void openlog(const char *ident, int option, +int facility)} + +Apre una connessione al sistema di \textit{syslog}. + +\bodydesc{La funzione non restituisce nulla.} +\end{prototype} -Questi programmi, che devono essere eseguiti in modalità non interattiva senza -nessun intervento dell'utente, sono normalmente chiamati \textsl{demoni}, (o -\textit{daemons}), nome ispirato dagli omonimi spiritelli che svolgevano vari -compiti, di cui parlava Socrate (che sosteneva di averne uno al suo -servizio).\footnote{NdT. ricontrollare, i miei ricordi di filosofia sono - piuttosto datati.} +La funzione permette di specificare, tramite \param{ident}, l'identità di chi +ha inviato il messaggio (di norma si passa il nome del programma, come +specificato da \code{argv[0]}); la stringa verrà preposta all'inizio di ogni +messaggio. Si tenga presente che il valore di \param{ident} che si passa alla +funzione è un puntatore, se la stringa cui punta viene cambiata lo sarà pure +nei successivi messaggi, e se viene cancellata i risultati potranno essere +impredicibili, per questo è sempre opportuno usare una stringa costante. Il +parametro \param{facility} permette invece di specificare l'omonimo indice per +la categoria del messaggio; i valori possibili sono riportati in +\tabref{tab:sess_syslog_facility}. + +\begin{table}[htb] +\centering +\begin{tabular}[c]{|l|p{8cm}|} +\hline +\textbf{Valore}& \textbf{Significato}\\ +\hline +\hline +\macro{LOG\_AUTH} & Messaggi relativi ad autenticazione e sicurezza, + obsoleto, è sostituito da \macro{LOG\_AUTHPRIV}. \\ +\macro{LOG\_AUTHPRIV} & Sostituisce \macro{LOG\_AUTH}.\\ +\macro{LOG\_CRON} & Messaggi dei demoni di gestione dei comandi + programmati (\cmd{cron} e \cmd{at}).\\ +\macro{LOG\_DAEMON} & Demoni di sistema.\\ +\macro{LOG\_FTP} & Server FTP.\\ +\macro{LOG\_KERN} & Messaggi del kernel\\ +\macro{LOG\_LOCAL0} & Riservato all'amministratore per uso locale\\ +--- & \\ +\macro{LOG\_LOCAL7} & Riservato all'amministratore per uso locale\\ +\macro{LOG\_LPR} & Messaggi del sistema di gestione delle stampanti \\ +\macro{LOG\_MAIL} & Messaggi del sistema di posta elettronica\\ +\macro{LOG\_NEWS} & Messaggi del sistema di gestione delle news (USENET) \\ +\macro{LOG\_SYSLOG} & Messaggi generati dallo stesso \cmd{syslogd}\\ +\macro{LOG\_USER} & Messaggi generici a livello utente\\ +\macro{LOG\_UUCP} & Messaggi del sistema UUCP\\ +\hline +\end{tabular} +\caption{Valori possibili per l'argomento \param{facility} di \func{openlog}.} +\label{tab:sess_syslog_facility} +\end{table} + +L'argomento \param{option} serve invece per controllare il comportamento della +funzione \func{openlog} e delle modalità con cui le successive chiamate +scriveranno i messaggi, esso viene specificato come maschera binaria composta +con un OR aritmetico di una qualunque delle costanti riportate in +\tabref{tab:sess_openlog_option}. + +\begin{table}[htb] +\centering +\begin{tabular}[c]{|l|p{8cm}|} +\hline +\textbf{Valore}& \textbf{Significato}\\ +\hline +\hline +\macro{LOG\_CONS} & Scrive sulla console quando. \\ +\macro{LOG\_NDELAY} & Sostituisce \macro{LOG\_AUTH}.\\ +\macro{LOG\_NOWAIT} & Messaggi dei demoni di gestione dei comandi + programmati (\cmd{cron} e \cmd{at}).\\ +\macro{LOG\_ODELAY} & .\\ +\macro{LOG\_PERROR} & Stampa anche su \file{stderr}.\\ +\macro{LOG\_PID} & Inserisce nei messaggi il \acr{pid} del processo + chiamante. \\ +\hline +\end{tabular} +\caption{Valori possibili per l'argomento \param{option} di \func{openlog}.} +\label{tab:sess_openlog_option} +\end{table} + +La funzione che si usa per generare un messaggio è \func{syslog}, dato che +l'uso di \func{openlog} è ozionale, sarà quest'ultima a provvede a chiamare la +prima qualora ciò non sia stato fatto (nel qual caso il valore di +\param{ident} è nullo). Il suo prototipo è: +\begin{prototype}{syslog.h} +{void syslog(int priority, const char *format, ...)} + +Genera un messaggio di priorità \param{priority}. + +\bodydesc{La funzione non restituisce nulla.} +\end{prototype} +Il comportamento della funzione è analogo quello di \func{printf}, e il valore +dell'argomento \param{format} è identico a quello descritto nella pagina di +manuale di quest'ultima (per i valori principali si può vedere la trattazione +sommaria che se ne è fatto in \secref{sec:file_formatted_io}); l'unica +differenza è che la sequenza \cmd{\%m} viene rimpiazzata dalla stringa +restituita da \code{strerror(errno)}. Gli argomenti seguenti i primi due +devono essere forniti secondo quanto richiesto da \func{format}. + +L'argomento \param{priority} permette invece di impostare l'importanza del +messaggio; il valore deve essere impostato i valori possibili sono riportati +in \secref{tab:sess_syslog_priority}. + +\begin{table}[htb] +\centering +\begin{tabular}[c]{|l|p{8cm}|} +\hline +\textbf{Valore}& \textbf{Significato}\\ +\hline +\hline +\macro{LOG\_EMERG} & Il sistema è inutilizzabile. \\ +\macro{LOG\_ALERT} & C'è una emergenza che richiede intervento immediato.\\ +\macro{LOG\_CRIT} & Si è in una condizione critica.\\ +\macro{LOG\_ERR} & Si è in una condizione di errore.\\ +\macro{LOG\_WARNING} & Messaggio di avvertimento.\\ +\macro{LOG\_NOTICE} & Notizia significativa relativa al comportamento.\\ +\macro{LOG\_INFO} & Messaggio informativo. \\ +\macro{LOG\_DEBUG} & Messaggio di debug.\\ +\hline +\end{tabular} +\caption{Valori possibili per l'argomento \param{priority} di \func{syslog}.} +\label{tab:sess_syslog_priority} +\end{table} + +Dato che in molti programmi + +Il sistema del \textit{syslog} usa la priorità del messaggio per classificare +gli stessi, è inoltre possibile restringere l'emissione dei messaggi +attraverso l'uso della funzione \func{setlogmask}, il cui prototipo è: +\begin{prototype}{syslog.h} +{int setlogmask(int mask)} + +Imposta la maschera dei log al valore specificato. + +\bodydesc{La funzione restituisce il precedente valore.} +\end{prototype}