2.7 I daemon

Un sistema, oltre ad eseguire i comandi impartiti dagli utenti, può mettere a disposizione degli stessi alcuni servizi come la posta elettronica, il server web, la gestione centralizzata degli utenti (in genere tutte cose che vengono utilizzate quando si ha a che fare con reti di computer, v. parte II).

La procedura di inizializzazione del sistema ha il compito di avviare il sistema operativo e di fermarlo, attivando e disattivando tutti i servizi necessari, cioè intervenendo nell’avvio e nella terminazione dei processi ad essi relativi. Tali processi, detti daemon (tradotti volgarmente “demoni”), forniscono i servizi desiderati ed hanno la caratteristica di essere avviati automaticamente all’avvio del sistema e rimanere in esecuzione in background (v. cap. 7) finché il sistema non viene spento. Niente vieta comunque che tali processi possano essere avviati o terminati manualmente in qualunque altro momento del funzionamento del sistema qualora lo si desideri.

La procedura di avvio dei daemon è un sistema automatico per l’avvio dei servizi che si desiderano attivare subito dopo l’avvio del sistema (e terminare subito prima dell’arresto del sistema stesso), derivata dalla procedura di avvio di System V . Secondo una convenzione diffusa, per facilitare l’avvio e la terminazione dei servizi si definisce una directory specifica (/etc/rc.d/init.d o simile), all’interno della quale si possono inserire degli script41 di gestione dei daemon che si preoccupano di gestire opportunamente l’avvio e la terminazione dei servizi. In genere per ogni daemon esiste sempre un opportuno script, detto script di controllo del daemon, che si preoccupa di lanciare in esecuzione il daemon in maniera opportuna, effettuando gli adeguati controlli, per mezzo di una sintassi semplice e “standard”. In genere lo script di controllo del daemon ha il nome del servizio da esso gestito. Convenzionalmente gli script di controllo dei daemon hanno la seguente sintassi di lancio:

 
# script_name {start|restart|stop|...}  
dove script_name è il nome dello script. Gli argomenti possono essere molteplici, ma comunque quasi tutti (per non dire tutti) gli script di controllo dei servizi hanno come argomenti start, stop e restart, che, come sottolineano i termini, indicano rispettivamente allo script di avviare, terminare o riavviare (terminare e subito dopo riavviare) il servizio. Tali script si preoccupano anche di effettuare i controlli necessari per servire la richiesta specificata dall’argomento passato sulla riga di comando: ad esempio controllano, prima di avviare un servizio, che questo non sia già in esecuzione.


pict
Figura 2.6: Gestione dei daemon.

Gli script di controllo dei daemon vengono gestiti nel modo seguente (v. fig. 2.6): ad ogni runlevel è associata una directory /etc/rc.d/rcx.d (dove x è il valore del runlevel relativo). In tali directory ci sono dei symbolic link, appositi file (v. sez. 4.6.3), che fanno riferimento ad alcuni script menzionati precedentemente. Il nome dei symbolic link è del tipo Snnscript_name e Knnscript_name, dove nn è un valore numerico a 2 cifre e script_name è il nome dello script che gestisce il servizio considerato. Il file che effettua la gestione automatica degli script di controllo dei daemon (/etc/rc.d/rc o simili) viene lanciato in esecuzione generalmente da init che provvede a fornirgli, nella riga di comando, il runlevel corrente (x). Tale file, che è a sua volta uno script, lancia in esecuzione, in ordine alfabetico, i file presenti all’interno della directory /etc/rc.d/rcx.d, il cui nome inizia per ‘K’ (Kill), con l’argomento stop. Quindi avvia, sempre in ordine alfabetico, quelli il cui nome inizia per ‘S’ (Start) con l’argomento start. In questo modo vengono eseguiti i symbolic link sopra menzionati ovvero gli script di controllo dei daemon (contenuti generalmente nella directory /etc/rc.d/init.d), i quali avviano o terminano l’esecuzione del relativo servizio (daemon). Un esempio semplificato del contenuto del file di gestione automatica degli script di controllo dei daemon è quello riportato di seguito.

#! /bin/bash
#
# Sample file for starting/stopping
# services when the runlevel changes.
runlevel="$1"
# Is there an rc directory for this runlevel?
[ -d /etc/rc$runlevel.d ] || exit 0
# First, run the KILL scripts.
for i in /etc/rc$runlevel.d/K* ; do
    # Check if the file exists at all.
    [ -x "$i" ] || continue
    # Check if the daemon is already up.
    daemonname=${i#/etc/rc$runlevel.d/K??}
    [ -f /var/lock/subsys/$daemonname -o -f /var/lock/subsys/$daemonname.init ] \
           || continue
    # Bring the daemon down.
    $i stop
done
# Then run the START scripts.
for i in /etc/rc$runlevel.d/S* ; do
    # Check if the file exists at all.
    [ -x "$i" ] || continue
    # Check if the daemon is already up.
    daemonname=${i#/etc/rc$runlevel.d/S??}
    [ -f /var/lock/subsys/$daemonname -o -f /var/lock/subsys/$daemonname.init ] \
           || continue
    # Bring the daemon up.
    $i start
done
Da quanto detto, se ne deduce che le directory /etc/rc.d/rc0.d e /etc/rc.d/rc6.d, relative ai runlevel 0 e 6 (che portano rispettivamente allo spegnimento e al riavvio del sistema), conterranno esclusivamente file che iniziano con ‘K’, in quanto, in tali casi, gli eventuali daemon in esecuzione dovranno essere terminati.

In questo modo, se si vuole aggiungere l’avvio di un servizio non c’è bisogno di modificare nessun file, ma è sufficiente creare lo script per la gestione del relativo daemon in modo che accetti i parametri start e stop e quindi creare i symbolic link relativi a tale file con i nomi opportuni (Snn... e Knn...) in maniera da inserirli nell’ordine corretto (l’ordine alfabetico dei symbolic link è quello secondo il quale vengono avviati/arrestati i servizi) tra quelli già presenti nella directory /etc/rc.d/rcx.d.

Ad esempio, il servizio server HTTP (server web - v. cap. 19) è effettuato dal daemon /usr/sbin/httpd che è controllato tramite lo script /etc/rc.d/init.d/httpd. Se si desidera avviare automaticamente il servizio di server HTTP all’accensione del sistema nel runlevel 3, sarà sufficiente creare un symbolic link al file /etc/rc.d/init.d/httpd con il nome Snnhttp dove nn è il numero che esprime l’ordine di avvio del daemon relativo al servizio HTTP rispetto agli altri servizi. L’ordine è importante perché alcuni servizi si appoggiano ad altri che devono quindi essere avviati precedentemente. Nel caso del server HTTP è una buona idea assegnare a nn un valore piuttosto alto.

Di seguito è riportato, a titolo di esempio, il contenuto del file /etc/init.d/httpd che gestisce il daemon httpd.

#!/bin/bash
#
# Startup script for the Apache Web Server
#
# chkconfig: - 85 15
# description: Apache is a World Wide Web server.  It is used to serve \
#              HTML files and CGI.
# processname: httpd
# pidfile: /var/run/httpd.pid
# config: /etc/httpd/conf/httpd.conf
# Include common useful functions.
# Source function library.
. /etc/rc.d/init.d/functions
if [ -f /etc/sysconfig/httpd ]; then
    . /etc/sysconfig/httpd
fi
# This will prevent initlog from swallowing up a pass-phrase prompt if
# mod_ssl needs a pass-phrase from the user.
INITLOG_ARGS=""
# Path to the apachectl script, server binary, and short-form for messages.
apachectl=/usr/sbin/apachectl
httpd=/usr/sbin/httpd
prog=httpd
RETVAL=0
# check for 1.3 configuration
check13 () {
    CONFFILE=/etc/httpd/conf/httpd.conf
    GONE="(ServerType|BindAddress|Port|AddModule|ClearModuleList|"
    GONE="${GONE}AgentLog|RefererLog|RefererIgnore|FancyIndexing|"
                                                                        
                                                                        
    GONE="${GONE}AccessConfig|ResourceConfig)"
    if grep -Eiq "^[[:space:]]*($GONE)" $CONFFILE; then
           echo
           echo 1>&2 " Apache 1.3 configuration directives found"
           echo 1>&2 " please read /usr/share/doc/httpd-2.0.40/migration.html"
           failure "Apache 1.3 config directives test"
start() {
    echo -n $"Starting $prog: "
    check13 || exit 1
# Start httpd as a daemon.
    daemon $httpd $OPTIONS
    RETVAL=$?
    echo
    [ $RETVAL = 0 ] && touch /var/lock/subsys/httpd
    return $RETVAL
}
stop() {
    echo -n $"Stopping $prog: "
# Stop httpd process.
    killproc $httpd
    RETVAL=$?
    echo
    [ $RETVAL = 0 ] && rm -f /var/lock/subsys/httpd /var/run/httpd.pid
}
reload() {
    echo -n $"Reloading $prog: "
    check13 || exit 1
# Send SIGHUP signal to httpd process (it causes httpd to rescan the config file).
    killproc $httpd -HUP
    RETVAL=$?
    echo
}
# See how we were called.
case "$1" in
start)
    start
    ;;
stop)
    stop
    ;;
status)
    status $httpd
    RETVAL=$?
    ;;
restart)
    stop
    start
    ;;
condrestart)
    if [ -f /var/run/httpd.pid ] ; then
           stop
           start
    fi
    ;;
reload)
    reload
    ;;
graceful|help|configtest|fullstatus)
    $apachectl $@
                                                                        
                                                                        
    RETVAL=$?
    ;;
*)
    echo $"Usage: $prog {start|stop|restart|condrestart|reload|status|fullstatus|graceful\
|help|configtest}"
    exit 1
esac
exit $RETVAL

Vari comandi utilizzati nello script riportato, come daemon e killproc, sono funzioni definite nel file /etc/rc.d/init.d/functions.

Il sistema di avvio automatico dei daemon, ovvero la creazione degli opportuni symbolic link che fanno riferimento ai relativi script di controllo dei servizi, è generalmente gestito da opportune applicazioni come chkconfig (man page chkconfig(8)).

____________________________________________________________________

Comando: chkconfig
Path: /sbin/chkconfig

SINTASSI  
$ chkconfig [option] [name {on|off|reset}]  
DESCRIZIONE

Se sulla riga di comando non viene specificato nessun argomento, viene visualizzato un aiuto sommario di chkconfig. ____________________________________________

Affinché un servizio sia gestibile da chkconfig, è necessario che lo script di gestione del daemon relativo (situato generalmente nella directory /etc/rc.d/init.d) contenga delle apposite righe di commento. In particolare una riga del file deve avere la seguente sintassi

 
# chkconfig: def_runlevel start_level stop_level  
dove

In genere, più elevato è il valore di start_level, più è basso quello di stop_level e viceversa.

Le righe successive contengono generalmente un commento che descrive il servizio gestito dallo script. Il commento può essere esteso su più righe per mezzo del carattere di continuazione di riga utilizzato dalla shell ‘\’ (backslash continuation).

Un esempio delle prime righe di uno script di gestione di un daemon è riportato di seguito (tratto dallo script di gestione dei numeri pseudocasuali)

 

# chkconfig: 2345 20 80
# description: Saves and restores system entropy pool for \
#              higher quality random number generation.
                                                                        
                                                                        
 
Oltre a chkconfig, esistono altri comandi come ntsysv (man page ntsysv(8)) (ed altri, forniti con le varie distribuzioni di GNU/Linux), che presentano un’interfaccia più agevole per l’utente.

____________________________________________________________________

Comando: ntsysv
Path: /usr/sbin/ntsysv

SINTASSI  
$ ntsysv [option]  
DESCRIZIONE

Il valore di ritorno (exit status) di ntsysv è riportato nella tab. 2.5.


|-Valore-|Significato-----------------|
|---0---|Operazione-conclusa correttamente.
|   1   |Operazione annullata dall’utente.  |
----2----Si`e verificato un-errore.-------

Tabella 2.5: Exit status di ntsysv.

__________________________________________________________________________________________________________

  2.7.1 Il comando service
  2.7.2 inetd e xinetd