%--------------------------------------------------------------------
\chapter{Panoramica di un sistema Linux}
\label{chap:overview}
%--------------------------------------------------------------------

        \begin{chapterquote}
	E Dio guardò quello che aveva fatto,\\
	e vide che era cosa buona.\\
	Genesi 1:31 \\
        \end{chapterquote}

	\noindent
	Questo capitolo dà una panoramica di un sistema Linux: per prima cosa vengono descritti i principali servizi forniti, poi senza scendere nei dettagli i programmi che implementano questi servizi. Lo scopo di questo capitolo è dare una comprensione complessiva del sistema, e le singole componenti sono descritte in altre parti della guida.

\section{Le varie parti di un sistema operativo}

	Un sistema operativo UNIX consiste di un \defin{kernel} ed alcuni \defin{programmi di sistema}. Ci sono anche alcuni \defin{programmi applicativi} con cui si fa il vero lavoro. Il kernel è il cuore del sistema operativo\footnote{In effetti viene spesso in modo errato considerato il sistema operativo stesso, ma non lo è. Un sistema operativo fornisce molti più servizi di un semplice kernel.}: tiene traccia dei file sul disco, avvia i programmi e li fa girare contemporaneamente, assegna la memoria ed altre risorse ai vari processi, riceve e manda i pacchetti alla rete, e così via. Il kernel fa pochissime cose da solo, ma fornisce gli strumenti con cui si possono costruire tutti i servizi; evita anche che chiunque acceda all'hardware direttamente, forzando tutti a utilizzare gli strumenti che fornisce: in questo modo protegge gli utenti l'uno dall'altro. Gli strumenti forniti dal kernel vengono usati attraverso \defin{chiamate di sistema}: consultate le pagine man della sezione 2 per ulteriori informazioni su questo argomento.
\index{kernel}
\index{sistema operativo}
\index{programma di sistema}
\index{programma applicativo}
\index{chiamata di sistema}

	I programmi di sistema usano gli strumenti forniti dal kernel per implementare i vari servizi richiesti per un sistema operativo. I programmi di sistema, come tutti gli altri programmi, girano `sopra al kernel', in quello che viene chiamato \defin{modalità utente} (user mode). La differenza tra i programmi di sistema e i programmi applicativi è lo scopo: le applicazioni sono concepite per fare delle cose utili (o per giocare, se si tratta di un gioco), mentre i programmi di sistema servono per fare funzionare il sistema stesso. Un word processor è un'applicazione, \cmd{telnet} è un programma di sistema. La differenza è comunque spesso non definita, ed è importante solo per chi è abituato a dividere tutto in categorie.
\index{user mode}
\index{modalità utente}

	Un sistema operativo può anche contenere dei compilatori e le corrispondenti librerie (sotto Linux in particolare GCC e la libreria C), anche se non c'è bisogno che tutti i linguaggi di programmazione siano parte integrante del sistema operativo. Ne possono fare parte anche la documentazione, e qualche volta anche dei giochi. Tradizionalmente, il sistema operativo è stato definito come il contenuto del nastro o dei dischi di installazione; con Linux non è così chiaro, perché è distribuito su tutti i siti FTP del mondo.
\index{GCC}
\index{linguaggio di programmazione}
\index{compilatore C}
\index{documentazione}
\index{giochi}

\section{Le parti principali del kernel}

	Il kernel di Linux consiste di diverse parti importanti: la gestione dei processi, la gestione della memoria, i driver per i dispositivi hardware, i driver per i filesystem, la gestione della rete ed altre parti minori. In Figura~\ref{fig:kernel-overview} ne sono mostrati alcuni.
\index{gestione dei processi}
\index{gestione della memoria}
\index{driver dei dispositivi}
\index{driver dei filesystem}
\index{gestione della rete}

\begin{figure}[htb]
\begin{center}
\includegraphics{overview/overview-kernel.ps}
\end{center}
\caption{Alcune delle parti più importanti del kernel Linux.}
\label{fig:kernel-overview}
\end{figure}

	Probabilmente le parti più importanti del kernel (nient'altro funziona senza di esse) sono la gestione della memoria e dei processi. La gestione della memoria si occupa di assegnare le aree di memoria e di spazio di swap ai processi e a parti del kernel, e per la cache di buffer. La gestione dei processi crea i processi ed implementa il multitasking cambiando il processo attivo sul processore.
\index{spazio di swap}
\index{cache di buffer}
\index{multitasking}

	Al livello più basso, il kernel contiene un driver per ciascun dispositivo hardware che supporta. Dato che il mondo è pieno di tipi diversi di hardware il numero dei driver è enorme. Ci sono spesso molti componenti hardware simili che differiscono solo in come vengono controllati dal software; queste similitudini rendono però possibile avere delle classi generali di driver che supportano operazioni simili: ogni membro della classe ha la stessa interfaccia con il resto del kernel, ma si distingue in quello che serve per implementarlo. Ad esempio, tutti i driver dei dischi sembrano uguali dal punto di vista del resto del kernel,  cioè hanno tutti operazioni come `inizializza il driver', `leggi il settore N' e `scrivi il settore N'.

	Alcuni dei servizi software forniti dal kernel stesso hanno proprietà simili, e possono dunque essere astratti in classi. Ad esempio, i vari protocolli di rete sono stati astratti in un'interfaccia di programmazione, la BSD socket library. Un altro esempio è il livello \defin{filesystem virtuale} (VFS), che astrae le operazioni su filesystem, senza considerare la loro implementazione. Ciascun tipo di filesystem fornisce un'implementazione di ogni operazione; quando un'entità prova ad usare un filesystem, la richiesta passa per il VFS, che la gira al driver opportuno.
\index{filesystem virtuale}
\index{VFS}
\index{BSD}
\index{socket}

\section{I principali servizi in un sistema UNIX}

	Questa sezione descrive alcuni dei servizi di UNIX più importanti, ma senza scendere molto nei dettagli; verranno descritti più accuratamente nei capitoli successivi.

\subsection{\cmd{init}}

	Il servizio più importante di un sistema UNIX è fornito da \cmd{init}. \cmd{init} viene inizializzato come primo processo di ciascun sistema UNIX, ed è l'ultima cosa che il kernel fa all'avvio. Quando parte \cmd{init}, continua il processo di boot portando avanti vari compiti (controlla e monta i filesystem, avvia i daemon ecc.).
\index{/sbin/init}
\index{mount di filesystem}
\index{processo di boot}

	L'elenco esatto delle cose che \cmd{init} fa dipende da che tipo è: ce ne sono diversi tra cui scegliere. \cmd{init} di solito fornisce il concetto di \defin{modalità a singolo utente}, in cui nessuno si può collegare e \cmd{root} usa una shella alla console; la modalità usuale viene chiamata \defin{modalità multiutente}.
Alcuni tipi generalizzano questo concetto in \defin{runlevel} (livelli di avvio): le modalità utente singolo e multiutente sono considerate due runlevel, e ce ne possono essere altri, ad esempio, per far girare X sulla console.
\index{runlevel}
\index{modalità utente singolo}
\index{modalità multiutente}
\index{Sistema X Window}

	Nelle normali operazioni, \cmd{init} si assicura che stiano girando processi di \cmd{getty} multipli (per poter far collegare gli utenti), e adotta i processi orfani (i processi il cui padre è morto: in UNIX \emph{tutti} i processi devono essere in un singolo albero, quindi gli orfani devono venire adottati).

	Quando il sistema viene spento, è \cmd{init} che deve uccidere tutti gli altri processi, smontare i filesystem e fermare il processore, oltre agli altri compiti per cui è stato configurato.
\index{uccisione di processi}
\index{unmount di filesystem}
\index{fermare il processore}

\subsection{Login dai terminali}

	I login dai terminali (attraverso linee seriali) e dalla console (quando non si sta usando X) vengono forniti dal programma \cmd{getty}. \cmd{init} avvia una \cmd{getty} separata per ogni terminale da cui sono consentiti i login. \cmd{getty} legge il nome dell'utente e avvia il programma \cmd{login}, che legge la password. Se il nome dell'utente e la password sono corretti, \cmd{login} avvia la shell. Quando la shell termina, cioè l'utente si scollega, o quando \cmd{login} termina perché il nome dell'utente e la password non corrispondono, \cmd{init} lo nota, e avvia un'altra copia di \cmd{getty}. Il kernel non ha nozione dei login, che vengono tutti gestiti dai programmi di sistema.
\index{/sbin/getty}
\index{loggin}
\index{logout}
\index{autenticazione degli utenti}

\subsection{Syslog}

	Il kernel e molti programmi di sistema producono messaggi di errore, di avvertimento e di altro tipo. Spesso è importantre che questi messaggi possano essere letti in un secondo tempo, anche dopo parecchio, quindi devono essere scritti in un file. Il programma che lo fa è \cmd{syslog}, che può essere configurato per distribuire i messaggi in file diversi a seconda di chi li genera o del loro grado di importanza. Ad esempio, i messaggi del kernel sono spesso rediretti in un file separato dagli altri, dato che i messaggi del kernel spesso sono più importanti e devono essere letti regolarmente per individuare i problemi.
\index{messaggi di errore}
\index{messaggi di avvertimento}
\index{file di log}

\subsection{Esecuzione periodica dei comandi: \cmd{cron} e \cmd{at}}

	Sia gli utenti che gli amministratori di sistema hanno spesso bisogno di avviare periodicamente dei comandi. Ad esempio, l'amministratore di sistema potrebbe voler avviare un programma che ripulisca le directory che contengono file temporanei (\fn{/tmp} e \fn{/var/tmp}) dai file vecchi, per evitare che i dischi si riempiano, dato che non tutti i programmi cancellano i file generati.
\index{esecuzione periodica di comandi|see{cron e at}}
\index{file temporanei}
\index{pulizia dei file temporanei}

	Il servizio di \cmd{cron} funziona proprio per questo. Ciascun utente ha una \cmd{crontab}, dove elenca i comandi che vuole eseguire ed il momento in cui farlo; il daemon \cmd{cron} avvia poi i comandi nel momento specificato.
\index{daemon!cron|see{cron}}

	Il servizio \cmd{at} è simile a \cmd{cron}, ma vale per una sola volta: il comando viene eseguito al momento indicato, ma non viene ripetuto.
\index{daemon!at|see{at}}

\subsection{GUI - interfaccia grafica utente}

	UNIX e Linux non hanno incorporata l'interfaccia utente nel kernel; invece, la fanno implementare dai programmi a livello utente. Questo si applica sia per l'ambiente testuale che per quello grafico.

	Questo modo di agire rende il sistema più flessibile, ma ha lo svantaggio che è facile implementare un'interfaccia diversa per ciascun programma, rendendo il sistema più difficile da imparare.

	L'ambiente grafico usato principalmente con Linux si chiama Sistema X Window (in breve, X). X stesso non implementa un'interfaccia utente, ma solo un sistema di finestre, cioè degli strumenti con cui implementarle. I tre stili più conosciuti in X sono Athena, Motif e Open Look.
\index{interfaccia grafica utente}
\index{Sistema X Window}
\index{Athena}
\index{Motif}
\index{Open Look}

\subsection{Le reti}

	Le reti sono dei mezzi per connettere due o più computer in modo che possano comunicare l'un l'altro. I metodi usati di connessione e comunicazione sono piuttosto complessi, ma il risultato finale è molto utile.

	I sistemi operativi UNIX hanno molte capacità di connessione in rete. La maggior parte dei servizi di base---i filesystem, la stampa, i backup ecc---possono essere fatti attraverso la rete; questo può rendere l'amministrazione di sistema più semplice, sfruttando nel contempo i lati positivi dei microcomputer e dell'informatica distribuita, come i costi minori e una più alta tolleranza degli errori.
\index{informatica centralizzata}
\index{informatica distribuita}
\index{tolleranza degli errori}

	Questo libro, comunque, dà solo un accenno alle reti; per ulteriori informazioni c'è la Guida dell'amministratore di rete di Linux, che comprende anche una descrizione di base del funzionamento delle reti.

\subsection{Login in rete}

	I login in rete funzionano in modo leggermente diverso dai login normali: c'è una linea seriale fisica separata per ciascun terminale attraverso cui ci si collega; per ciascuna persona che si collega via rete c'è invece una connessione virtuale separata, e ce ne possono essere infinite\footnote{Beh, almeno ce ne possono essere parecchie. La banda passante della rete è ancora una risorsa piuttosto scarsa, c'è ancora un limite superiore al numero di login contemporanei su una singola connessione di rete.}: non è quindi possibile avviare una \cmd{getty} separata per ciasuna connessione virtuale possibile. Ci sono diversi modi possibili per collegarsi attraverso una rete: i principali nelle reti di tipo TCP/IP sono \cmd{telnet} e \cmd{rlogin}.
	I login di rete hanno, invece di un insieme di \cmd{getty}, un daemon singolo per ciascun modo di collegamento (\cmd{telnet} e \cmd{rlogin} hanno daemon separati) che stanno in ascolto per i tentativi di login in ingresso. Quando ne notano uno, inizializzano una copia di se stessi per gestire quel singolo tentativo; l'istanza originale continua ad aspettarne altri. La nuova istanza funziona in modo simile a \cmd{getty}.
\index{demoni!telnet|see{telnet}}
\index{demoni!rlogin|see{rlogin}}

\subsection{Filesystem di rete}
\label{sec:NFS}

	Una delle cose più utili che possono essere fatte con i servizi di rete è la condivisione di file attraverso un \defin{filesystem di rete}. Quello che viene usato di solito si chiama Network File System, o NFS, ed è sviluppato dalla SUN.
\index{NFS}
\index{file system di rete}
\index{Network File System|see{NFS}}

	Con un filesystem di rete qualsiasi operazione su file fatta da un programma su una macchina è spedita attraverso la rete ad un altro computer. Questo inganna il programma e gli fa pensare che tutti i file sull'altro computer sono in realtà sul computer su cui sta girando il programma, e rende molto semplice la condivisione di informazioni, dato che non richiede modifiche ai programmi.

\subsection{Posta}

La posta elettronica è di solito il metodo più importante per comunicare attraverso il computer. Un messaggio di posta elettronica viene immagazzinato in un file usando un formato speciale, e degli speciali programmi di posta vengono usati per mandare e leggere i messaggi.
\index{comunicazione}
\index{e-mail|see{posta elettronica}}
\index{posta elettronica}
\index{messaggio|see{posta elettronica}}

	Ciascun utente ha una \defin{casella di posta in arrivo} (un file nel formato speciale) dove viene immagazzinata tutta la nuova posta in arrivo. Quando qualcuno spedisce della posta, il programma di posta ritrova la casella del destinatario e aggiunge il messaggio al file. Se la casella di posta del destinatario si trova su un altra macchina, il messaggio viene inviato a quella macchina, che lo aggiunge alla casella nel modo che ritiene migliore.
\index{casella di posta}
\index{posta, casella|see{posta elettronica}}
\index{casella di posta in arrivo}

	Il sistema di posta consiste di molti programmi. La distribuzione a caselle locali o remote viene fatta da un programma (l'agente di trasferimento di posta (\defin{mail transfer agent} o \defin{MTA}), cioè \cmd{sendmail} o \cmd{smail}), mentre i programmi utilizzati dagli utenti sono molti e vari (agenti di posta utente, \defin{mail user agent} o \defin{MUA}, come ad esempio \cmd{pine} o \cmd{elm}). Le caselle di posta vengono in genere tenute in \fn{/var/spool/mail}.

\subsection{Stampa}

	Solo una persona alla volta può usare una stampante, ma non è economico non condividere le stampanti tra vari utenti. La stampante viene quindi gestita da del software che implementa una \defin{coda di stampa}: tutti i job di stampa vengono messi in una coda e quando la stampante ne ha finito uno gliene viene mandato un altro automaticamente. Questo solleva gli utenti dall'organizzazione della coda di stampa e dal litigare per il controllo della stampante.\footnote{Invece formano una nuova coda \emph{alla} stampante, aspettando le stampe, dato che nessuno sembra mai capace di far sapere al software di coda quando i vari job sono veramente finiti. \`E un gran passo avanti per le relazioni sociali inter-ufficio.}
\index{coda di stampa}
\index{condivisione di stampanti}
\index{relazioni sociali}

	Il software di stampa fa anche lo \defin{spool} delle stampe sul disco, cioè il testo viene mantenuto in un file finché il job è in coda. Ciò permette ad un programma applicativo di sputar fuori i job di stampa velocemente al software di coda; l'applicazione non deve così aspettare finché il job è stampato realmente per poter continuare. \`E veramente conveniente, dato che permette di stampare una versione di un file, e non dover aspettare che sia stampata per farne una nuova completamente diversa.
\index{spool}

\section{La struttura del filesystem}

	Il filesystem è diviso in molte parti: di solito insieme a root ci sono \fn{/bin}, \fn{/lib}, \fn{/etc}, \fn{/dev} che formano un singolo filesystem, e poi ce ne possono essere altri, come \fn{/usr} con i programmi ed i dati che non vengono modificati, \fn{/var} con i dati che vengono modificati (come i file di log), ed \fn{/home} con i file personali dei vari utenti. A seconda della configurazione dell'hardware e delle decisioni dell'amministratore di sistema, la divisione può cambiare, e potrebbero essere anche tutti un singolo filesystem.

	Il capitolo~\ref{chap:walkabout} descrive la struttura del filesystem piuttosto nel dettaglio: il Linux Filesystem Standard lo descrive in maniera ancora più dettagliata.
\index{FSSTND}
\index{Linux Filesystem Standard|see{FSSTND}}
\index{Filesystem Standard|see{FSSTND}}
