Ma distribution de référence est la RedHat 4.2. Même si vous employez une autre distribution, vous ne devriez pas avoir trop de problèmes pour comprendre le fonctionnement général. Les exemples donnés ici ne sont que des exemples, et votre système peut varier en fonction de la distribution que vous avez, ainsi que sa version.
À la fin de la séquence de boot, le kernel va exécuter la commande /bin/init, qui va se charger de lancer certains services nécessaires (c'est-à-dire de placer le système dans un run level particulier). La première chose que cette commande va faire, est de scanner le fichier /etc/inittab. Ce fichier contient, entre autres, la définition du run level par défaut (cherchez la ligne qui contient initdefault)
Il y a différents run levels, qui correspondent chez moi à :
Un conseil : n'allez pas mettre 0 ou 6 comme run level : dès le boot, votre système se bloquerait, et vous devriez alors passer par la bidouille pour le restaurer.
Enfin, /bin/init peut être utilisé pour changer le run level actuel : un petit "init 6" mettra le système dans le run level 6 (et donc la machine reboote).
id:rstate:action:process
id est un identificateur, formés de deux caractères.
rstate est une suite de numéros de run level. Ces numéros indiquent dans quel run level on peut trouver ces processus. Si rstate vaut "1245", le process devra être tué si le run level devient 0, 3 ou 6. Suivant la valeur de action, le process sera lancé en debut de session (once), sera relancé s'il meurt (respawn), ...
process sera n'importe quelle commande shell valide (qui peut être lancée par 'exec') .
Un petit exemple : si vous êtes dans le run level 5 (mode multi-utilisateur avec X Window), essayez donc de tuer le process xdm. Il se relance automatiquement, ce qui est normal, vu que la ligne correspondante dans /etc/inittab est :
x:5:respawn:/usr/bin/X11/xdm -nodaemon
Dès qu'il est tué (et tant qu'on est dans le run level 5), il doit être relancé. Si vous modifiez le fichier /etc/inittab, vous pouvez demander à init de le relire : "init q". Sans cela, tout changement ne sera pris en compte que lors du boot suivant.
Remarquez aussi que lors de l'initialisation de la machine, un script est lancé : /etc/rc.d/rc.sysinit. Il contient les commandes pour mounter les partitions swap, vérifier l'intégrité des partitions (fsck), mounter les partitions non NFS, lancer le kerneld, ... Ce script n'est lancé qu'une seule fois, juste avant que init ne mette le système dans le run level correct. Pour cela, init vérifie l'entrée de /etc/inittab contenant le mot initdefault.Ensuite, il va lancer les commandes nécessaires pour faire passer le système dans le run level adéquat. Par exemple, chez moi, le run level par défaut est le 5. Dans mon fichier /etc/inittab, j'ai la ligne suivante :
l5:5:wait:/etc/rc.d/rc 5
C'est-à-dire qu'init va lancer, lorsqu'il passe dans le run level 5, la commande "/etc/rc.d/rc 5". Le script /etc/rc.d/rc est générique, c'est-à-dire que le traitement de chaque run level est le même. Ce traitement est défini dans la section suivante.
Je voudrais encore rajouter un petit commentaire par rapport aux run levels : on peut trouver des entrées dans /etc/inittab qui contiennent dans le champ rstate les valeurs a, b ou c. Il ne s'agit pas de nouveaux run levels, mais de pseudo run levels : ils permettent d'exécuter certaines commandes. Un petit "init a" va exécuter toutes les commandes ayant a dans le champ rstate.
K20nfs
K40snmpd
K90nfsfs
S01keytable
S10network
S30syslog
S40cron
S40portmap
S45pcmcia
S50inet
S60lpd.init
S60sendmail
S85gpm
S99local
Le changement de run level est fait de manière simple : on tue
les process qui ne doivent pas s'y trouver, et on lance les services présents
dans ce run level.
Les scripts commencant par un K (les K-scripts) sont les scripts appelés
pour tuer des processus : K20nfs est utilisé pour arrêter
le service NFS. Les scripts commencant par un S (les S-scripts) sont les
scripts qui lancent des services : S01keytable est le script qui
va charger la keytable correspondant à mon clavier.
Vous aurez remarqué que les scripts sont aussi formés d'un numéro. Ce numéro est utilisé pour séquencer (ordonner) leur lancement. Ainsi, dans l'exemple ci-dessus, lors du lancement des S-scripts, S01keytable sera lancé avant S10network, lui-même avant S30syslog, ... Notez qu'on peut avoir deux scripts ayant le même numéro : voyez S60lpd.init, et S60sendmail. En fait, pour simplifier le tout, il suffit de se dire que les scripts sont exécutés dans l'ordre alphabétique.
Une petite finesse : il y a, en plus des répertoires rc?.d, un répertoire init.d. C'est dans ce répertoire que sont réellement stockés les scripts des répertoires rc?.d. Ces derniers ne contiennent que des liens symboliques. Ainsi, /etc/rc.d/rc1.d/K90nfs et /etc/rc.d/rc2.d/K23nfs pointent tous deux vers le même fichier, à savoir /etc/rc.d/init.d/nfs.
Encore plus fort : un K-script et un S-script peuvent tous deux pointer
vers le même fichier, et avoir des comportements différents.
En fait, un script est appelé en lui passant un paramètre,
soit "start" s'il s'agit d'un S-script, soit "stop" (le 'K' est celui de
'Kill' : tuer) s'il s'agit d'un K-script. En fonction de ce paramètre,
le script réagit différemment :
/etc/rc.d/init.d/nfs, appelé avec le paramètre
"start", va lancer le service NFS, tandis que le même script, appelé
avec le paramètre "stop", arrêtera ce service :
# See how we were called.
case "$1" in
start)
# Start daemons.
echo -n "Starting NFS services: "
daemon rpc.mountd
daemon rpc.nfsd
echo
touch /var/lock/subsys/nfs
;;
stop)
# Stop daemons.
echo -n "Shutting down NFS services: "
killproc rpc.mountd
killproc rpc.nfsd
echo
rm -f /var/lock/subsys/nfs
;;
*)
echo "Usage: nfs {start|stop}"
exit 1
esac
Enfin, dans chaque run level, on trouve (en dernier dans l'ordre alphabétique) un script lançant les applications spécifiques à la machine (c'est un pointeur vers le fichier /etc/rc.d/rc.local). C'est de préférences dans ce fichier là qu'il faut mettre toutes les commandes spécifiques à tous les run levels (comme par exemple la gestion du clavier, si elle n'est pas lancée dans un autre script).