6.3. Notion de niveau d'exécution et amorçage du système

La plupart des systèmes Unix utilisent la notion de niveau d'exécution. Un niveau d'exécution est un mode de fonctionnement dans lequel un certain nombre de services sont accessibles. En général, il existe 7 niveaux d'exécution, dont seulement trois fournissent des services bien définis pour quasiment toutes les distributions de Linux.

Le niveau 0 correspond à l'arrêt du système, et aucun service n'est disponible (à part le redémarrage de la machine bien entendu...). Le fait de passer dans le niveau d'exécution 0 correspond donc à arrêter le système. Le niveau 6 correspond au redémarrage de la machine. Le fait de passer dans le niveau d'exécution 6 revient donc à arrêter et à redémarrer la machine. Le niveau d'exécution 1 correspond au mode de fonctionnement monoutilisateur (encore appelé mode de maintenance). Ce niveau d'exécution fournit les services de base pour un seul utilisateur (normalement l'administrateur du système). Dans ce niveau d'exécution, l'administrateur peut changer la configuration et effectuer les tâches de maintenance les plus critiques (par exemple, vérifier le système de fichiers racine). La signification des autres niveaux d'exécution dépend de la distribution que vous utilisez mais en général le niveau d'exécution 2 correspond au mode multiutilisateur avec réseau mais sans XWindow, et le niveau d'exécution 3 ou 4 correspond au mode multiutilisateur avec login graphique sous XWindow. Les autres niveaux restent à votre disposition.

Le programme en charge de gérer les niveaux d'exécution est le programme init. Ce programme est le premier programme lancé par le noyau après qu'il a été chargé et démarré par le gestionnaire d'amorçage (à savoir, en général, LILO ou le GRUB). Ce programme ne peut pas être détruit ou arrêté, et c'est réellement le processus père de tous les autres dans le système. Le rôle fondamental d'init est de gérer les changements de niveau d'exécution, mais il s'occupe également des tâches de base concernant la gestion des autres processus. En particulier, il permet de supprimer les processus zombies.

Note : Un processus « zombie » est un processus qui vient de se terminer et dont aucun processus n'a lu le code de retour. De tels processus apparaissent généralement lorsque leur processus père se termine avant eux car, généralement, c'est toujours le processus père qui lit le code de retour de ses processus fils.

Il suffit d'utiliser la syntaxe suivante pour forcer le changement de niveau d'exécution :

init niveau
niveau est le niveau d'exécution à atteindre. Cela dit, cette manière de faire est assez rare, car en général on n'a pas besoin de changer de niveau d'exécution, sauf pour arrêter et redémarrer la machine. Mais pour ces opérations, les commandes shutdown, halt et reboot sont déjà disponibles.

Le niveau d'exécution dans lequel le système doit se placer lors de son démarrage peut également être précisé en paramètre du noyau lors du démarrage. Vous devrez donc utiliser une commande semblable à celle-ci : LILO boot:linux niveau si vous utilisez LILO, ou kernel noyau niveau si vous utilisez le GRUB pour démarrer le noyau noyau Linux dans le niveau d'exécution niveau. Ainsi, pour passer en mode monoutilisateur (c'est-à-dire le mode de maintenance), il suffit de taper la commande suivante à l'amorçage de LILO :

LILO boot:linux 1

ou la commande suivante sur la ligne de commande interactive du GRUB :

kernel /boot/vmlinuz 1

Note : Il est également possible d'utiliser le paramètre single, qui est synonyme du niveau d'exécution 1.

Le comportement d'init est défini dans le fichier de configuration /etc/inittab. Ce fichier contient la description des niveaux d'exécution, le niveau par défaut dans lequel le système se place au démarrage, et les actions qu'init doit effectuer lorsque certains événements arrivent. En particulier, il est indiqué quels sont les scripts qui doivent être exécutés lors du changement de niveau d'exécution. Il est fortement, mais alors très fortement déconseillé de toucher au fichier /etc/inittab pour des raisons bien évidentes. Vous trouverez de plus amples renseignements dans les pages de manuel d'init et d'inittab.

Lorsqu'on change de niveau d'exécution, ainsi qu'au démarrage du système, des scripts de configuration sont appelés. Comme on l'a vu, ces scripts sont spécifiés dans le fichier /etc/inittab. En général, ils sont tous placés dans le répertoire /etc/rc.d/ (ou /sbin/init.d/, selon votre distribution). Ce répertoire contient donc :

Le script appelé lors du démarrage du système est en général spécifié directement dans /etc/inittab. Vous pouvez y ajouter les commandes spécifiques à votre système, comme par exemple les commandes de configuration du matériel. Ce fichier n'est exécuté qu'une seule fois et est placé directement dans /etc/rc.d/ (ou dans /sbin/init.d/).

En revanche, les scripts appelés lors du changement de niveau d'exécution sont souvent placés dans des sous-répertoires du répertoire rc.d ou init.d. Ils sont classés à raison d'un répertoire par niveau d'exécution. Ces sous-répertoires portent le nom de rc0.d, rc1.d, rc2.d, etc. pour les différents niveaux d'exécution. En fait, un seul script est exécuté par init lorsqu'on change de niveau d'exécution, et ce script se charge d'exécuter les bons scripts dans les sous-répertoires de rc.d ou init.d. Classiquement, ce script principal est appelé avec le numéro du niveau d'exécution en paramètre, et il commence par appeler les scripts de sortie du niveau d'exécution courant, puis les scripts d'entrée dans le nouveau niveau d'exécution.

La distinction entre les scripts d'entrée et de sortie dans chaque répertoire rc?.d se fait par la première lettre du script. Sur certaines distributions, la lettre 'K' correspond aux scripts de sortie et la lettre 'S' au script d'entrée (ces deux lettres correspondent respectivement aux mots anglais « Kill » et « Start »). De plus, l'ordre dans lequel ces scripts doivent être exécutés est indiqué par le nombre suivant cette lettre dans le nom du script. Cela dit, ces conventions peuvent varier selon votre distribution. Consultez votre documentation pour plus de détails à ce sujet.

Il est assez courant que les répertoires rc?.d ne contiennent que des liens symboliques vers les fichiers de scripts, et que ceux-ci soient tous placés directement dans le répertoire /etc/rc.d/ (ou /sbin/init.d/). La raison en est qu'un même script peut être utilisé pour différents niveaux d'exécution, et qu'il n'a donc pas de raison d'être dans le répertoire d'un niveau plutôt que celui d'un autre.

De même, il est assez courant que chacun de ces scripts gère à la fois l'entrée et la sortie du niveau d'exécution, selon le paramètre qu'il reçoit lors de son appel. Parmi les paramètres les plus courants, on retrouve les suivants :

Ce sont les deux paramètres que le script de contrôle de changement de niveau d'exécution (celui appelé par init et enregistré dans /etc/inittab) utilisera lors de l'entrée et de la sortie du niveau d'exécution. Il existe d'autres paramètres, comme par exemple restart, pour redémarrer le service correspondant.

De cette manière, vous pouvez ajouter ou supprimer des services simplement dans chaque niveau d'exécution. Il suffit d'écrire un fichier script capable de prendre en paramètre l'action à réaliser sur le service (start ou stop), de le placer dans /etc/rc.d/ (ou /sbin/init.d/) et de créer les liens dans les sous-répertoires /etc/rc.d/rc?.d/ (ou /sbin/init.d/rc?.d/). Dès lors, votre service sera arrêté ou redémarré selon le niveau d'exécution dans lequel passera le système.

La rédaction des scripts shells de configuration dépasse largement le cadre de ce document, de même que la configuration du comportement du système à chaque changement de niveau d'exécution. La description qui était donnée ici permet simplement d'avoir une idée plus claire de la manière dont le système se comporte au démarrage et à l'arrêt. Consultez la documentation de votre distribution pour plus de détails à ce sujet.