Cherchant à tout hasard une procédure ou un outil comme raidreconf permettant d'automatiser le maximum d'opérations, je suis tombé sur deux billets notables. Dans le premier, Nathan Gray se prend à jouer avec EVMS, mdadm et des loopbacks pour faire exactement ce que je cherche à faire, c'est à dire passer d'un RAID1 à deux disques à un RAID5 à trois disques. Diantre ! Dans le second, Scott Wallace confirme les affirmations du premier, mais sur un vrai système de fichiers, de taille conséquente. Il se pourrait donc que je puisse obtenir le résultat attendu sans avoir à passer par la descente d'un backup, et surtout sans forcément devoir réaliser l'intégralité de l'opération avec un système de secours. Prometteur...

Les avantages de cette technique, si elle marche, sont clairs. D'abord elle va me dispenses des phases de destruction complète et de reconstruction des systèmes de fichiers impactés. Ensuite, parce qu'elle est entièrement basée sur des fonctions de maintenance de mdadm, la plupart des opération seront réalisées en tâche de fond par le driver RAID et laisseront le système de fichiers utilisable. Point d'interrogation majeur, il semble falloir passer par une configuration surprenante, à savoir la construction d'une grappe RAID5 à seulement deux disques, au lieu des trois attendus. Surprenant, non ?

Pour comprendre comment et pourquoi ça marche, je suis allé voir comment étaient calculées les sommes de contrôle de chaque bande dans une grappe RAID-5. Considérons l'illustration[1] suivante d'une grappe RAID-5.

Grappe RAID-5 à quatre disques

Le chunck de contrôle de la première bande est stocké sur le quatrième disque. Il contient une somme calculée sur les trois chunks de données de cette même bande, 1a, 2a et 3a. Pour la calculer, on utilise un algorithme qui commence par prendre la valeur du premier chunk de données, 1a, puis entre dans une boucle dans laquelle il fait un XOR incrémental avec chaque chunk de données supplémentaire, 2a puis 3a. Si on appelle Ca la somme de contrôle de la première bande a et N le nombre de disques dans la grappe, il semblerait qu'on ait quelque chose qui ressemble à cela :

i=1
Ca = $ia
While (i < N-1) {
        i++
        Ca = XOR(Ca, $ia)
}

Si on veut la formule générique et l'algorithme qui fonctionnent pour toutes les bandes, il faut ajouter des tests pour gérer l'entrelacement des chunks de contrôle, c'est dire à les identifier et les sauter lors du calcul. Mais je voulais juste donner l'idée générale qui permet de relever les points de l'algorithme qui m'intéressent, à savoir :

  • son fonctionnement quand N=2 ;
  • le résultat retourné.

Quand N=2, on s'aperçoit qu'il fonctionne encore. C'est une bonne chose. Les chunks de contrôle se trouvent alternés sur chaque disque comme suit.

Grappe RAID-5 à deux disques

L'algorithme n'entre alors jamais dans la boucle et se borne à produire des répliques du seul chunk de données de la bande. Ce RAID-5 à deux disques n'est en fait qu'un bon vieux RAID-1.

Grappe RAID-1 à deux disques

La différence entre un RAID-1 et un RAID-5 à deux disques sous Linux ne tient donc qu'au contenu du superbloc. Tout le reste est parfaitement identique. D'où l'idée de passer directement du RAID-1 au RAID-5 en arrêtant d'abord l'instance RAID à modifier et en la recréant ensuite avec un superbloc RAID-5 :

# mdamd --stop /dev/md0
# mdadm --create /dev/md0 -l5 -n2 /dev/sda1 /dev/sdb1

La grappe obtenue est fonctionnelle et tout à fait utilisable. Je peux ensuite ajouter à cette grappe le nouveau volume qui va se retrouver en spare :

# mdadm --add /dev/md0 /dev/sdc1

La dernière étape, celle qui prend beaucoup de temps[2], consiste à activer ce nouveau disque et à étendre le volume RAID-5 sur l'ensemble de l'espace maintenant disponible, chose possible depuis les noyaux 2.6.17 :

# mdadm --grow /dev/md0 -n3 --backup-file=/mnt/backup

Une fois cette très longue opération achevée, mon nouveau volume a doublé de taille, passant de 250Go à 500Go. Il ne reste plus qu'à répercuter ce changement au niveau du système de fichiers en utilisant resize2fs, opération qui prend certes du temps, mais nettement moins que l'extension de la grappe RAID :

# e2fsck -f /dev/md0
# resize2fs -p /dev/md0

Et voilà. Est-ce que je me sens plus en sécurité maintenant ? Même pas. Un jour, quelque chose va se passer que le RAID-5 ne pourra pas récupérer, sans parler des problèmes imputables au driver Linux lui-même. Je devrais peut-être me mettre en quête d'un quatrième disque à monter en spare. Au cas où...


Ah oui. J'ai oublié de vous dire qu'avant de me lancer là-dedans, j'ai tout de même fait une sauvegarde de tous les systèmes de fichiers impactés, forcément. Ça doit être devenu une habitude ;)

Notes

[1] Les illustrations viennent, ou sont inspirées, de http://www.prepressure.com/techno/raid.htm.

[2] Genre plusieurs heures.