Cette procédure décrit le passage d'une Ubuntu Breezy (5.10) avec un seul disque système à une plate-forme avec deux disques systèmes en miroir (raid1), en utilisant mdadm pour la gestion des metadevices et grub comme bootloader.

La procédure est décrite pour un environnement de type Debian/Ubuntu, mais devrait s'appliquer sans soucis sur une autre distribution.

Attention : ce document n'est qu'une synthèse de mon expérience personnelle sur le sujet. Je ne peux aucunement être tenu responsable des conséquences de l'utilisation, correcte ou non, des informations exposées ici. Je ne répondrai pas non plus aux demandes directes d'assistance!

Aperçu des opérations

  • Vérification de la présence des modules nécessaires
  • Ajout physique du nouveau (second) disque
  • Copie de la table des partitions de l'ancien vers le nouveau disque
  • Changement des flags partitions sur le nouveau disque
  • Création des métadevices sur le nouveau disque
  • Création des filesystems sur les métadevices
  • Copie des données de l'ancien disque sur les nouveaux filesystems
  • Modification de la fstab sur le nouveau filesystem root
  • Création de l'initrd
  • Modification du menu.lst de grub et installation sur les deux disques
  • Rebooter sur le nouveau disque seul pour valider
  • Attacher l'ancien disque au miroir
  • Mieux dormir la nuit en sachant que son serveur préféré ne mourra pas au premier crash disque!

Vérification de la présence des modules nécessaires

Vérifier la présence des modules md et raid1 :

# lsmod | egrep "md|raid1"

S'ils manquent, vérifier leur présence en les chargeant :

# modprobe md # modprobe raid1

Vérifier que les modules sont bien reconnus :

# cat /proc/mdstat Personalities : [raid1] read_ahead not set unused devices:

Vérifier également la présence du binaire mdadm. S'il manque, l'installer avec synaptic ou apt-get :

# apt-get install mdadm

Ajout du nouveau disque

L'idéal est d'ajouter un disque de même modèle que le disque existant, mais ce n'est pas strictement nécessaire. L'essentiel est d'avoir la place de reproduire les partitions existantes sur le nouveau disque!

Chez moi, le disque d'origine était /dev/hda, et le nouveau est /dev/hdd, ce sont donc les devices que j'utiliserai dans les exemples de ce mini-guide.

Copie de la table des partitions

Puisqu'on souhaite garder la configuration existante de la machine, on va conserver le partitionnement existant pour servir de base aux métadevices. On va donc copier la table des partitions de l'ancien disque sur le nouveau, par exemple avec sfdisk :

# sfdisk -d /dev/hda | sfdisk /dev/hdd

Chez moi, les partitions d'origines sont les suivantes, encore une fois, je les utiliserai comme exemples :

  • /dev/hda1 = /
  • /dev/hda2 = swap
  • /dev/hda3 = /home

Modification des flags des partitions

Pour que l'ensemble fonctionne correctement, il faut annoncer au système que les types de partitions ont changé. On va donc éditer la table des partitions du nouveau disque et déclarer chaque partition comme étant de type raid autodetect. Le code hexadécimal correspondant est fd.

# sfdisk -c /dev/hdd 1 fd # sfdisk -c /dev/hdd 2 fd # sfdisk -c /dev/hdd 3 fd

Cela peut bien entendu aussi se faire avec fdisk (option t pour changer les flags des partitions).

Création des métadevices

Il est maintenant temps de créer les métadevices, c'est-à-dire les devices raid qui s'appuient sur des devices physiques. Pour cette création, on va s'appuyer sur le second disque, /dev/hdd, et annoncer à mdadm que l'autre pan du miroir est manquant, ce qui nous permet de conserver les données du premier disque /dev/hda.

# mdadm -C /dev/md0 --level=1 --raid-devices=2 /dev/hdd1 missing # mdadm -C /dev/md1 --level=1 --raid-devices=2 /dev/hdd2 missing # mdadm -C /dev/md2 --level=1 --raid-devices=2 /dev/hdd3 missing

Création des filesystems

On peut maintenant recréer les filesystems sur les nouveaux volumes.

# mkfs -t ext3 /dev/md0 # mkfs -t ext3 /dev/md2 # mkswap /dev/md1

Recopie du système existant

A ce stade-là, nous sommes toujours sur le système d'origine, avec en particulier un root filesystem sur /dev/hda1. Nous allons donc monter les nouveaux filesystems et y recopier les données actuelles.

# mkdir /newroot # mount /dev/md0 /newroot # cd / ; find . -xdev | cpio -pmd /newroot/ # mount /dev/md2 /newroot/home # cd /home ; find . -xdev | cpio -pmd /newroot/home/

Vous pouvez bien sûr utiliser un autre moyen de copie, cp et tar fonctionnent parfaitement aussi.

Note : si vous vous demandez pourquoi il faut créer un nouveau filesystem et y recopier les données existantes au lieu de simplement créer un métadevice "autour" de la partition existante, c'est parce que mdadm utilise le début de la partition physique pour stocker ses propres métadonnées, et il a donc besoin de se réserver cet espace, ce qu'il fait à la création. Sur la partition existante, cet espace était déjà occupé par des données.

Modification de la nouvelle fstab

Sur notre tout nouveau (futur) filesystem root, on va modifier la fstab pour utiliser les métadevices.

# vi /newroot/etc/fstab
    • /dev/hda1 devient /dev/md0
    • /dev/hda2 devient /dev/md1
    • /dev/hda3 devient /dev/md2

Création d'un initrd

Attention : cette section ne décrit pas le téléchargement et la recompilation d'un noyau. Il vous faudra donc un noyau raisonnablement récent. J'ai fait l'opération avec un 2.6.12, mais tant que vous avez le support du module md et du module raid1, ça devrait pouvoir fonctionner.

L'initrd (INIT RamDisk) est lu et chargé en mémoire par le noyau au début du processus de boot, avant que le filesystem root définitif ne soit accessible. Il permet de fournir un certain nombre de fonctionnalités supplémentaires non présentes dans le noyau, typiquement sous forme de modules. Puisqu'il est spécifique à un noyau donné, il est généralement recréé à chaque upgrade de vos paquets kernel, attention donc à regénérer un initrd lorsque vous mettez à jour le noyau!

Nous allons donc recréer un initrd en forçant le chargement du module raid1, et surtout en lui spécifiant explicitement le root filesystem à utiliser. En effet, le mkinitrd Debian va par défaut utiliser le root filesystem déclaré dans la fstab courante, soit /dev/hda1, ce qui nous provoquerait un beau panic lors du reboot si le filesystem en question n'existait plus!

# vi /etc/mkinitrd/modules
  • ajouter une ligne raid1
# vi /etc/mkinitrd/mkinitrd.conf
  • remplacer ROOT=probe par ROOT=/dev/md0
# mkinitrd -o /boot/initrd.img-.raid

La version du noyau est tout simplement celle du package kernel utilisé. Donc chez moi, avec un noyau 2.6.12-10 pour i386 :

# mkinitrd -o /boot/initrd.img-2.6.12-10-i386.raid

Notons que ces manipulations viennent d'être effectuées sur /dev/hda1, il faut donc les copier sur notre nouveau filesystem.

# cp -r /etc/mkinitrd /newroot/etc # cp /boot/initrd.img-.raid /newroot/boot

Mise à jour de grub

Il est temps de déclarer notre nouveau filesystem dans le bootloader.

# vi /boot/grub/menu.lst

Ajoutons une entrée :

title Ubuntu, kernel 2.6.12 sur /dev/md0 root (hd0,0) kernel /boot/vmlinuz-2.6.12-10-386 root=/dev/md0 md=0,/dev/hda1,/dev/hdd1 ro quiet initrd /boot/initrd.img-2.6.12-10-386.raid boot

Encore une fois, la modification étant faite sur l'ancien filesystem, on la recopie sur le nouveau (on aurait aussi pu se contenter de la faire sur le nouveau et passer le /newroot/boot/grub/menu.lst en paramètre à grub-install, mais je préfère avoir la même version du fichier des deux côtés de toute façon)

# cp /boot/grub/menu.lst /newroot/boot/grub/menu.lst

Notre configuration étant maintenant au point, il est temps de l'installer.

# grub-install /dev/hda1

Pour ce qui est du second disque, on va utiliser une petite astuce : nous voulons être capables de booter dessus si par hasard le premier est mort. Or, le premier disque détecté par le BIOS se voit affecter par grub l'identifiant hd0, le suivant hd1, etc. Il faut donc que le second disque (/dev/hdd) croie être hd0, pour pouvoir booter en l'absence du vrai hd0 (/dev/hda). Grub permet de faire ça très simplement :

# grub grub> device (hd0) /dev/hdd grub> root (hd0,0) grub> setup (hd0) grub> quit

Test de la configuration

Voilà, nous avons maintenant en plus de notre disque /dev/hda un disque /dev/hdd sur lequel nous avons construit des métadevices, recopié notre système, et que grub sait maintenant booter. Avant d'intégrer notre ancien disque au miroir (et donc d'écraser ses données), validons quand même la configuration.

Pour ce faire, rien de plus simple : on arrête le PC, et on débranche l'ancien disque. Le nouveau disque se retrouve donc seul, s'il boote correctement c'est que tout va bien.

S'il ne boote pas, remettre l'ancien pour rebooter sur la conf existante, et vérifier qu'on n'a pas oublié d'étape.

Incorporation de l'ancien disque

Puisque tout va bien, il est temps d'intégrer l'ancien disque, pour avoir réellement un miroir capable de supporter la perte d'un disque!

Rien de plus simple :

# mdadm -a /dev/md0 /dev/hda1 # mdadm -a /dev/md1 /dev/hda2 # mdadm -a /dev/md2 /dev/hda3

Le système va maintenant resynchroniser les données sur /dev/hda (comprendre, écraser tout ce qui s'y trouve à partir des données des métadevices).

Pour suivre l'avancement de la resynchronisation :

# cat /proc/mdstat

Une fois la resynchronisation terminée, ca y est, votre système est prêt!

Note : certaines personnes recommandent de refaire l'initrd à ce stade, mais je ne suis pas certain de l'utilité de cette démarche, et je n'ai pas fait de tests poussés sur le sujet. Mais étant donné que ça ne prend que quelques secondes, il n'y pas vraiment de raisons de s'en priver!