From: Simone Piccardi Date: Mon, 30 Sep 2002 22:20:56 +0000 (+0000) Subject: Aggiunta socketpair, ed iniziata la descrizione del syslog X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=commitdiff_plain;h=51e3c35a5012dba879b2cd3af28f08fddd6dc68c Aggiunta socketpair, ed iniziata la descrizione del syslog --- diff --git a/ipc.tex b/ipc.tex index 1116f2e..d0cf5ce 100644 --- a/ipc.tex +++ b/ipc.tex @@ -786,7 +786,6 @@ dal server siano sempre di dimensioni inferiori a \macro{PIPE\_BUF}, tralasciamo la gestione del caso in cui questo non è vero. Infine si stampa (\texttt{\small 32}) a video la risposta, si chiude (\texttt{\small 33}) la fifo e si cancella (\texttt{\small 34}) il relativo file. - Si noti come la fifo per la risposta sia stata aperta solo dopo aver inviato la richiesta, se non si fosse fatto così si avrebbe avuto uno stallo, in quanto senza la richiesta, il server non avrebbe potuto aprirne il capo in @@ -808,6 +807,57 @@ come quelli che esamineremo in seguito. +\subsection{La funzione \func{socketpair}} +\label{sec:ipc_socketpair} + +Un meccanismo di comunicazione molto simile alle pipe, ma che non presenta il +problema della unidirezionalità del flusso dei dati, è quello dei cosiddetti +\textit{socket} locali (o \textit{Unix domain socket}). Tratteremo l'argomento +dei socket in \capref{cha:socket_intro}, nell'ambito dell'interfaccia generale +che essi forniscono per la programmazione di rete; e vedremo +(in~\secref{sec:sock_sa_local}) come in tal caso si possono definire dei file +speciali (di tipo \textit{socket}, analoghi alle fifo) cui si accede però +attraverso quella interfaccia; vale però la pena esaminare qui una +modalità\footnote{la funzione \func{socketpair} è stata introdotta in BSD4.4, + ma è supportata in genere da qualunque sistema che fornisca l'interfaccia + dei socket.} di uso di questi socket che li rende sostanzialmente identici +ad una pipe bidirezionale. + +Attraverso la funzione \func{socketpair} infatti è possibile creare una coppia +di socket (che sono trattati com file descriptor) connessi fra di loro, senza +fare nessun riferimento ad un file speciale sul filesystem, in maniera analoga +a quello che si fa con \func{pipe}; la differenza è che in questo caso il +flusso dei dati è bidirezionale. Il prototipo della funzione è: +\begin{functions} + \headdecl{sys/types.h} + \headdecl{sys/socket.h} + + \funcdecl{int socketpair(int domain, int type, int protocol, int sv[2])} + + Crea una coppia di socket connessi fra loro. + + \bodydesc{La funzione restituisce 0 in caso di successo e -1 in caso di + errore, nel qual caso \var{errno} assumerà uno dei valori: + \begin{errlist} + \item[\macro{EAFNOSUPPORT}] I socket locali non sono supportati. + \item[\macro{EPROTONOSUPPORT}] Il protocollo specificato non è supportato. + \item[\macro{EOPNOTSUPP}] Il protocollo specificato non supporta la + creazione di coppie di socket. + \end{errlist} + ed inoltre \macro{EMFILE}, \macro{EFAULT}. +} +\end{functions} + +La funzione restituisce in \param{sv} una coppia di descrittori di socket +(come vedremo in \capref{cha:socket_intro} i file descriptor vengono usati +anche per i socket) connessi fra di loro, così che quello che si scrive da una +parte può essere riletto dall'altra e viceversa. I parametri \param{domain}, +\param{type} e \param{protocol} derivano dall'interfaccia dei socket, ma in +questo caso i soli valori validi sono rispettivamente \macro{AF\_UNIX}, +\macro{SOCK\_STREAM} e \macro{0}. + + + \section{La comunicazione fra processi di System V} \label{sec:ipc_sysv} @@ -1162,7 +1212,7 @@ una \funcdecl{int msgget(key\_t key, int flag)} - Restituisce l'identificatore di una cosa di messaggi. + Restituisce l'identificatore di una coda di messaggi. \bodydesc{La funzione restituisce l'identificatore (un intero positivo) o -1 in caso di errore, nel qual caso \var{errno} assumerà uno dei valori: diff --git a/network.tex b/network.tex index e59115e..db2cb4d 100644 --- a/network.tex +++ b/network.tex @@ -74,18 +74,18 @@ livelli, secondo quanto riportato in \tabref{tab:net_osilayers}. \begin{table}[htb] \centering - \begin{tabular}{|l|c|c|l|} + \begin{tabular}{|l|c|c|} \hline - \textbf{Livello} & \multicolumn{2}{|c|}{\textbf{Nome}} & \\ + \textbf{Livello} & \multicolumn{2}{|c|}{\textbf{Nome}} \\ \hline \hline - Livello 7&\textit{Application} &\textsl{Applicazione}& \\ - Livello 6&\textit{Presentation} &\textsl{Presentazione}& \\ - Livello 5&\textit{Session} &\textsl{Sessione}& \\ - Livello 4&\textit{Transport} &\textsl{Trasporto}& \\ - Livello 3&\textit{Network} &\textsl{Rete}& \\ - Livello 2&\textit{DataLink} &\textsl{Collegamento Dati}& \\ - Livello 1&\textit{Connection} &\textsl{Connessione Fisica}& \\ + Livello 7&\textit{Application} &\textsl{Applicazione}\\ + Livello 6&\textit{Presentation} &\textsl{Presentazione} \\ + Livello 5&\textit{Session} &\textsl{Sessione} \\ + Livello 4&\textit{Transport} &\textsl{Trasporto} \\ + Livello 3&\textit{Network} &\textsl{Rete}\\ + Livello 2&\textit{DataLink} &\textsl{Collegamento Dati} \\ + Livello 1&\textit{Connection} &\textsl{Connessione Fisica} \\ \hline \end{tabular} \caption{I sette livelli del protocollo ISO/OSI.} diff --git a/session.tex b/session.tex index ffc6946..2deb5d6 100644 --- a/session.tex +++ b/session.tex @@ -602,26 +602,31 @@ occorrer \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 processo non è un \textit{process group leader}, e si può chiamare - \func{setsid} con successo. + 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 è leader, che non ha associato nessun - terminale di controllo. + 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} proseguendo nel figlio, che a questo - punto non essendo più leader di sessione non può più ottenere un terminale - di controllo. -\item Eseguire una \func{chdir} per impostare la directory di lavoro (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 + 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 i file standard (o redirigerli verso \file{/dev/null}). +\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} @@ -637,14 +642,112 @@ prototipo 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 \func{setsid}. 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}; in caso di valori non nulli non viene eseguita nessuna altra -azione. - +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 secondo +due indici, una \textit{facility}, che indica quale categoria di demone ha +emesso il messaggio, e permette di classificarli per sottosistemi (kernel, +posta elettronica, demoni di stampa, ecc.), ed una \textit{priority}, che +identifica l'importanza del messaggio. Il sistema di \textit{syslog} provvede +poi a riportare i messaggi all'amministratore in varie modalità come: +\begin{itemize*} +\item scriverli sulla console. +\item inviarli via mail ad uno specifico utente. +\item scriverli su un file (comunemente detto \textit{log file}). +\item inviarli ad un altro demone (anche via rete). +\item scartarli. +\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 relative 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}; 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} +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. Il parametro \param{facility} permette invece di specificare una +categoria per classificare i vari messaggi; 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} & \\ +\macro{LOG\_AUTHPRIV} & \\ +\macro{LOG\_CRON} & \\ +\macro{LOG\_DAEMON} & \\ +\macro{LOG\_FTP} & \\ +\macro{LOG\_KERN} & \\ +\macro{LOG\_LOCAL0} & \\ +...& \\ +\macro{LOG\_LOCAL7} & \\ +\macro{LOG\_LPR} & \\ +\macro{LOG\_MAIL} & \\ +\macro{LOG\_NEWS} & \\ +\macro{LOG\_SYSLOG} & \\ +\macro{LOG\_USER} & \\ +\macro{LOG\_UUCP} & \\ +\hline +\end{tabular} +\caption{Valori possibili per l'argomento \param{facility} di \func{openlog}.} +\label{tab:sess_syslog_facility} +\end{table} \section{L'I/O su terminale} diff --git a/socket.tex b/socket.tex index a5af5da..98a79a6 100644 --- a/socket.tex +++ b/socket.tex @@ -480,12 +480,13 @@ possibilit \subsection{La struttura degli indirizzi locali} \label{sec:sock_sa_local} -I socket di tipo \macro{PF\_UNIX} vengono usati per una comunicazione -efficiente fra processi che stanno sulla stessa macchina; essi rispetto ai +I socket di tipo \macro{PF\_UNIX} o \macro{PF\_LOCAL} vengono usati per una +comunicazione fra processi che stanno sulla stessa macchina (per vengono +chiamati \textit{local domain} o anche \textit{Unix domain}); essi rispetto ai precedenti possono essere anche creati in maniera anonima attraverso la -funzione \func{socketpair}. Quando però si vuole fare riferimento esplicito -ad uno di questi socket si deve usare la seguente struttura di indirizzi -definita nel file di header \file{sys/un.h}. +funzione \func{socketpair} (vedi \secref{sec:ipc_socketpair}). Quando però si +vuole fare riferimento esplicito ad uno di questi socket si deve usare la +seguente struttura di indirizzi definita nel file di header \file{sys/un.h}. \begin{figure}[!htb] \footnotesize