3.8 I Demoni, i Segnali, e come Uccidere i Processi

Quando esegui un editor risulta semplice averne il controllo, dirgli di caricare file, e così via. Tutto questo può essere fatto poichè l'editor fornisce delle agevolazioni in questo senso, e anche perchè l'editor è collegato a un terminale. Alcuni programmi non sono stati progettati per essere eseguiti con un continuo input dell'utente, e perciò questi programmi si disconnettono dal terminale alla prima occasione. Per esempio, un server web trascorre tutto il giorno rispondendo a richieste web, e normalmente non necessita di alcun input da parte tua. I programmi che trasportano la posta elettronica da un sito a un altro sito sono un altro esempio di questa classe di applicazioni.

Chiamiamo questi programmi demoni. I demoni erano dei personaggi della mitologia greca: nè buoni nè cattivi, erano piccoli spiriti custodi che, nel complesso, risultavano essere utili per l'umanità, molto similmente i server web e quelli di posta elettronica di oggi fanno cose utili. Ecco il motivo per cui la mascotte di BSD è stata per molto tempo, e lo è ancora, l'allegro demone con le scarpe da tennis e con il forcone.

Esiste la convenzione di chiamare i programmi che normalmente sono eseguiti come demoni con una “d” finale. BIND sta per Berkeley Internet Name Domain, ma il nome effettivo del programma che viene eseguito è named; il nome del programma Apache, un server web, è httpd; il demone dello spool di stampa è lpd e così via. Questa è una convenzione, non è una regola ferrea; per esempio, il principale demone di posta elettronica per l'applicazione Sendmail è chiamato sendmail, e non maild, come potresti aspettarti.

A volte puoi aver bisogno di comunicare con un processo demone. Un modo per farlo è di mandare a esso (o ad altri processi in esecuzione), un segnale. Esistono svariati segnali che puoi inviare--alcuni di questi hanno un significato specifico, altri sono interpretabili dall'applicazione, e la documentazione dell'applicazione ti dirà come l'applicazione stessa interpreta i segnali. Puoi mandare un segnale solo ai processi che ti appartengono. Se mandi un segnale a un processo che non ti appartiene con il comando kill(1) o kill(2), il permesso ti sarà negato. L'eccezione a questa regola riguarda l'utente root, che può mandare segnali a processi di chiunque.

Inoltre in alcune circostanze FreeBSD invia segnali alle applicazioni. Se un'applicazione è stata scritta malamente, e tenta di accedere alla memoria che non gli compete, FreeBSD manda al processo il segnale di Violazione della Segmentazione (SIGSEGV). Se un'applicazione ha utilizzato la system call alarm(3) in modo tale da essere avvisata dopo un certo periodo di tempo trascorso allora FreeBSD invierà a questa applicazione il segnale di Allarme (SIGALRM), e così via.

Per fermare un processo possono essere utilizzati due segnali, SIGTERM e SIGKILL. SIGTERM è il modo cortese di terminare un processo; il processo può catturare il segnale, capire che vuoi abbatterlo, chiudere i file di log che potrebbe avere aperto, e in genere terminare qualunque cosa che stava facendo prima dell'interruzione. Nei casi in cui un processo sia coinvolto in qualche compito che non può essere interrotto allora questo processo può persino ignorare SIGTERM.

Il segnale SIGKILL non può essere ignorato da un processo. Questo è il segnale che dice “Non mi interessa cosa stai facendo, fermati subito”. Se mandi il segnale SIGKILL a un processo allora FreeBSD fermerà subito il processo[1].

Altri segnali che potresti aver bisogno di usare sono SIGHUP, SIGUSR1, e SIGUSR2. Questi sono segnali a scopo generico, e differenti applicazioni possono fare cose diverse quando catturano questi segnali.

Supponiamo che hai cambiato il file di configurazione del tuo server web--hai bisogno di dire al server web di rileggere la sua configurazione. Potresti fermare e riavviare httpd, ma questo porterebbe a un breve periodo di interruzione del tuo server web, che potrebbe non essere gradito. Molti demoni sono stati scritti per rispondere al segnale SIGHUP tramite la rilettura dei loro file di configurazione. In questo modo invece di terminare e riavviare httpd potresti inviare il segnale SIGHUP. Poichè non esiste un modo standard di trattare questi segnali, differenti demoni potrebbero avere un comportamento diverso, quindi assicurati di leggere la documentazione per il demone in questione.

I segnali sono inviati utilizzando il comando kill(1), come mostra questo esempio.

Inviare un Segnale a un Processo

Questo esempio mostra come inviare un segnale a inetd(8). Il file di configurazione di inetd è /etc/inetd.conf, e inetd rilegge questo file di configurazione quando riceve il segnale SIGHUP.

  1. Cerca il process ID del processo a cui vuoi mandare il segnale. Puoi utilizzare ps(1) e grep(1) per farlo. Il comando grep(1) viene utilizzato per perlustrare attraverso l'output, cercando la stringa da te specificata. Questo comando viene eseguito in modalità utente, e inetd(8) viene eseguito in modalità root, quindi le opzioni da dare a ps(1) sono ax.

    % ps -ax | grep inetd
      198  ??  IWs    0:00.00 inetd -wW
    

    Come puoi vedere il PID di inetd(8) è 198. In alcuni casi potrebbe apparire nel risultato anche il comando grep inetd. Questo dipende dal modo utilizzato da ps(1) nell'elencare la lista dei processi in esecuzione.

  2. Usa il comando kill(1) per inviare il segnale. Poichè inetd(8) viene eseguito in modalità root prima devi usare il comando su(1) per diventare root.

    % su
    Password:
    # /bin/kill -s HUP 198
    

    Come avviene per la maggior parte dei comandi UNIX®, il comando kill(1) non stampa il risultato dell'operazione se questa ha avuto successo. Se mandi un segnale a un processo del quale non sei il proprietario allora vedrai il messaggio “kill: PID: Operation not permitted”. Se sbagli il PID invierai il segnale al processo sbagliato, il che potrebbe essere dannoso, o, se hai fortuna, manderai il segnale a un PID che in quel momento non è in uso, e in questo caso vedrai il messaggio “kill: PID: No such process”.

    Perchè Usare /bin/kill?: Molte shell forniscono il comando kill come comando built-in; ossia, la shell invia il segnale in modo diretto, senza dover eseguire /bin/kill. Tutto ciò può essere molto utile, ma le diverse shell hanno una sintassi diversa per specificare il nome del segnale da inviare. Invece di cercare di imparare tutte queste sintassi, può essere più semplice usare direttamente il comando /bin/kill ....

L'invio di altri segnali è analogo, basta sostituire all'occorrenza TERM o KILL nella linea di comando.

Importante: Terminare processi in modo random su un sistema può essere una cattiva idea. In particolare, il processo init(8), con process ID 1, è un caso molto speciale. Eseguire /bin/kill -s KILL 1 è un modo veloce per arrestare il tuo sistema. Controlla sempre due volte gli argomenti quando esegui kill(1) prima di premere Invio.

Note

[1]

Non è del tutto vero--ci sono alcune cose che non possono essere interrotte. Per esempio, se il processo sta tentando di leggere un file situato su un altro computer in rete, e questo computer non è disponibile per qualche ragione (è stato spento, o la rete ha qualche problema), allora il processo è detto “non interrompibile”. Il processo finirà in time out, generalmente dopo due minuti. Non appena avviene il time out il processo potrà essere terminato.

Questo, ed altri documenti, possono essere scaricati da ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.

Per domande su FreeBSD, leggi la documentazione prima di contattare <questions@FreeBSD.org>.
Per domande su questa documentazione, invia una e-mail a <doc@FreeBSD.org>.