# RAID logiciel : mdadm

*Un article de Le wiki de 2 noisettes - noisette.ch.*

Mdadm est un logiciel de gestion de RAID logiciel. Il est très complet au point que je le conseille même pour un environnement de production.

Cet article explique comment créer un RAID, assembler plusieurs disques ayant déjà fait parti d'un array, ou comment réagir en cas de panne. Pour les commandes données en exemple, nous ferons du RAID1 avec 2 disques partitionnés en 4, respectivement /boot, swap, / et /home.

# <span class="mw-headline" id="bkmrk-cr%C3%A9ation-0">Création</span>

## <span class="mw-headline" id="bkmrk-configurer-les-disqu-0">Configurer les disques</span>

Une fois le logiciel mdadm installé sur l'ordinateur, il faut configurer les disques

```
fdisk /dev/sda
fdisk /dev/sdb
```

pour que les partitions qui vont accueillir du RAID soient de type Linux raid autodetect (fd). Puis on va les assembler avec mdadm pour finalement pouvoir les formater et installer le le system dessus.

La configuration des disques sera la suivante :

```
/dev/*1 --> /boot,  100MB
/dev/*2 --> swap, 1-2GB
```

/ dev/\*3 --&gt; /, 20GB

```
/dev/*4 --> /home, le reste (bien que mettre /var serait plus judicieux sur une gentoo.
```

## <span class="mw-headline" id="bkmrk-noyau-0">Noyau</span>

Compilez le noyau avec les options suivantes (et sélectionner un autre mode de RAID si souhaité)

```
Device Drivers  ---> 
   Multi-device support (RAID and LVM)  --->
       [*] Multiple devices driver support (RAID and LVM)
       [*]   RAID support 
       [*]     RAID-1 (mirroring) mode 
```

Si vous démarrez d'un live CD, il faut charger le module (raid1 par exemple) :

```
modprobe raid1
```

Créer les nodes /dev/mdX

```
mknod /dev/md1 b 9 1
mknod /dev/md3 b 9 3
mknod /dev/md4 b 9 4
```

## <span class="mw-headline" id="bkmrk-cr%C3%A9ation-des-arrays-0">Création des arrays</span>

Pour les assembler avec mdadm, la commande ressemble à la suivante

```
mdadm --create /dev/md1 --level=1 --raid-devices=2 /dev/sda1 /dev/sdb1
mdadm --create /dev/md3 --level=1 --raid-devices=2 /dev/sda3 /dev/sdb3
mdadm --create /dev/md4 --level=1 --raid-devices=2 /dev/sda4 /dev/sdb4
```

Une fois l'array créé, reste les formatage et le montage à l'endroit voulu.

```
mke2fs /dev/md1
mkreiserfs /dev/md3
mkreiserfs /dev/md4
mkswap /dev/sda2 && mkswap /dev/sdb2
swapon /dev/sda2 && swapon /dev/sdb2 
mount /dev/md3 /mnt
mkdir -p /mnt/boot && mount /dev/md1 /mnt/boot
mkdir -p /mnt/home && mount /dev/md4 /mnt/home
```

On peut maintenant consulter les informations sur les disques, et insérer ces informations dans /etc/mdadm.conf :

```
mdadm --detail --scan >> /etc/mdadm.conf
```

### <span class="mw-headline" id="bkmrk-cr%C3%A9er-un-raid10-0">Créer un raid10</span>

```
mdadm -v --create /dev/md2 --level=raid10 --raid-devices=12 /dev/sd[a-l]2
```

### <span class="mw-headline" id="bkmrk-cr%C3%A9er-un-raid-50-0">Créer un raid 50</span>

Commencer par créer 4 baies de trois disques en RAID5 :

```
mdadm --create /dev/md21 -v --raid-devices=3 --level=5 /dev/sd[a-c]2
mdadm --create /dev/md22 -v --raid-devices=3 --level=5 /dev/sd[d-f]2
mdadm --create /dev/md23 -v --raid-devices=3 --level=5 /dev/sd[g-i]2
mdadm --create /dev/md24 -v --raid-devices=3 --level=5 /dev/sd[j-l]2
```

Pour créer un raid 0 avec ces 4 RAID5 :

```
mdadm --create /dev/md2 -v --raid-devices=4 --level=0 /dev/md21 /dev/md22 /dev/md23 /dev/md24
```

Si par la suite on veut étendre le raid : Recréer une baie de raid5 :

```
mdadm --create /dev/md25 -v --raid-devices=3 --level=5 /dev/sd[l-n]2
```

L'ajouter daans le raid0 existant :

```
mdadm --manage /dev/md2 --add /dev/md25
```

Définir le nombre de Baies pour le raid0 :

```
mdadm --grow /dev/md2 --raid-devices=5
```

# <span class="mw-headline" id="bkmrk-%28r%C3%A9%29assemblage-0">(Ré)Assemblage</span>

Une fois le RAID créé et des données dessus, on ne veut plus nécessairement le reformater et le recréer quand on l'a démonté. La solution sera donc de le réassemblé avec mdadm.

La première étape conciste à examiner une partition pour contrôler si elle fait bien partie d'un RAID (pour ceux qui on une mauvaise mémoire à très court terme) :

```
mdadm --examine /dev/sda1
```

La sortie nous dit si oui ou non la partition fait partie d'un RAID, et si oui quels autres disques en font aussi partie. Une fois en possession de ces informations, il nous reste à assembler l'ARRAY :

```
mdadm --assemble /dev/md1 /dev/sda1 /dev/sdb1
mdadm --assemble /dev/md3 /dev/sda3 /dev/sdb3
mdadm --assemble /dev/md4 /dev/sda4 /dev/sdb4
```

Reste le montage à l'endroit voulu.

# <span class="mw-headline" id="bkmrk-reconstruction-0">Reconstruction</span>

J'ai fait des tests de tolérence sur le RAID logiciel. J'ai commencé par enlever des disques à chaud (et j'ai pu bien constater qu'IDE était hot-déswap mais pas hot-swap), puis en utilisant l'option --fail pour simuler une panne. Les résultat étaient assez intéressants, mais le problème était de reconstruire le raid après la panne simulée.

Une fois la panne détectée (une véritable panne ou une simulée), on identifie le disque défectueux (avec dmesg ou /proc/mdstat) et on le retire de l'array :

```
mdadm --manage /dev/md1 --remove /dev/sdb1
```

Si on n'a pas de SATA pour enlever et remettre un disque à chaud, on arrête la machine et on la redémarre avec le nouveau disque. Puis on ajoute le nouveau disque à l'array :

```
mdadm --manage /dev/md1 --add /dev/sdb1
```

# <span class="mw-headline" id="bkmrk-suppression-0">Suppression</span>

## <span class="mw-headline" id="bkmrk-supprimer-le-raid-ex-0">Supprimer le raid existant</span>

Passer le status des disques à fail :

```
mdadm --manage /dev/md2 --fail /dev/sd[a-l]2
```

Puis les retirer du raid :

```
mdadm --manage /dev/md2 --remove /dev/sd[a-l]2
```

Arrêter le raid :

```
mdadm --manage --stop /dev/md2
```

Commenter la ligne correspondant à md2 dans /etc/mdadm.conf

Initialiser les périphériques pour effacer toute trace et redémarrer la machine:

```
mdadm --zero-superblock /dev/sd[a-l]2
reboot
```

# <span class="mw-headline" id="bkmrk-monitoring-0">Monitoring</span>

Mdadm offre une option de monitoring des arrays : --monitor. Pouvant être directement lancé sur centos avec le daemon mdmonitor : service mdmonitor start chkconfig mdmonitor on

## <span class="mw-headline" id="bkmrk-notifications-de-bas-0">Notifications de base</span>

Ajouter dans /etc/mdadm.conf

```
MAILADDR youremail@domain.com
MAILFROM my-server-name
```

tester : mdadm --monitor --scan --test --oneshot

## <span class="mw-headline" id="bkmrk-notification-%C3%A0-l%27aid-0">Notification à l'aide d'un script</span>

Mdmonitor peut appeler un script externe lors d'un événement (bon ou mauvais). Pour cela rajouter dans /etc/mdadm.conf :

```
PROGRAM /opt/systools/handle-mdadm-events.sh
```

Les arguments passés au script seront les suivants :

```
   * $1 : une chaine de caractère qui décrit l'évènement qui s'est produit
         o 'SparesMissing' : une panne est détectée mais aucun disque de remplacement n'est présent
         o 'Fail' : un disque est détecté comme déféctueux
         o 'RebuildStarted' : un nouveau disque est ajouté à l'array et la reconstruction commence
         o 'Rebuild20' : la reconstruction est à 20%
         o 'Rebuild40' : la reconstruction est à 40%
         o 'Rebuild60' : la reconstruction est à 60%
         o 'Rebuild80' : la reconstruction est à 80%
         o 'RebuildFinished' : la reconstruction est terminée
         o 'SpareActive' : un disque de réserve est ajouté à un array 
   * $2 : le nom de la device md : /dev/mdX 
```

$1 et $2 étant le premier et le deuxième argument passé en paramètre.

Voici le script :

```
#!/bin/bash
CONFIG="/etc/mdadm.conf"

MAILADDR="pbrun@systea.net" # support@systea.net" #espace entre les mails

parse_event()
{
  echo "Hôte            : $HOSTNAME"
  if [ -z "$1" ]; then
    echo "Événement        : Test message"
  else
    echo "MD Device       : $2"
    echo "Événement           : $1"
    if [ -n "$3" ]; then
      echo "Élément en cause: $3"
    fi
  fi

  echo ""
  echo "/proc/mdstat dump:"
  FAIL=0
  DEGRADED=0
  while read LINE; do
    echo -n "$LINE"
    if [ -n "$(echo "$LINE" |grep 'active raid')" ]; then
      if [ -n "$(echo "$LINE" |grep '\(F\)')" ]; then
        FAIL=$(($FAIL + 1))
        echo -n " (ATTENTION: DISQUE(S) DÉFÉCTUEUX!)"
      fi

      if [ -n "$(echo "$LINE" |grep '\(S\)')" ]; then
        echo -n " (Hotspare(s) disponibles)"
      else
        echo -n " (NOTE: Pas de hotspare?!)"
     fi
    fi

    if [ -n "$(echo "$LINE" |grep 'blocks')" ]; then
      if [ -n "$(echo "$LINE" |grep '_')" ]; then
        DEGRADED=$(($DEGRADED + 1))
        echo -n " (DEGRADED!!!)"
      fi
    fi

    echo ""
  done < /proc/mdstat

  if [ $FAIL -gt 0 ]; then
    echo ""
    echo "** ATTENTION: Un ou plusieurs RAID ont un ou plusieurs disques déféctueux! **"
  fi

  if [ $DEGRADED -gt 0 ]; then
    echo ""
    echo "** ATTENTION: Un ou plusieurs RAID fonctionnent en mode dégradé! **"
  fi
}

# main line:

# Get MAILADDR from mdadm.conf config file, if not set already
if [ -z "$MAILADDR" ] && [ -f "$CONFIG" ]; then
  MAILADDR=`grep MAILADDR "$CONFIG" |cut -d' ' -f2`
  if [ -z "$MAILADDR" ]; then
    MAILADDR="root"
  fi
fi

# Call the parser and send it to the configured address
parse_event $* |mail -s"Événement RAID(MD) sur  $HOSTNAME" "$MAILADDR"

exit 0
```

Afin de ne pas recevoir deux mails pour chaque alerte il est conseillé de commenter les deux lignes :

```
MAILADDR youremail@domain.com
MAILFROM my-server-name - mdadm
```

## <span class="mw-headline" id="bkmrk-un-script-plus-simpl-0">Un script plus simple...</span>

```
#!/bin/bash
MAIL=admin@domain.com
if [ $(date +\%w) -ne 0 ]
then
   STATE=$(/sbin/mdadm --query --detail /dev/md1 | grep State | grep -v Major | awk '{print $3}')
   if [ "$STATE" != "clean" -a "$STATE" != "active" ]
   then
      (/sbin/mdadm --query --detail /dev/md1
      )| mail -s "PROBLEME RAID sur $(hostname) $(date +%d/%m)" $MAIL
   fi
fi
```

# <span class="mw-headline" id="bkmrk-notes-0">Notes</span>

<div class="mw-body-content" id="bkmrk-v%C3%A9rifier-d%27avoir-une"><div class="mw-content-ltr" dir="ltr" id="bkmrk-v%C3%A9rifier-d%27avoir-une-0" lang="fr"><div class="mw-parser-output">- Vérifier d'avoir une version &gt; 2.5.0, car elle souffre d'un gros memory leak quand mdadm est lancé en monitoring.

</div></div></div>