Démarrage du système

La personnalisation du processus de démarrage (boot) implique de comprendre comment les scripts de démarrage sont appelés. Ce chapitre décrit également les problèmes communs que vous pourrez rencontrer au cours des différentes étapes du processus de démarrage ainsi que des techniques de récupération. Enfin nous focaliserons notre attention sur le chargement du disque virtuel en mémoire initrd au démarrage du système. Cela nous permettra de décider quand la création d'un disque virtuel en mémoire est nécessaire.

État : {relect}

Retour au document principal

Pré-requis

Personnaliser le processus de Boot

Présentation d'init

Afin d'éviter que les processus lancés par les utilisateurs interfèrent avec le noyau, deux espaces de mémoire distinct ont été définis : l'espace mémoire du noyau et l'espace mémoire utilisateur. Le processus init est le premier programme lancé dans l'espace utilisateur.

init est donc le processus père de tous les processus. Le fichier de configuration de init est : /etc/inittab

Les niveaux d'exécution (runlevels)

Les niveaux d'exécution déterminent quels processus doivent fonctionner ensemble. Tous les processus peuvent être démarrés ou stoppés à un niveau d'exécution donné par un script (appelé script init ou script rc) dans /etc/rc.d/init.d (RedHat).

Liste des scripts RC sur un système standard :

anacron halt kudzu ntpd rusersd syslog ypxfrd apmd identd lpd portmap rwalld vncserver
atd ipchains netfs radvd rwhod xfs autofs iptables network random sendmail xinetd
crond kdcrotate nfs rawdevices single ypbind functions keytable nfslock rhnsd snmpd yppasswdd
gpm killall nscd rstatd sshd ypserv

La sélection d'un processus qui doit être lancé ou stoppé dans un niveau d'exécution donné est effectuée par la création de liens symboliques dans le répertoire /etc/rc.d/rcN.d/ ou N est le niveau d'exécution.

Exemple 1 : Sélectionner le processus httpd pour le niveau d'exécution 3

ln -s /etc/rc.d/init.d/httpd /etc/rc.d/rc3.d/S85httpd

Information : Le nom du lien est le même que celui du processus mais précédé par un S pour start et un nombre représentant l'ordre d'exécution.

Exemple 2 : Stopper le processus httpd pour le niveau d'exécution 3

rm /etc/rc.d/rc3.d/S85httpd
ln -s /etc/rc.d/init.d/httpd /etc/rc.d/rc3.d/K15httpd

Cette fois, le nom de la ligne débute avec un K pour Kill pour s'assurer que le processus est arrêté lors du passage d'un niveau d'exécution a l'autre.

Lancement des scripts locaux

Nous voulons lancer un script a un niveau d'exécution donné . Notre script sera appelé printtotty10 et affichera simplement le message donné en argument a /dev/tty10.

/bin/printotty10

# !/bin/bash
echo $1 > /dev/tty10
  1. Une possibilité d'avoir le script lancé a un niveau d'exécution spécifique est d'ajouter une ligne dans /etc/inittab comme :

pr10:3:once:/bin/printtotty10 “Printtotty a été lancé dans inittab”

Ce n'est pas toujours la meilleurs solution. Que se passe t-il si vous devez lancer beaucoup de scripts ? Le fichier inittab sera illisible.

  1. Nous allons écrire un rc-script personnalisé. Nous suivons la méthode pour appeler le même nom que l'outil que nous voulons lancer.

/etc/rc.d/init.d/printtotty10

# !/bin/sh
# chkconfig: 345 85 15
# description: Cette ligne est necessaire au fonctionnement de chkconfig... \
# Ce script affiche un message sur /dev/tty10
# Tout d'abord, recuperons des fonctions pre-definies comme echo_success()
./etc/rc.d/init.d/functions

start() {
        echo -n "lancement de printtotty10"
        /bin/printtotty10 "printtotty10 a ete lance a partir d un script rc"
        echo_success
        echo
}

stop() {
       echo -n "Arret de custom-rc"
       /bin/printtotty10 "Le script personnalise a ete arrete"
       echo_success
       echo
}
case "$1" in
  start)
       start;;
  stop)
       stop;;
esac
exit 0
  1. Le script printtotty10 peut être lancé au moment du démarrage (boot) en plaçant la commande dans /etc/rc.d/rc.local. Le script rc.local est le dernier script rc a être lancé.

Information: lorsque vous voulez configurer un serveur Linux comme un routeur, il est possible d'activer l'ip-forwarding au moment du démarrage par l'ajout de la ligne suivante dans rc.local :

echo 1 > /proc/sys/net/ipv4/ip_forward

Cependant il est mieux d'utiliser le mécanisme de sysctl pour activer l'ip-forwarding chaque fois que le réseau est démarré. On le fait en ajoutant la ligne suivante dans /etc/sysctl.conf :

net.ipv4.ip_forward = 1

2. La récupération du système

Quand un système se bloque et ne parvient pas à redémarrer, il est nécessaire de modifier le processus de démarrage normal. Cette section décrit quelques solutions correspondant à des problèmes qui peuvent se produire aux étapes suivantes du processus de démarrage.

Étape de démarrage

Type d'erreur

Solution suggérée|

INIT

Systeme de fichier Racine corrompu ou une erreur dans le fichier /etc/fstab

Utiliser le prompt en utilisateur root

Échec de chargement d'un module du Noyau ou d'un script RC

Redéfinition d'INIT ( voire page 23) ou utiliser un runlevel alternatif

KERNEL

Panique du Noyau (Kernel panic)

(Voire page 24)

Erreur d'initialisation materiel ( souvent avec des anciens Noyaux sur les dernières carte mères)

Mettre le paramètre approprié sur le chargeur de démarrage - acpi=off. (p.27)

BOOT LOADER

Non installé ou endommagé

Utiliser un disque de secours ou un disque de démarrage (voire p.24)

Redéfinition de l'étape d'init

Cela est nécessaire si le processus de démarrage échoue à cause d'un script d'initialisation défectueux. Une fois que le noyau a réussit à trouver le système de fichiers racine, il va essayer de lancer /sbin/init. Mais le noyau peut être chargé d'exécuter un shell à la place qui nous permettra d'avoir accès au système avant que les services soit démarrés.

Au démarrage de GRUB ou LILO, a l'invite de commande ajouter le paramètre de noyau suivants:

init=/bin/bash

A la fin de l'étape de démarrage du Noyau vous devrez obtenir un invite de commande bash. Un accès en lecture / écriture sur le système de fichier racine est obtenu de la manières suivante :

mount /proc
mount -o remount,rw /

Erreur a la fin de l'étape du Noyau

. Si le Noyau ne peut monter le système de fichier racine il affichera le message suivant :

Kernel panic: VFS: Unable to mount root fs on 03:05

Le nombre 03 est le numéro majeur pour le premier contrôleur IDE, et 05 est la 5eme partition sur le disque. Le problème est que le Noyau et ses modules d'accès au disque sont absent .

Nous devons pour démarrer le système utiliser une méthode alternative. La prochaine difficulté consiste à créer un initrd personnalisé et de l'utiliser pour le processus de démarrage normal.

Question: Dans le cas précèdent le disque n'est pas un disque SCSI , qu'est ce qui pourrait avoir causé le problème ?

. Si le mauvais disque racine est transmis au Noyau par le chargeur de démarrage ( LILO ou GRUB ) l'étape INIT ne pourra pas démarrer depuis /sbin/init qui sera manquant.

Kernel Panic: No init found. Try passing init= option to kernel

Encore une fois nous avons besoin de démarrer le système en utilisant une méthode différente, puis modifier le fichier de configuration du chargeur de démarrage (pour dire au Noyau d'utiliser un autre disque comme système de fichier racine), et redémarrage.

Dans les deux scénarios ci-dessus, il n'est pas toujours nécessaire d'utiliser une disquette de secours. En fait, c'est souvent la cas d'un démarrage avec un Noyau configuré proprement. Mais qu'advient-il si l'on ne dispose pas de l'option? Que ce passe t-il si le chargeur de démarrage a été configuré avec le mauvais Noyau n'utilisant pas l'initrd ou essayant de monter le mauvais système de fichier racine ?

Ce qui nous amène a la cause la plus proche possible du problème de démarrage.

Chargeur de démarrage mal configuré

A cette étape nous avons besoin d'utiliser une méthode de secours pour démarrer le système.

Utilisation d'un disque de secours

Nous savons déjà via le LPI 101 que tout CD de distribution Linux peut être utiliser pour démarrer un système en mode secours. L'avantage de ces CD c'est qu'ils fonctionnent sur tout type de système Linux.

Le processus de secours peut être ventilés dans les étapes suivantes :

1. Démarrer depuis le CD et trouver les options appropriées ( souvent appelé rescue ou boot an existing system( démarrer sur un système existant)).

2. Dans la plupart des cas le disque racine pour un système existant est automatiquement détecté et monté dans un sous répertoire du périphérique racine (en RAM).

3. Si le point de montage est appelé /system il peut devenir le système de fichier racine par notre shell courant en tapant :

chroot /system

4. A cette étape l'ensemble du système est disponible et le chargeur de démarrage peut être réparé.

Quand un chargeur de démarrage est mal configuré on peut utiliser un chargeur de démarrage de remplacement (sur une disquette ou un CD). Ce chargeur de démarrage va charger le Noyau avec lequel est configuré l'utilisation du périphérique racine sur le disque.

Cette méthode est appelé un disque de démarrage et peut être utilisé pour récupérer un système spécifique.

Disque de démarrage personnalisé 1:

Nous avons besoins d'une disquette avec une image du Noyau Linux qui peut démarrer, et cette image doit savoir ou trouver le périphérique racine sur le disque.

En supposant que nous utilisons une disquette DOS préformaté, la commande suivante va créer une disquette bootable avec lequel nous lancerons une image du Noyau Linux :

dd if=/boot/vmlinuz of=/dev/fd0

Ensuite, rdev est utilisé pour dire au Noyau ou est le périphérique racine. La commande doit être lancer sur le système que nous tenons a protéger et la disquette avec le noyau doit etre dans le lecteur.

rdev /dev/fd0 /dev/hda2

Disque de démarrage personnalisé 2:

Le paquet syslinux installe un binaire appelé syslinux qui peut être utilisé pour créer une disquette bootable. La procédure (prise dans la documentation du paquet) se présente comme ceci :

1. Faire une disquette DOS bootable. Cela peut se faire par l'option spécifique /s lors du formatage du disque en DOS, ou par le lancement de la commande SYS DOS ( cela peut se faire en vertu de DOSEMU si DOSEMU a directement accès au périphérique):

format a: /S

sys a:

2.Démarrage Linux. Copier le secteur de démarrage (boot) DOS a partir du disque dans n fichier :

dd if=/dev/fd0 of=dos.bss bs=512 count=1

3. Lancer SYSLINUX sur le disque:

syslinux /dev/fd0

4.Monter le disque et copier le secteur de démarrage DOS a partir du fichier. Le fichier *doit* avoir une extension .bss :

mount -t msdos /dev/fd0 /mnt
cp dos.bss /mnt

5.Copier l'image(s) du Noyau Linux,initrd(s), etc .. dans le disque, et créer/éditer syslinux.cfg et les fichiers d'aides si vous le désirez :

Par exemple si vous avez un disque racine /dev/sda1, syslinux.cfg serait :

DEFAULT linux
LABEL linux
KERNEL vmlinuz
APPEND initrd=initrd.img root=/dev/sda1

puis

cp /boot/vmlinuz /mnt
cp /boot/initrd.img /mnt

6. Démonter le disque

umount /mnt

Informations

Bien que SYSLINUX peut être installer sur un CD , il est recommandé d'utiliser ISOLINUX a la place ( voire p.53).

Paramètre du Noyau par le chargeur de démarrage

load_ramdisk=n

Si n est égale a 1 ca charge un disque virtuel, par défaut c'est 0

prompt_ramdisk=n

Si n est égale a 1 on vous invite a insérer une disquette contenant un disque virtuel

nosmp ou maxcpus=N

Désactive ou limite le nombre de CPU (processeur)

apm=off

Désactive APM, parfois nécessaire pour démarrer a partir d'une carte mère non supportée

init=

Par défaut /sbin/init mais peut etre un shell ou processus alternatif

root=

Définit le périphérique racine ( peut être définit par rdev)

mem=

Définit une taille de RAM utilisable

vga=

Change le type de vidéo pour la console ( peut être définit avec rdev)

*Le manuelle de rdev dit : L'utilitaire rdev, lorsqu'il est utilisé autrement que pour trouver un nom pour le périphérique racine actuel, est une ancienne astuce qui fonctionne en modifiant l'image du noyau à un offset avec un numéro magique. Il ne fonctionne pas sur d'autres architectures que i386. Son utilisation est fortement déconseillée. Utilisez un chargeur de démarrage comme SysLinux ou LILO .

Dépannage de LILO

Quand on installe LILO le chargeur de démarrage,/sbin/lilo,il va sauvegarder le chargeur de démarrage existant.

Par exemple si vous installez LILO sur une disquette, le chargeur de démarrage original sera sauvegarder dans /boot/boot.0200

Idem lorsqu'on change le chargeur de démarrage sur un disque IDE ou un SCSI le fichier sera appelé respectivement boot.0300 et boot.0800. Le chargeur de démarrage original peut être restauré avec :

lilo -u

Par défaut la deuxième étape de LILO est appelé /boot/boot.b et quand il est chargé avec succès il vous invite a un prompt avec boot:.

Voici les erreurs possibles lors de la phase de démarrage (extrait du README LILO)

.nothing : LILO n'est pas installé ou la partition n'est pas active 

.L : La première étape du chargeur de démarrage a été chargé mais pas la deuxième. 

.LI : La seconde étape du chargeur de démarrage a été chargé mais n'est pas valide pour être exécuter. 
''This could be cause if /boot/boot.b moved and /sbin/lilo wasn't rerun''

.LIL La seconde étape du chargeur de démarrage a été exécuté, mais il ne peut pas chargé la table de description situé dans le fichier map ou la seconde étape du chargeur de démarrage a été chargé avec une addresse incorrecte. 
''This could be cause if /boot/boot.b moved and /sbin/lilo wasn't rerun.''

.LIL- La table de description est corrompu
''This could be cause if /boot/map moved and /sbin/lilo wasn't rerun.''

.Scrolling 010101 errors Cela se produit lorsque le chargeur d'amorçage est situé sur un périphérique esclave 

initrd personnalisé

Dans la plupart des cas un initrd personnalisé nécessite la commande mkinitrd qui déterminera les modules du Noyau nécessaire pour supporter les périphériques block et les systèmes de fichier utiliser sur le périphérique racine.

Le script Mkinitrd

Les éléments suivants sont utilisées dans le script mkinitrd pour déterminer les informations critiques sur le périphérique racine et les systèmes de fichiers.

-Le système de fichier racine :
L'utilisation de "/etc/fstab" le script détermine quel système de fichier est utilisé sur le périphérique racine et le module correspondant ( par example "ext3" ou "Xfs" ).

-RAID Logiciel :
L'utilisation de "/etc/raidtab" , le script "Mkinitrd" en déduit le nom du Raid pour démarrer tous les disques.

-Périphérique Racine LVM
Depuis le périphérique racine "$rootdev" est déterminé dans "/etc/fstab", le Nombre majeur est obtenu depuis la ligne suivante :

''root_major=$(/bin/ls -l $rootdev | awk '{ print $5 }')''

Si cela correspond a un volume logique, la commande des volumes logique sont copiés dans la ram disk .

Le script "mkinitrd" va transférer tous les outils et modules nécessaires a monter un système de fichier en tant que dispositif de boucle sur un répertoire temporaire. Une fois démonté, le fichier est compressé et est utilisé comme un initrd.

Syntaxes

La syntaxe de mkinitrd pour Debian et les autres distributions sont différentes.

Mkinitrd pour Debian

Options:
 -d confdir Spécifie un répertoire de configuration alternatif.
 -k Garde le répertoire temporaire utiliser pour construire l'image.
 -m command Défini la commande pour créer une image initrd.
 -o outfile Écrit le fichier de sortie.
 -r root Écrit les paramètres ROOT dans mkinitrd.conf

Exemple: mkinitrd -o /boot/initrd-test-$(uname -r).img

-

Mkinitrd pour Mandriva,RedHat,Suse/Novell

usage: mkinitrd [--version] [-v] [-f] [--preload <module>]
[--omit-scsi-modules] [--omit-raid-modules] [--omit-lvm-modules]
[--with=<module>] [--image-version] [--fstab=<fstab>] [--nocompress]
[--builtin=<module>] [--nopivot] <initrd-image> <kernel-version>

Exemple: mkinitrd /boot/initrd-test-2.2.5-15.img 2.2.5-15

Exemple

Comme exemple nous allons copier le contenu d'un initrd existant vers un nouveau initrd et changer le système de fichier d'un ext3 vers un ext2 ..

cp /boot/initrd-your-kernel-version.img /tmp/initrd.img.gz
gunzip /tmp/initrd.img.gz

mkdir /mnt/current
mount -o loop /tmp/initrd.img /mnt/current

df -k /mnt/current
Filesystem 1K-blocks Used Available Use% Mounted on
/tmp/initrd.img 317 191 126 61%
/mnt/current

dd if=/dev/zero of=/tmp/initrd-new.img bs=1K count=317

df -i /mnt/current
Filesystem Inodes IUsed IFree IUse% Mounted on
/tmp/initrd.img 48 33 15 69% /mnt/current

mke2fs -F -m 0 -N 48 /tmp/initrd-new.img

mkdir /mnt/new
mount -o loop /tmp/initrd-new.img /mnt/new
(cd /mnt/current/; tar cf - .) | (cd /mnt/new; tar xf -)

gzip /tmp/initrd-new.img ; mv /tmp/initrd-new.img.gz /boot/initrdtest.img

Ou

gzip < /tmp/initrd-new.img > /boot/initrd-test.img

Extrait grub.conf

title linux (2.4.22)
    root (hd0,1)
    kernel /vmlinuz-2.4.22 ro root=LABEL=/
    initrd /initrd-2.4.22.img
title broken?
    root (hd0,1)
    kernel /vmlinuz-2.4.22-1.2115.nptl ro root=LABEL=/
    initrd /initrd-new.img

Extrait lilo.conf

image=/boot/vmlinuz-2.4.22-1.2115.nptl
    initrd=/boot/initrd-2.4.22.img
    read-only
    label=linux
    append=”root=LABEL=/”
image=/boot/vmlinuz-2.4.22-1.2115.nptl
    initrd=/boot/initrd-new.img
    read-only
    label=broken?
    append=”root=LABEL=/”