X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=session.tex;h=cdc557360e7171ba87bed6c0715662f15134bfd9;hp=d852e8463210304efb26bb2947249e675e8942cb;hb=b7117ca455af39e662610dae3413cc561df91c96;hpb=fd934ebcf645120b9c92a434ab6b8755c04a3c07 diff --git a/session.tex b/session.tex index d852e84..cdc5573 100644 --- a/session.tex +++ b/session.tex @@ -1,45 +1,221 @@ -\chapter{Il controllo di sessione} +\chapter{Sessioni di lavoro} \label{cha:session} +Unix nasce prima dell'esistenza dei moderni PC, quando i computer occupavano +stanze intere e ci si poteva collegare solo attraverso dei terminali, ma fin +dalle sue origini è sempre stato un sistema multitasking e multiutente, +in grado di consentire l'utilizzo di un solo computer da parte di più persone. +Esamineremo in questo capitolo i concetti base del sistema delle sessioni di +lavoro, vale a dire il metodo con cui il kernel gestisce l'accesso concorrente +al sistema da parte di più utenti, permettendo loro di eseguire più programmi +in contemporanea. -\section{Il login} -\label{sec:sess_login} +\section{Il \textit{Job control}} +\label{sec:sess_job_control} -\subsection{Il login da terminale} -\label{sec:sess_term_log} +Viene comunemente chiamato \textit{Job control} quell'insieme di funzionalità +del sistema il cui scopo è quello di permettere ad un utente di poter +sfruttare le capacità multitasking di un sistema Unix per eseguire in +contemporanea più processi, pur potendo accedere, di solito, ad un solo +terminale,\footnote{con X e con i terminali vituali tutto questo non è più + vero, dato che si può accedere a molti terminali in contemporanea, ma il + sistema è nato prima dell'esistenza di tutto ciò.} avendo cioè un solo punto +in cui si può avere accesso all'input ed all'output degli stessi. -\subsection{Il login via rete} -\label{sec:sess_net_log} +\subsection{La struttura di base} +\label{sec:sess_relation} + +Per poter gestire il \textit{Job Control} il kernel associa a ciascun processo +due ulteriori identificatori (oltre quelli visti in \secref{sec:proc_pid}): +l'identificatore del cosiddetto \textit{process group} (o +\textsl{ragguppamento di processi}), cui si fa di norma riferimento con la +sigla \acr{pgid}, l'identificatore di sessione (il \textit{session id}) cui si +fa riferimento con la sigla \acr{sid}). In questo modo, sulla base dei valori +dei rispettivi indicatori, i processi vengono organizzati in \textsl{sessioni} +e \textsl{raggruppamenti}. + +Entrambi gli identificatori vengono impostati alla creazione di ciascun +processo allo stesso valore che hanno nel processo padre, un processo appena +creato cioè appartiene sempre allo stesso raggruppamento e alla stessa +sessione del padre. La differenza fra i due identificatori è che un processo +può cambiare \acr{pgid} soltanto ad un valore che corrisponda al +\textit{process group} di un altro processo della stessa sessione, oppure al +suo stesso \acr{pid} (creando così un nuovo \textit{process group}). Se invece +si modifica il \acr{sid} il processo viene automaticamente messo anche in un +nuovo \textit{process group}, corrispondente al suo \acr{pid}. + +Per capire meglio il significato di questi identificatori vediamone subito +l'uso concreto nella gestione del \textit{job control} della linea di comando. +Una volta che si è completata la procedura di login (che esamineremo in +dettaglio in \secref{sec:sess_login}), si avrà a disposizione una shell, +associata ad un terminale (detto \textsl{terminale di controllo}), dalla quale +eseguire i comandi, una delle caratteristiche della shell è quella di +consentire di inviare un comando in \textit{background}, cioè di farlo +eseguire distaccandolo dal terminale, che potrà essere utilizzato da altri +comandi. Così un solo un comando alla volta potrà leggere e scrivere sul +terminale (quello che viene detto in \textit{foreground}). + +Fra le funzionalità della shell c'è anche quella di consentire di concatenare +più programmi in una sola riga di comando con le pipe, in tal caso, ed +inoltre, anche quando si invoca un singolo programma, questo può sempre +lanciare ulteriori sottoprocessi per eseguire dei compiti specifici. + +La shell farà si che tutti i processi che originano da un sola riga di +comando vengano raggruppati in un unico \textit{process group}; questo perché +i segnali inviati sul terminale con i comandi da tastiera (quelli illustrati +in \secref{sec:sig_job_control}) vengono inviati a tutti i processi che fan +parte del raggruppamento di \textit{foreground}, cioè quelli che stanno corre + + +Per consentire l'utilizzo contemporaneo dello stesso terminale la shell deve +essere in grado di garantire che solo un comando alla volta possa accedervi; + + + + + +Lo stato del sistema può essere verificato con il comando \cmd{ps -je f} + + + +\subsection{Il login ed il terminale di controllo} +\label{sec:sess_login} + +L'organizzazione del sistema del \textit{Job Control} è strettamente connessa +alle modalità con cui un utente accede al sistema, collegandosi ad esso con un +terminale, che sia questo realmente tale, come un VT100 collegato 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 +file standard di \secref{sec:file_std_descr}, tratteremo solo il caso in +questo è il classico terminale. + +Abbiamo già brevemente illustrato in \secref{sec:intro_kern_and_sys} le +modalità con cui il sistema si avvia, e di come, a partire da \cmd{init}, +vengano lanciati tutti gli altri processi. Adesso vedremo in maniera più +dettagliata le modalità con cui il sistema arriva a fornire ad un utente la +shell che gli permette di lanciare i suoi comandi su un terminale. + +Nella maggior parte delle distribuzioni di GNU/Linux\footnote{fa eccezione la + distribuzione \textit{Slackware}, come alcune distribuzioni su dischetto, ed + altre distribuzioni dedicate a compiti limitati e specifici.} viene usata +la procedura di avvio di System V; questa prevede che \cmd{init} legga dal +file di configurazione \file{/etc/inittab} quali programmi devono essere +lanciati, ed in quali modalità, a seconda del cosiddetto \textit{run level}, +anch'esso definito nello stesso file. + +Tralasciando la descrizione del sistema dei run level, (per il quale si +rimanda alla lettura delle pagine di manuale di \cmd{init} e di +\file{inittab}) quello che comunque viene sempre fatto è di eseguire almeno +una istanza di un programma che permetta l'accesso ad un terminale. Uno schema +di massima della procedura è riportato in \secref{fig:sess_term_login}. + +\begin{figure}[htb] + \centering + \includegraphics[width=15cm]{img/tty_login} + \caption{Schema della procedura di login su un terminale.} + \label{fig:sess_term_login} +\end{figure} + +Un terminale, che esso sia un terminale effettivo, attaccato ad una seriale o +ad un altro tipo di porta di comunicazione, o una delle console virtuali +associate allo schermo, viene sempre visto attraverso attraverso un device +driver che ne presenta un'interfaccia comune su un apposito file di +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 + associati alle connessioni di rete con \cmd{telnet} o \cmd{ssh}.} + +Per controllare i terminali si usa di solito il programma \cmd{getty} (od una +delle sue varianti), che permette di mettersi in ascolto sugli stessi. Alla +radice della catena che porta ad una shell per i comandi perciò c'è sempre +\cmd{init} che esegue prima una \func{fork} e poi una \func{exec} per lanciare +una istanza di questo programma su un terminale, il tutto ripetuto per +ciascuno dei terminali che si hanno a disposizione (o per un certo numero di +essi, nel caso delle console virtuali), secondo quanto indicato +dall'amministratore nel file di configurazione del programma, +\file{/etc/inittab}. + +Quando viene lanciato da \cmd{init} il programma parte con i privilegi di +amministratore e con un ambiente vuoto; \cmd{getty} si cura di aprire il +terminale in lettura sullo standard input ed in scrittura sullo standard +output e sullo standard error, e di effettuare, 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 + tipi di caratteri (a beneficio di alcuni vecchi terminali che non + supportavano le minuscole).} ed infine il programma stamperà un messaggio di +benvenuto per poi porsi in attesa dell'immissione del nome di un utente. + +Una volta che si sia immesso il nome di login \cmd{getty} esegue direttamente +il programma \cmd{login} con una \func{exevle}, passando come argomento la +suddetta stringa ed un ambiente opportunamente costruito che contenga quanto +necessario (ad esempio di solito viene opportunamente inizializzata la +variabile di ambiente \texttt{TERM}) ad identificare il terminale su cui si +sta operando, a beneficio dei programmi che verranno lanciati in seguito. + +A sua volta \cmd{login}, che mantiene i privilegi di amministratore, usa il +nome dell'utente per effettuare una ricerca nel database degli +utenti,\footnote{in genere viene chiamata \func{getpwnam}, che abbiamo visto + in \secref{sec:sys_user_group}, per leggere la password e gli altri dati dal + database degli utenti.} e richiede una password. Se l'utente non esiste o se +la password non corrisponde\footnote{il confronto non viene effettuato con un + valore in chiaro; quanto immesso da terminale viene invece a sua volta + criptato, ed è il risultato che viene confrontato con il valore che viene + mantenuto nel database degli utenti.} la richiesta viene ripetuta un certo +numero di volte dopo di che \cmd{login} esce ed \cmd{init} provvede a +rilanciare un'altra istanza di \func{getty}. + +Se invece la password corrisponde a questo punto \cmd{login} esegue +\func{chdir} per settare la \textit{home directory} dell'utente, cambia i +diritti di accesso al terminale (con \func{chown} e \func{chmod}) per +assegnarne la titolarità all'utente ed al suo gruppo principale, assegnandogli +al contempo i diritti di lettura e scrittura. Inoltre il programma provvede +a costruire gli opportuni valori per le variabili di ambiente, come +\texttt{HOME}, \texttt{SHELL}, ecc. Infine attraverso l'uso di \func{setuid}, +\func{setpid} e \func{initgroups} verrà cambiata l'identità del proprietario +del processo, infatti, come spiegato in \secref{sec:proc_setuid}, avendo +invocato tali funzioni con i privilegi di amministratore, tutti gli userid ed +i groupid (reali, effettivi e salvati) saranno settati a quelli dell'utente. + +A questo punto \cmd{login} provvederà (fatte salve eventuali altre azioni +iniziali, come la stampa di messaggi di benvenuto o il controllo della posta) +ad eseguire con un'altra \func{exec} la shell di login, che si troverà con un +ambiente già pronto e con file standard di \secref{sec:file_std_descr} +impostati sul terminale, pronta ad eseguire i comandi fino all'uscita. Dato +che il processo genitore resta sempre \cmd{init} quest'ultimo provvederà, +ricevendo un \macro{SIGCHLD} all'uscita della shell, a rilanciare \cmd{getty} +per ripetere da capo tutto il procedimento. -\section{Le relazioni fra i processi} -\label{sec:sess_relation} \subsection{I \textit{process group}} \label{sec:sess_proc_group} + \subsection{Le sessioni} \label{sec:sess_sessions} + \subsection{Il terminale di controllo} \label{sec:sess_ctrl_term} -\section{Il \textit{job control}} -\label{sec:sess_job_control} - - \subsection{La shell e i programmi} \label{sec:sess_shell} + %%% Local Variables: %%% mode: latex %%% TeX-master: "gapil"