Guide de suppression d’une matrice mdadm
RAID1 tout en préservant les données existantes de la partition, évitant ainsi d’avoir à réinstaller ou copier des fichiers.
Si jamais vous avez un besoin similaire, voici comment je m’en suis sorti. Il va de soi que vous devriez sauvegarder les données avant de faire quoi que ce soit, à défaut vous acceptez le risque de tout perdre. Hic sunt dracones 🐉
Un serveur dédié SoYouStart avec deux disques, pour héberger des machines virtuelles via VMware ESXi.
Malheureusement VMware ESXi ne prend pas en charge le RAID logiciel : comme solution de contournement, on peut attacher deux VMDK (disque virtuel) à chaque VM, chaque VMDK étant stocké sur un datastore (disque matériel) distinct, et configurer un RAID1 logiciel directement depuis la VM via mdadm
.
Cette ennuyeuse limitation fut d’ailleurs l’une des principales motivations pour migrer de VMware ESXi vers Promox VE, ce dernier prenant en charge le RAID1 logiciel via ZFS. Le RAID étant désormais géré au niveau de l’hôte, plus besoin que les machines virtuelles gèrent elles-mêmes un RAID logiciel, et on peut ne conserver qu’un seul disque pour chaque VM.
On va retirer des partitions de la matrice, puis faire en sorte que mdadm
se satisfasse d’une matrice RAID1 composée d’une seule partition.
Tout d’abord, inspecter partitions et disques pour identifier où se trouve quoi et ce qui doit être fait :
mdadm
et sur quels disques.# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 100G 0 disk
├─sda1 8:1 0 953M 0 part [SWAP]
└─sda2 8:2 0 99.1G 0 part
└─md0 9:0 0 99.1G 0 raid1 /
sdb 8:16 0 100G 0 disk
├─sdb1 8:17 0 953M 0 part /var/tmp
└─sdb2 8:18 0 99.1G 0 part
└─md0 9:0 0 99.1G 0 raid1 /
# cat /proc/mdstat
md0 : active raid1 sda2[0] sdb2[1]
103872512 blocks super 1.2 [2/2] [UU]
# mdadm --detail /dev/md0
State : active
Par exemple, ici :
/var/tmp
.md0
est répartie sur sda2
et sdb2
.sda
et conserver sdb2
.Une fois que tout est décidé :
# mdadm /dev/md0 --fail /dev/sda2
mdadm: set /dev/sda2 faulty in /dev/md0
# mdadm /dev/md0 --remove /dev/sda2
mdadm: hot removed /dev/sda2 from /dev/md0
# mdadm --zero-superblock /dev/sda2
Dans notre cas, on a d’abord supprimé la partition de swap sda1
(non illustré ci-dessus : désactivée avec swapoff
et mise à jour de /etc/fstab
), puis supprimé sda2
de la matrice.
Si on s’arrêtait ici, mdadm
se plaindrait que la matrice est dégradée car il lui manque une partition :
# cat /proc/mdstat
md0 : active raid1 sdb2[1]
103872512 blocks super 1.2 [2/1] [_U]
# mdadm --detail /dev/md0
State : clean, degraded
Heureusement, on peut forcer la matrice à se satisfaire d’une seule partition pour qu’elle ne se plaigne pas d’être dégradée :
# mdadm --grow /dev/md0 --force --raid-devices=1
raid_disks for /dev/md0 set to 1
# cat /proc/mdstat
md0 : active raid1 sdb2[1]
103872512 blocks super 1.2 [1/1] [U]
# mdadm --detail /dev/md0
State : clean
Si la partition ou disque supprimé était également la partition ou disque de démarrage, s’assurer de mettre à jour grub
, initramfs
et /etc/fstab
si nécessaire :
# vi /etc/fstab
# grub-install /dev/sdb
# update-initramfs -u
Dans notre cas :
md0
est la partition de démarrage mais le bootloader n’a été installé que sur sda
(vérifier la présence de GRUB
avec dd if=/dev/sda bs=512 count=1 2> /dev/null | strings
), on a donc dû réinstaller grub
sur le disque sdb
restant pour que le démarrage puisse s’effectuer depuis ce dernier.initramfs
fait référence à la partition de swap via sa variable RESUME
, on a donc dû la supprimer de /etc/initramfs-tools/conf.d/resume
et mettre à jour initramfs
puisque la partition de swap a été supprimée.La machine peut maintenant être arrêtée et le disque inutilisé détaché du matériel. Mettre à jour l’ordre de démarrage des disques si nécessaire et démarrer : voilà !
# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 100G 0 disk
├─sda1 8:1 0 953M 0 part /var/tmp
└─sda2 8:2 0 99.1G 0 part
└─md0 9:0 0 99.1G 0 raid1 /
La solution ci-dessus fonctionne parfaitement.
Cependant, si on souhaite aller plus loin et supprimer complètement mdadm
, on doit également bidouiller le disque restant : l’idée générale est de réécrire la partition mdadm
pour supprimer le superbloc RAID tout en gardant le reste intact.
Ce genre d’opération pas très nette sur les partitions est généralement effectuée à partir du mode rescue, mais dans cet article, on va le faire directement à partir du vrai système pour un maximum de sensations.
# blkid
/dev/sda2: UUID="<sda2_uuid>" TYPE="linux_raid_member"
/dev/md0: UUID="<md0_uuid>" TYPE="ext4"
Prendre note à la fois de la partition RAID linux_raid_member
(ici sda2
) et de la partition sous-jacente elle-même (ici md0
).
linux_raid_member
restante et prendre note de la version et de l’offset des données :# mdadm --examine /dev/sda2
Data Offset : 16384 sectors
D’après la man page:
The different sub-versions store the superblock at different locations on the device, either at the end (for 1.0), at the start (for 1.1) or 4K from the start (for 1.2). “1” is equivalent to “1.2” (the commonly preferred 1.x format). “default” is equivalent to “1.2”.
En version 1.2, tout ce qui précède l’offset des données dans la partition correspond au superbloc RAID, tout ce qui suit correspond à la partition sous-jacente.
fdisk
sur le disque :# fdisk -u /dev/sda
fdisk
, afficher les partitions avec p
:Command (m for help): p
Device Boot Start End Sectors Size Id Type
/dev/sda1 * 2048 1953791 1951744 953M 83 Linux
/dev/sda2 1953792 209715199 207761408 99.1G fd Linux raid autodetect
d
et son numéro de partition.n
:
p
comme primaire et réutiliser le même numéro de partition.16384 + 1953792 = 1970176
en utilisant l’exemple ci-dessus).209715199
).w
. Cela devrait positionner la nouvelle partition sda2
à la place de la partition sous-jacente (anciennement md0
).Spoiler : si la partition modifiée était également celle de démarrage, alors la sueur froide arrive maintenant 😱
C’est notre cas : on tombe grub rescue
car on a détruit la partition de démarrage.
Pour s’en sortir, on va pointer manuellement grub rescue
vers notre toute nouvelle partition.
grub rescue
, afficher les variables de démarrage existantes avec set
:grub rescue> set
prefix=(mduuid/<sda2_uuid>)/boot/grub
root=mduuid/<sda2_uuid>
Comme on peut le voir, le problème est que grub
pointe vers la partition que nous venons de détruire (<sda2_uuid>
).
Prendre note du chemin de fichier du prefix
(ici /boot/grub
).
ls
pour afficher les partitions existantes, nommées (hdX,msdosX)
(MBR) ou (hdX,gptX)
(GPT) :grub rescue> ls
(hd0) (hd0,msdos2) (hd0,msdos1)
ls
sur chaque partition jusqu’à trouver celle contenant le chemin de fichier du prefix
:grub rescue> ls (hd0,msdos1)/boot/grub
error: file '/boot/grub' not found
grub rescue> ls (hd0,msdos2)/boot/grub
./ ../ unicode.pf2 i386-pc/ locale/ fonts/ grubenv grub.cfg
grub rescue> set prefix=(hd0,msdos2)/boot/grub
grub rescue> set root=(hd0,msdos2)
normal
et le démarrer :grub rescue> insmod normal
grub rescue> normal
Le système devrait démarrer normalement.
sda2
a correctement remplacé l’ancienne partition md0
:# blkid
/dev/sda2: UUID="<md0_uuid>" TYPE="ext4"
mdadm
a été correctement supprimé :# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 100G 0 disk
├─sda1 8:1 0 953M 0 part /var/tmp
└─sda2 8:2 0 99.1G 0 part /
# cat /proc/mdstat
Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10]
unused devices: <none>
# mdadm --detail /dev/md0
mdadm: cannot open /dev/md0: No such file or directory
# mdadm --examine /dev/sda2
mdadm: No md superblock detected on /dev/sda2.
grub
afin de le faire pointer vers le bon UUID et d’éviter de tomber à nouveau en grub rescue
:# grub-install /dev/sda