RAID software sous Linux
Avertissement: Ce document décrit une méthode exécutée il y a déjà un bon moment, et qui n'est donc plus très fraîche dans mon esprit. Je n'ai pas non plus sous la main les ordinateurs sur lesquels je l'ai appliquée, ni le matériel pour la reproduire et je n'exclus donc pas l'un ou l'autre oubli. Plus que d'habitude, vos neurones restent vos meilleurs alliés.
Le RAID (Redundant Array of Inexpensive Disks) consiste à combiner plusieurs disques durs de manière à ce qu'ils soient redondants et à ce que si l'un des disques casse, l'information soit toujours disponible et le système continue à tourner normalement. D'ordinaire, cela est géré par un matériel dédié, souvent conçu pour des disques SCSI. Cela reste donc fort cher. Même si l'on peut rencontrer dans les produits grand public des cartes-mères supportant le RAID, celles-ci ne proposent en fait qu'une assistance pour le démarrage, et laisse la gestion du RAID au logiciel. Il y a aussi plusieurs variantes du RAID: RAID1, RAID5 ... Ce document explique la mise en place et la réparation de tableaux RAID1 logiciels sous Linux. Une dernière note: tout cela ne dispense pas de faire des backups.
Le RAID1
Le RAID1 est la variante la plus simple du RAID: il s'agit d'un tableau de 2 ou plusieurs disques qui sont des copies conformes les uns des autres. Si un des disques lâche, l'information reste disponible sur les autres disques en attendant le remplacement du disque défectueux et la synchronisation du nouveau disque avec les disques intacts. On parle aussi, en RAID1, de disques miroirs. En RAID matériel, le RAID est géré au niveau des disques (chaque disque est un miroir des autres); en RAID logiciel, cette synchronisation se fait au niveau des partitions, ou plus généralement de périphériques de type bloc.
Si l'installeur de la distribution le gère, alors on peut le laisser faire; je vais ici décrire la migration d'un système installé sur un seul disque vers des tableaux RAID1 sur 2 partitions.
Pour ne pas se compliquer la tâche
Avoir deux disque rigoureusement identiques du point de vue géométrie: deux disques affichant la même taille peuvent en effet avoir des tailles légèrement différentes et un arrangement secteurs/cylindres différent. A défaut de disques parfaitement identiques, placer en début de disque la partition contenant le kernel (/ ou /boot) pourrait simplifier les choses en cas d'utilisation d'un bootloader ne connaissant pas les filesystems (ex: LILO).
Passage d'une partition simple en RAID
Partitionnement
Sur le deuxième disque dur (par exemple: /dev/hdc), encore vierge, recréer une table de partitions identique à celle du disque dur original (par exemple /dev/hda), mais changer le type des partitions créées à la valeur hexadécimale FD. Cette valeur permettra, avec un superbloc écrit lors de la création du tableau, au système d'apparier les partitions des tableaux.
Si les disques durs ont des géométries différentes, ce serait une coincidence heureuse de pouvoir faire des partitions identiques. Dans ce cas, il faut créer des partitions légèrement plus petites que les partitions originales. La raison sera expliquée plus bas.
A propos des blocs et des partitions
Attention, le calcul des tailles de partitions peut être trompeur: on cherche à faire des partitions avec des tailles précises, mais cela est impossible car les partitions doivent être alignées sur les cylindres du disque dur. A celà, il faut ajouter que la définition de bloc varie selon les contextes, et qu'il faut effectuer les opérations de conversion sans se tromper. On peut rencontrer 3 types de blocs:
- Le bloc de disque dur
- Ce bloc sert d'unité pour mesurer la taille des disques et des partitions. Il fait 512 bytes.
- Le bloc fdisk
- fdisk n'affiche pas des blocs de 512 bytes, mais de 1024; c'est plus facile à lire humainement, mais ne permet pas de représenter une partition avec un nombre impair de blocs. Dans ce cas, fdisk affiche un "+" après la valeur en kB pour représenter les 512 bytes manquants.
- Le bloc du filesystem
- Le filesystem manipule ses propres blocs. Par défaut, ext2/ext3 a une taille de bloc de 4kB, mais cela est configurable à la création du filesystem.
Lorsque l'on utilise la commande p de fdisk, il indique d'abord la géométrie du disque. On peut y voir combien de blocs compte un cylindre, et puis, pour chaque partition, le nombre de blocs qu'elle comporte. Comme les partitions ont un nombre entier de cylindres, l'utilisation de ces données sur le disque hda sont importantes pour calculer le nombre de cylindres à donner sur le disque hdc dans le cas où les deux disques ont des géométries différentes.
Initialisation du tableau
Pour créer un tableau /dev/md1 à partir de /dev/hda1 (partition montée) et /dev/hdc1 (partition nouvellement créée), il faut faire appel à la commande mdadm . Comme la partition hda1 est déjà montée, on ne va pas pouvoir le créer en une étape. On va d'abord créer un tableau de deux partitions, dont une est /dev/hdc1, et l'autre manquante. Il n'est donc pas complet, mais vu que le RAID1 peut fonctionner avec un seul disque, il est utilisable. La commande est la suivante:
mdadm --create /dev/md1 --level=1 -n 2 /dev/hdc1 missing
Le périphérique /dev/md1 est donc créé comme un tableau RAID1 de deux partitions, qui sont hdc1 et une partition qui sera ajoutée plus tard, et a la même taille que /dev/hdc1. On peut maintenant créer le filesystem dessus via la commande mkfs désirée, par exemple, pour ext2:
mke2fs /dev/md1
L'ordre de ces deux opérations est important. Ce n'est pas un problème de disparition des données stockées sur hdc1: elles sont accessibles via /dev/md1, mais le problème est plus subtil: le tableau RAID a une taille multiple de 4 kB, et donc il est possible qu'il soit un peu plus petit que la partition, et donc que les derniers blocs du filesystem hébergé par la partition soient inaccessibles ou écrasés par le superblock RAID. Le fait de créer le filesystem sur le périphérique RAID permet de s'assurer qu'il ne débordera pas.
Petite remarque à propos des noms des périphériques, il n'y a aucune obligation que hda1, hdc1 et md1 portent le même numéro, mais cela aide à s'y retrouver. Par contre, pour la partition contenant le kernel, utiliser des partitions ayant le même numéro simplifie aussi la configuration du démarrage qui suivra.
Peuplement du périphérique RAID
Une fois /dev/md1 prêt, on peut le monter et y copier les données de /dev/hda1 (utiliser l'option -a de cp et s'assurer que personne n'utilise ces fichiers pendant la copie (idéalement, couper tous les services).
Démarrage en RAID1
Une fois la procédure répétée pour chaque partition, on peut préparer le système pour le redémarrage en RAID1. Pour cela, il faut:
- Préparer un kernel avec le support RAID1 en dur (je ne détaille pas ici), ou modifier le ramdisk initial pour inclure le module correspondant (sous Debian, jeter un oeil au fichier /etc/mkinitrd/modules ).
- Modifier /etc/fstab , et y remplacer les hdaN par les mdN correspondants
- Modifier la configuration du bootloader pour remplacer le paramètre root=/dev/hdN par root=/dev/mdN sur la ligne de commande passée à Linux.
Une fois cela effectué, on peut redémarrer. Le démarrage fonctionne bien, car la partition de boot (hda1 par exemple) est toujours intacte pour récupérer le kernel et le ramdisk.
En tapant la commande df ou mount , on peut confirmer que le système utilise bien les périphériques md au lieu des hda. Comme le système d'origine sur hda* a été modifié depuis la copie des fichiers (actions relatives au boot), il faut les répéter pour qu'elles soient aussi effectives sur le nouveau système.
Finalisation des tableaux RAID
Les tableaux RAID sont toujours incomplets; il va en effet falloir leur ajouter leur deuxième partition, afin qu'ils soient redondants. Au préalable, il faut d'abord modifier le type des partitions de hda en FD, comme cela a été fait sur hdc. Ensuite, pour ajouter la partition hda1 au tableau md1, la commande est:
mdadm --add /dev/md1 /dev/hda1
Comme on a prévu de faire une partion hdc1 plus petite ou aussi grande que hda1, toute l'information sur hdc1 pourra être dupliquée sur hda1; dans le cas contraire, l'ajout de la partition au tableau aurait échoué. On peut suivre l'évolution de la synchronisation dans le fichier /proc/mdstat . Procéder de même pour chaque tableau.
Configuration du boot sur le deuxième disque
Les données sont redondantes, mais pas le démarrage. En effet, si le premier disque lâche, il n'y a pas de bootloader sur le deuxième, et donc le système aura du mal à démarrer. Lancer grub depuis la ligne de commande, et taper les commandes suivantes:
device (hd0) /dev/hdc root (hd0,0) setup (hd0) quit
Cela est valable si la partition membre du tableau où se trouve le kernel est sur /dev/hdc1 (voir la doc de grub, pour faire vite, il numérote les partitions à partir de 0 et non de 1, et hd0 désigne le disque qui a servi au démarrage, pour lequel on l'a forcé à croire qu'il s'agit de hdc pour qu'il s'installe sur ce disque).
Et voilà, il reste à surveiller /proc/mdstat jusqu'à ce qu'il indique que tous les tableaux sont synchronisés. Une fois que c'est fait, on peut redémarrer le système pour en vérifier le bon fonctionnement.
A propos du démarrage, il fonctionne uniquement parce que les partitions membres d'un tableau contiennent exactement ce que contient le tableau, et donc le bootloader peut lire les fichiers sur une partition sans rien connaître du RAID; s'il y avait eu un RAID différent (0 ou 5) par exemple, une telle configuration n'aurait pas fonctioné. Aussi, après cette réalisation, les métadonnées du tableau RAID ont été déplacées de la fin au début de la partition, empêchant cette technique. Heureusement, GRUB2 connaît le RAID et permet un démarrage plus propre et dans des configurations plus variées.
Quand un disque a lâché
Lorsqu'un disque lâche, il faut le remplacer, recréer les mêmes partitions que sur le disque survivant, ou, si le nouveau disque a une géométrie diférente, légèrement plus grandes. Ensuite, ajouter les partitions aux tableaux comme on l'a fait à la finalisation des tableaux RAID, y réinstaller GRUB et attendre la synchronisation.
Si le nouveau disque est un peu trop petit
Il faut dans ce cas jouer de subtilité: le plus simple est de recréer toutes les nouvelles partitions légèrement plus grandes que les tableaux correspondants, et de les ajouter à ces tableaux, et de créer la dernière avec l'espace restant, mais qui sera plus petite. Y créer un filesystem ayant la taille de la partition moins 128 KB (pour laisser la place au superblock), la monter quelque part et y copier les données du tableau correspondant. Ensuite, démonter le tableau et la partition, supprimer le tableau par la commande mdadm --stop /dev/mdN et en recréer un nouveau avec pour comme composants la nouvelle partition et un disque manquant ("missing"). Monter le nouveau tableau et y ajouter la partition de l'ancien tableau. On a ainsi recréé un nouveau tableau plus petit que l'original. Ou, plus simple et moins risqué, répéter l'opération de migration du disque simple vers le RAID (avec un tableau RAID portant un numéro différent.
tags: linux