X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=session.tex;h=2f73d61b53bd790d8a3f0303dcf86eb926c7ac63;hp=756984321132fe5d73b3a9666287e436218fd508;hb=9448294bbb0d4ffbf8e606a39e5c0c616776cbde;hpb=f4e0bed8a292cd120d3d21958ad0810d95915cec diff --git a/session.tex b/session.tex index 7569843..2f73d61 100644 --- a/session.tex +++ b/session.tex @@ -60,7 +60,7 @@ questo potr Per questo l'esecuzione di un comando può originare più di un processo; quindi nella gestione del job control non si può far riferimento ai singoli processi. Per questo il kernel prevede la possibilità di raggruppare più processi in un -\textit{process group} (detto anche \textsl{raggruppamento}, vedi +\textit{process group} (detto anche \textsl{raggruppamento di processi}, vedi \secref{sec:sess_proc_group}) e la shell farà sì che tutti i processi che originano da una riga di comando appartengano allo stesso \textit{process group}, in modo che le varie funzioni di controllo, ed i segnali inviati dal @@ -237,7 +237,7 @@ componente. Inoltre la funzione distacca il processo da ogni terminale di controllo (torneremo sull'argomento in \secref{sec:sess_ctrl_term}) cui fosse in precedenza associato. -La funzione ha successo soltanto se il processo non è già leader di un + funzione ha successo soltanto se il processo non è già leader di un \textit{process group}, per cui per usarla di norma si esegue una \func{fork} e si esce, per poi chiamare \func{setsid} nel processo figlio, in modo che, avendo questo lo stesso \acr{pgid} del padre ma un \acr{pid} diverso, non ci @@ -279,15 +279,16 @@ controllo. Alla creazione di una nuova sessione con \func{setsid} ogni associazione con il precedente terminale di controllo viene cancellata, ed il processo che è -divenuto un nuovo leader di sessione dovrà riottenere (qualora sia necessario, -cosa che, come vedremo in \secref{sec:sess_daemon}, non è sempre vera), un -terminale di controllo. In generale questo viene fatto automaticamente dal -sistema quando viene aperto il primo terminale\footnote{a meno di non avere - richiesto esplicitamente che questo non diventi un terminale di controllo - con il flag \macro{O\_NOCTTY} (vedi \secref{sec:file_open}). In questo Linux - segue la semantica di SVr4; BSD invece richiede che il terminale venga - allocato esplicitamente con una \func{ioctl} con il comando - \macro{TIOCSCTTY}.} che diventa automaticamente il terminale di controllo, +divenuto un nuovo leader di sessione dovrà riottenere\footnote{solo quando ciò + è necessario, cosa che, come vedremo in \secref{sec:sess_daemon}, non è + sempre vera}, un terminale di controllo. In generale questo viene fatto +automaticamente dal sistema\footnote{a meno di non avere richiesto + esplicitamente che questo non diventi un terminale di controllo con il flag + \macro{O\_NOCTTY} (vedi \secref{sec:file_open}). In questo Linux segue la + semantica di SVr4; BSD invece richiede che il terminale venga allocato + esplicitamente con una \func{ioctl} con il comando \macro{TIOCSCTTY}.} +quando viene aperto il primo terminale (cioè uno dei vari file di dispositivo +\file{/dev/tty*}) che diventa automaticamente il terminale di controllo, mentre il processo diventa il \textsl{processo di controllo} di quella sessione. @@ -328,9 +329,11 @@ controllo provocher lettura o scrittura) a tutto il suo \textit{process group}; dato che il comportamento di default di questi segnali (si riveda quanto esposto in \secref{sec:sig_job_control}) è di bloccare il processo, di norma questo -comporta che tutti verranno fermati, ma non si avranno condizioni di -errore. Se però si bloccano o ignorano i due segnali citati, le funzioni di -lettura e scrittura falliranno con un errore di \macro{EIO}. +comporta che tutti i membri del gruppo verranno fermati, ma non si avranno +condizioni di errore.\footnote{la shell in genere notifica comunque un + avvertimento, avvertendo la presenza di processi bloccati grazie all'uso di + \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 ad un terminale con la funzione \func{tcgetpgrp}, il cui prototipo è: @@ -361,40 +364,79 @@ file descriptor originario; un caso tipico accetta la redirezione sullo standard input di un file da decrittare, ma deve poi leggere la password dal terminale. -Un'altra caratteristica del gruppo di \textit{foreground} è che il kernel -invia i segnali generati dai caratteri speciali del terminale (\cmd{C-z}, -\cmd{C-c}, \cmd{C-y} e \verb|C-\|, che generano rispettivamente -\macro{SIGTSTP}, \macro{SIGINT}, \macro{SIGQUIT} e \macro{SIGTERM}), solo ai -processi che ne fanno parte. - -In caso di \textit{hungup} del terminale (si chiama così una condizione di -blocco del terminale, letteralmente sarebbe \textsl{impiccagione}), ad esempio -se si interrompe la linea, o va giù la rete, il kernel provvederà ad inviare -il segnale di \macro{SIGHUP} al processo di controllo. L'azione preimpostata -in questo caso è la terminazione del processo, il problema è cosa accade agli -altri processi nella sessione, che non han più un processo di controllo che -possa gestire l'accesso al terminale, che potrebbe essere riutilizzato per -qualche altra sessione. - -Lo standard POSIX.1 prevede che se il processo di controllo termina (che ciò -avvenga per un \textit{hungup} del terminale o meno) venga inviato un segnale -di \macro{SIGHUP} ai processi del gruppo di foreground. In questo modo essi -potranno essere avvisati che non esiste più un processo in grado di gestire il -terminale (di norma tutto ciò comporta la terminazione anche di questi -ultimi). - -Restano però i processi in background, che, per quanto detto, potrebbero -proseguire la loro esecuzione e, fintanto che non accedono al terminale non ci -sarebbero problemi. In caso di accesso però potrebbero (in seguito al -comportamento standard appena descritto) bloccarsi, e restare tali per sempre, -dato che non c'è più il processo di controllo. Questa situazione è quella che -in cui si ha un cosiddetto \textit{orphaned process group}, che POSIX.1 -definisce come un \textit{process group} i cui processi hanno come padri o -altri processi nel gruppo, o processi fuori della sessione. - -Si ricordi che un processo è detto orfano quando il suo padre è terminato, nel -qual caso viene adottato da \cmd{init}, che è al di fuori di qualunque -sessione, +Un'altra caratteristica del terminale di controllo usata nel job control è che +utilizzando su di esso le combinazioni di tasti speciali (\cmd{C-z}, +\cmd{C-c}, \cmd{C-y} e \verb|C-\|) si farà si che il kernel invii i +corrispondenti segnali (rispettivamente \macro{SIGTSTP}, \macro{SIGINT}, +\macro{SIGQUIT} e \macro{SIGTERM}, trattati in \secref{sec:sig_job_control}) a +tutti i processi del gruppo di \textit{foreground}; in questo modo la shell +può gestire il blocco e l'interruzione dei vari comandi. + +Per completare la trattazione delle caratteristiche del job control legate al +terminale di controllo, occorre prendere in considerazione i vari casi legati +alla terminazione anomala dei processi, che sono di norma gestite attraverso +il segnale \macro{SIGHUP}. Il nome del segnale deriva da \textit{hungup}, +termine che viene usato per indicare la condizione in cui il terminale diventa +inutilizzabile, (letteralmente sarebbe \textsl{impiccagione}). + +Quando si verifica questa condizione, ad esempio se si interrompe la linea, o +va giù la rete o più semplicemente si chiude forzatamente la finestra di +terminale su cui si stava lavorando, il kernel provvederà ad inviare il +segnale di \macro{SIGHUP} al processo di controllo. L'azione preimpostata in +questo caso è la terminazione del processo, il problema che si pone è cosa +accade agli altri processi nella sessione, che non han più un processo di +controllo che possa gestire l'accesso al terminale, che potrebbe essere +riutilizzato per qualche altra sessione. + +Lo standard POSIX.1 prevede che quando il processo di controllo termina, che +ciò avvenga o meno per un \textit{hungup} del terminale (ad esempio si +potrebbe terminare direttamente la shell con \cmd{kill}) venga inviato un +segnale di \macro{SIGHUP} ai processi del gruppo di foreground. In questo modo +essi potranno essere avvisati che non esiste più un processo in grado di +gestire il terminale (di norma tutto ciò comporta la terminazione anche di +questi ultimi). + +Restano però gli eventuali processi in background, che non ricevono il +segnale; in effetti se il terminale non dovesse più servire essi potrebbero +proseguire fino al completamento della loro esecuzione; ma si pone il problema +di come gestire quelli che sono bloccati, o che si bloccano nell'accesso al +terminale, in assenza di un processo che sia in grado di effettuare il +controllo dello stesso. + +Questa è la situazione in cui si ha quello che viene chiamato un +\textit{orphaned process group}. Lo standard POSIX.1 lo definisce come un +\textit{process group} i cui processi hanno come padri esclusivamente o altri +processi nel gruppo, o processi fuori della sessione. Lo standard prevede +inoltre che se la terminazione di un processo fa sì che un raggruppamento di +processi diventi orfano e se i suoi membri sono bloccati, ad essi vengano +inviati in sequenza i segnali di \macro{SIGHUP} e \macro{SIGCONT}. + +La definizione può sembrare complicata, e a prima vista non è chiaro cosa +tutto ciò abbia a che fare con il problema della terminazione del processo di +controllo. Consideriamo allora cosa avviene di norma nel \textit{job + control}: una sessione viene creata con \func{setsid} che crea anche un +nuovo process group: per definizione quest'ultimo è sempre \textsl{orfano}, +dato che il padre del leader di sessione è fuori dalla stessa e il nuovo +process group contiene solo il leader di sessione. Questo è un caso limite, e +non viene emesso nessun segnale perché quanto previsto dallo standard riguarda +solo i raggruppamenti che diventano orfani in seguito alla terminazione di un +processo.\footnote{l'emissione dei segnali infatti avviene solo nella fase di + uscita del processo, come una delle operazioni legate all'esecuzione di + \func{_exit}, secondo quanto illustrato in \secref{sec:proc_termination}.} + +Il leader di sessione provvederà a creare nuovi raggruppamenti di processi che +a questo punto non sono orfani in quanto esso resta padre per almeno uno dei +processi del gruppo (gli altri possono derivare dal primo). Alla terminazione +del leader di sessione però avremo che, come visto in +\secref{sec:proc_termination}, tutti i suoi figli vengono adottati da +\cmd{init}, che è fuori dalla sessione. Questo renderà orfani tutti i process +group creati direttamente dal leader di sessione (a meno di non aver spostato +con \func{setpgid} un processo da un gruppo ad un altro, cosa che di norma non +viene fatta) i quali riceveranno, nel caso siano bloccati, i due segnali: +\macro{SIGCONT} ne farà proseguire l'esecuzione, e, essendo stato nel +frattempo inviato anche \macro{SIGHUP}, se non c'è un gestore per +quest'ultimo, essi saranno terminati. + @@ -513,8 +555,6 @@ ricevendo un \macro{SIGCHLD} all'uscita della shell, a rilanciare \cmd{getty} per ripetere da capo tutto il procedimento. - - In generale quando con il contollo di sessione è la shell che assume il ruolo di processo di controllo, seleziona il gruppo di \textit{foregroud} e gestisce l'assegnazione dei process group ai programmi eseguiti sulla stessa riga di