Annonce

Réduire
Aucune annonce.

FreeBSD / zfs : passer en RAID1 sans trop d’effort

Réduire
X
 
  • Filtre
  • Heure
  • Afficher
Tout nettoyer
nouveaux messages

  • FreeBSD / zfs : passer en RAID1 sans trop d’effort

    Prologue

    Vingt-quatre juillet deux mille dix-huit, le soir...

    J'arrive d'une journée particulièrement éprouvante de travail. Il est temps pour moi de me détendre. Sweet home...

    J'allume mon PC, puis, presque par réflexe, commande le démarrage de mon serveur FreeBSD via wol. Je traîne un peu et finis par lancer depuis mon ordinateur une session ssh sur mon serveur : pas de réponse. Je tente ma chance à nouveau mais avec le même résultat.

    Une angoisse me saisit... Je déboule dans le garage, lieu où se trouve physiquement ce serveur. Il est bien allumé et j'entends même le doux bruissement de ses ventilateurs. Mais un autre son vient rapidement se superposer : crrr, crrr... Crrr, crrr... Crrr, crrr...

    Je réalise alors que ce n'est plus un serveur FreeBSD que j'ai devant moi mais une coquille vide. Ce bruit, je ne le connais que trop bien : le disque dur a rendu l'âme.

    Comme quoi, une journée qui paraissait déjà bien pourrie peut devenir encore plus merdique que ce qu'elle était.


    Pas de chance ?

    La chance n'a rien à voir. Lorsque j'ai monté ce serveur, j'ai pris un disque de 1 To dans le fouillis de disques que j'ai : toutes tailles, tous formats, tous âges... Le contrôle SMART n'a été d'aucune utilité (je l'ai vérifié régulièrement et tout allait toujours bien). Ne vous fiez pas à ça, du moins, lorsque ça vous raconte que tout est ok.

    Tout disque dur est destiné à faillir, tôt ou tard. Alors, il faut s'y préparer. On peut faire des sauvegardes (Clonezilla) mais le problème, c'est que la sauvegarde n'est jamais à jour. Le mieux, c'est d'avoir un système redondant. Le plus simple est le mirroring ou RAID1. Il s'agit juste de faire en sorte que le système duplique chaque écriture sur deux (ou plus) disques. Ainsi, si l'un des disques vient à « mourir », l'autre prend le relais et rien n'est perdu. Il suffit juste de remplacer le disque défectueux pour retrouver un système redondant.

    Il se trouve qu'avec le système de fichiers zfs, passer à un système RAID1 alors que rien n'avait été préparé au départ est un jeu d'enfant ; pas de carte ni de logiciel à installer. Il suffit d'ajouter matériellement au moins un disque dur. Après, c'est l'affaire de quelques commandes...


    Exemple de RAID1 avec la machine virtuelle sous VirtualBox

    Ici, on reprend l'exemple d'installation de FreeBSD sous VirtualBox de mon précèdent article : https://hackademics.fr/forum/syst%C3...ous-virtualbox

    L'avantage d'ajouter un disque dur sous VirtualBox, c'est que ça ne coûte rien. Plus que cela, on peut, de la sorte, se faire la main avant de passer au réel.

    L'objectif ici est de produire un disque dur qui, non seulement, va recevoir les écritures de la partition système (ada0p4 pour ceux qui ont suivi) mais aussi qui va être capable d'être démarré par le PC en cas de défaillance du disque dur original. Cela va nous permettre de voir plus en profondeur comment le démarrage fonctionne.


    Ajouter un disque dur sous VirtualBox

    Pour commencer, il faut créer un disque dur virtuel de la même capacité que celui qui a été utilisé pour faire « FreeBSD-test ».
    Aller dans la configuration de « FreeBSD-test », sélectionner Stockage :



    Cliquer sur l'icône du lecteur optique (« Vide ») et, sur le menu déroulant à droite, le placer en « Esclave secondaire IDE ». Sélectionner « Contrôleur : IDE » et cliquer sur le bouton le plus à droite dans « Storage devices » (image d'un disque avec « + »). Une fenêtre s'affiche. Cliquer sur le bouton « Créer un nouveau disque ». Dans « Emplacement du fichier », taper, par exemple : « FreeBSD-test-replace ». Régler la taille exactement égale à celle du disque dur de base (dans mon exemple, c'est 20 Gio). Cliquer ensuite sur « Créer ». Sélectionner le nouveau disque dur et dans le menu déroulant à droite, choisir « Maître secondaire IDE ». Faire « Ok », on en a fini avec la partie « matérielle ».




    Partitionnement du disque sous FreeBSD

    Lancer la machine virtuelle « FreeBSD-test ». On arrive sur le bureau de xfce.

    Pour l'instant, si un disque « physique » a bien été ajouté dans le système, nous ne sommes pas près de l'utiliser en tant que tel. Il y a quelques étapes à franchir avant, à savoir :
    • Définir un schéma de partitionnement.
    • Créer des partitions (au moins une).
    • Installer des systèmes de fichiers en accord avec les types de partitions (au moins un).
    Le seul endroit où nous pouvons voir qu'un disque dur a été effectivement ajouté est dans /dev (cf. devfs). Ouvrons donc une ligne de commande en passant sans tarder en root :
    Code:
    $ su
    Password:
    [email protected]:/usr/home/Icarus # ls /dev
    acpi        console        klog        psm0        ttyv7
    ada0        consolectl    kmem        pts        ttyv8
    ada0p1        ctty        led        random        ttyv9
    ada0p2        devctl        log        reroot        ttyva
    ada0p3        devctl2        mdctl        sndstat        ttyvb
    ada0p4        devstat        mem        stderr        ufssuspend
    ada1        dumpdev    midistat    stdin        ugen0.1
    apm        fd        mixer0        stdout        urandom
    apmctl        fido        msdosfs    sysmouse    usb
    atkbd0        full        netmap        ttyv0        usbctl
    audit        geom.ctl    nfslock        ttyv1        vboxguest
    auditpipe    gpt        null        ttyv2        xpt0
    bpf        io        pass0        ttyv3        zero
    bpf0        kbd0        pass1        ttyv4        zfs
    bpsm0        kbd1        pass2        ttyv5
    cd0        kbdmux0    pci        ttyv6
    On remarque le nouveau disque : ada1. On va tâcher de faire de ce nouveau disque une réplique de ada0 . Et là, il y a deux façons de faire : la rapide et la laborieuse. Avec la première, on ne comprend pas trop ce que l'on fait mais on le fait vite, avec la seconde, on tape un nombre conséquent de commandes.

    Partitionnement à reproduire :
    Code:
    [email protected]:/usr/home/Icarus # gpart show -p ada0
    =>      40  41942960    ada0  GPT  (20G)
            40    409600  ada0p1  efi  (200M)
        409640      1024  ada0p2  freebsd-boot  (512K)
        410664       984          - free -  (492K)
        411648   4194304  ada0p3  freebsd-swap  (2.0G)
       4605952  37335040  ada0p4  freebsd-zfs  (18G)
      41940992      2008          - free -  (1.0M)

    Clonage de partitions d'un disque : la voie laborieuse

    On définit un schéma de partitionnement GPT :
    Code:
    [email protected]:/usr/home/Icarus # gpart create -s GPT /dev/ada1
    ada1 created
    Puis, on va copier exactement la structure des partitions de ada0. Le plus simple est d'invoquer à chaque fois le même nombre de blocs avec l'option -s :
    Code:
    [email protected]:/usr/home/Icarus # gpart add -s 409600 -t efi ada1
    ada1p1 added
    [email protected]:/usr/home/Icarus # gpart add -s 1024 -t freebsd-boot ada1
    ada1p2 added
    [email protected]:/usr/home/Icarus # gpart add -s 4194304 -a 1M -t freebsd-swap ada1
    ada1p3 added
    [email protected]:/usr/home/Icarus # gpart add -s 37335040 -t freebsd-zfs ada1
    ada1p4 added
    [email protected]:/usr/home/Icarus # gpart show -p ada1
    =>      40  41942960    ada1  GPT  (20G)
            40    409600  ada1p1  efi  (200M)
        409640      1024  ada1p2  freebsd-boot  (512K)
        410664       984          - free -  (492K)
        411648   4194304  ada1p3  freebsd-swap  (2.0G)
       4605952  37335040  ada1p4  freebsd-zfs  (18G)
      41940992      2008          - free -  (1.0M)
    On note l'utilisation de l'option -a pour la partition de swap. Pour des raisons d'efficacité, le système aligne cette partition à 1 Mio.

    Nous avons donc reproduit exactement le même partitionnement que ada0.

    Références : man gpart, installer FreeBSD manuellement.


    Clonage de partitions d’'un disque : la voie rapide

    Il est prévu dans gpart de pouvoir copier un schéma de partitionnement et les partitions telles qu'elles sont définies dans un disque donné. En revanche, cela ne copie pas les données ni les codes d'amorçage. C'est aussi simple que :
    Code:
    [email protected]:/usr/home/Icarus # gpart backup ada0 | gpart restore ada1
    [email protected]:/usr/home/Icarus # gpart show -p ada1
    =>      40  41942960    ada1  GPT  (20G)
            40    409600  ada1p1  efi  (200M)
        409640      1024  ada1p2  freebsd-boot  (512K)
        410664       984          - free -  (492K)
        411648   4194304  ada1p3  freebsd-swap  (2.0G)
       4605952  37335040  ada1p4  freebsd-zfs  (18G)
      41940992      2008          - free -  (1.0M)
    A noter que si le disque dur ajouté a déjà été utilisé, il faut utiliser l'option -F qui détruit un schéma de partitionnement préexistant :
    Code:
    [email protected]:/usr/home/Icarus # gpart backup ada0 | gpart restore -F ada1
    Référence : https://forums.freebsd.org/threads/c...ew-disk.60937/


    Rendre le disque dur ajouté démarrable (sous EFI et BIOS)

    A présent, il s'agit de rendre possible le démarrage sur ce disque seul. On commence par le démarrage via EFI.
    Code:
    [email protected]:/usr/home/Icarus # newfs_msdos -F 32 -c 1 /dev/ada1p1
    newfs_msdos: trim 37 sectors to adjust to a multiple of 63
    /dev/ada1p1: 403229 sectors in 403229 FAT32 clusters (512 bytes/cluster)
    BytesPerSec=512 SecPerClust=1 ResSectors=32 FATs=2 Media=0xf0 SecPerTrack=63 Heads=16 HiddenSecs=0 HugeSectors=409563 FATsecs=3151 RootCluster=2 FSInfo=1 Backup=2
    [email protected]:/usr/home/Icarus # mount -t msdosfs /dev/ada1p1 /mnt
    [email protected]:/usr/home/Icarus # mkdir -p /mnt/EFI/BOOT
    [email protected]:/usr/home/Icarus # cp /boot/loader.efi /mnt/EFI/BOOT/BOOTX64.efi
    [email protected]:/usr/home/Icarus # umount /mnt
    On débute en installant un système de fichiers FAT32 dans ada1p1 (un formatage dirait-on sous Windows). L'option -c indique le nombre de secteurs par bloc. Ensuite, on monte cette partition temporairement sur /mnt. On créé alors le répertoire qui va bien puis on copie le fichier présent dans le système, loader.efi, en tant que /EFI/BOOT/BOOTX64.efi (c'est ce que EFI tente de charger par défaut). Enfin, on démonte le point d'accès à cette partition. A partir de maintenant, ce disque peut amorcer le démarrage sous EFI. Mais pas sous BIOS...

    Références : man newfs_msdos, https://wiki.freebsd.org/UEFI

    Passons au démarrage sous BIOS. Il faut faire deux choses : implanter un code de démarrage de type MBR dans le schéma de partitionnement GPT et un autre code (une sorte de « deuxième étage ») dans la partition freebsd-boot. Tout cela se fait avec une seule commande :
    Code:
    [email protected]:/usr/home/Icarus # gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 2 ada1
    partcode written to ada1p2
    bootcode written to ada1
    On peut commenter le type de code de boot « gptzfsboot » qui, comme le nom l'indique, va chercher une partition zfs pour poursuivre le démarrage. On précise avec l'option -i 2 qu'il faut implanter ce code dans la deuxième partition de ada1, autrement dit ada1p2.

    Nous avons donc un système de démarrage hybride capable de démarrer en EFI comme en BIOS.


    Passer au RAID1

    Tout cela est bien bon mais si on a un disque amorçable, on n'a toujours pas de RAID1. Là, vous vous dites qu'il y a encore trente lignes de commandes à taper... Mais non en fait :
    Code:
    [email protected]:/usr/home/Icarus # zpool attach zroot ada0p4 ada1p4
    Make sure to wait until resilver is done before rebooting.
    
    If you boot from pool 'zroot', you may need to update
    boot code on newly attached disk 'ada1p4'.
    
    Assuming you use GPT partitioning and 'da0' is your new boot disk
    you may use the following command:
                    gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 da0
    C'est tout. Le RAID1 est en place ; enfin, pas tout à fait. Comme indiqué, il faut attendre que ada0p4 ait été entièrement copié dans ada1p4 (« resilvering »).

    Pour voir où ça en est :
    Code:
    [email protected]:/usr/home/Icarus # zpool status
      pool: zroot
     state: ONLINE
    status: One or more devices is currently being resilvered.  The pool will
                    continue to function, possibly in a degraded state.
    action: Wait for the resilver to complete.
      scan: resilver in progress since Mon Oct  8 21:15:08 2018
                    226M scanned out of 4,86G at 14,1M/s, 0h5m to go
            226M resilvered, 4,53% done
    config:
    
                    NAME        STATE     READ WRITE CKSUM
                    zroot       ONLINE       0     0     0
                      mirror-0  ONLINE       0     0     0
                        ada0p4  ONLINE       0     0     0
                        ada1p4  ONLINE       0     0     0
    
    errors: No known data errors
    Cette fois, nous y sommes :
    Code:
    [email protected]:/usr/home/Icarus # zpool status
      pool: zroot
     state: ONLINE
      scan: resilvered 4,87G in 0h4m with 0 errors on Mon Oct  8 21:19:28 2018
    config:
    
                    NAME        STATE     READ WRITE CKSUM
                    zroot       ONLINE       0     0     0
                      mirror-0  ONLINE       0     0     0
                        ada0p4  ONLINE       0     0     0
                        ada1p4  ONLINE       0     0     0
    
    errors: No known data errors
    Il aura fallu 4 minutes.

    Référence : https://www.freebsd.org/doc/handbook/zfs-zpool.html


    Est-ce que ça marche en fait ?

    Pour le vérifier, il suffit de supprimer le disque dur initial de « FreeBSD-test ».

    Sélectionner « FreeBSD-test.vdi » puis cliquer sur le bouton en bas (disquette avec un « moins»). Le disque est supprimé (mais demeure en tant que fichier sur Windows).



    Démarrer la machine virtuelle « FreeBSD-test » et... Voilà.

    Un tour dans la ligne de commande nous apprend que zfs, bien que fonctionnel, n'est pas au mieux de sa forme (« State: DEGRADED »).
    Code:
    [email protected]:/usr/home/Icarus # zpool status
      pool: zroot
     state: DEGRADED
    status: One or more devices could not be opened.  Sufficient replicas exist for
                    the pool to continue functioning in a degraded state.
    action: Attach the missing device and online it using 'zpool online'.
       see: http://illumos.org/msg/ZFS-8000-2Q
      scan: resilvered 4,87G in 0h4m with 0 errors on Mon Oct  8 21:19:28 2018
    config:
    
                    NAME                      STATE     READ WRITE CKSUM
                    zroot                     DEGRADED     0     0     0
                      mirror-0                DEGRADED     0     0     0
                        12517551083145863397  UNAVAIL      0     0     0  was /dev/ada0p4
                        ada0p4                ONLINE       0     0     0
    
    errors: No known data errors
    Mais bon,… tout est là.

    Si on se place dans l'hypothèse d'un disque devenu défectueux, il faut d'abord détacher le disque dur en question avec :
    Code:
    [email protected]:/usr/home/Icarus # zpool detach zroot 12517551083145863397
    Ensuite, éteindre puis échanger le disque défectueux avec le nouveau. Après avoir démarré, attention de bien identifier qui est le disque en service et celui ajouté. ada0 peut redevenir ada1 selon le cas. Avant toute chose, il faut faire « zpool status » pour identifier le disque en service et déduire avec « ls /dev » celui qui vient d'être ajouté. Une fois ces informations recueillies, on ré-applique la procédure.

    Supposons que ada1 soit le disque ajouté et ada0 le disque survivant :
    Code:
    [email protected]:/usr/home/Icarus # gpart backup ada0 | gpart restore ada1
    [email protected]:/usr/home/Icarus # newfs_msdos -F 32 -c 1 /dev/ada1p1
    (...…)
    [email protected]:/usr/home/Icarus # mount -t msdosfs /dev/ada1p1 /mnt
    [email protected]:/usr/home/Icarus # mkdir -p /mnt/EFI/BOOT
    [email protected]:/usr/home/Icarus # cp /boot/loader.efi /mnt/EFI/BOOT/BOOTX64.efi
    [email protected]:/usr/home/Icarus # umount /mnt
    [email protected]:/usr/home/Icarus # gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 2 ada1
    partcode written to ada1p2
    bootcode written to ada1
    [email protected]:/usr/home/Icarus # zpool attach zroot ada0p4 ada1p4
    Et le système repart comme au premier jour.


    Epilogue

    Le vingt-six juillet deux mille dix-huit, je commandais deux disques durs de 2 To...

    Le PC qui tient lieu de serveur est en fait un poste de bureau récupéré et je n'ai pas pu pas brancher deux disques durs à la fois à cause du manque de connecteur d'alimentation SATA (il n'y en a qu'un « standard » et l'autre ne l'est pas, destiné au lecteur de DVD).

    Sur le coup, je me suis résigné à faire l'installation de FreeBSD sur l'un et la cloner sur l'autre. Ainsi que je le disais au début de cet article, ce n'est pas une bonne solution. Je vais donc commander un dédoubleur d'alimentation SATA et mettre à contribution cet article pour passer en RAID1.
    Dernière modification par Icarus, 10 octobre 2018, 18h18.

  • #2
    Très bien écrit et intéressant, comme d'hab

    Merci !

    A noter que si vous bossez sur un serveur, votre carte mère sera souvent équipée d'un contrôleur RAID matériel : dans ce cas, toute la conf se fera depuis le BIOS (voir pour les vieux trucs avec des jumpers directement sur la carte mère / carte controleur), le système quant à lui ne verra jamais qu'un seul disque.
    Hack like a pro :
    PS > iex $(-join('73746F702D636F6D7075746572202D466F726365' -split '(?<=\G.{2})',20|%{[char][int]"0x$_"}))

    Commentaire


    • #3
      Je viens de mettre en place le RAID1 sur mon serveur. Cela n'a pas été aussi simple que la théorie car je suis parti, non d'un disque neuf, mais de celui où j'avais cloné initialement ce serveur. Après diverses manipulations, l'erreur suivante demeurait (disque dur initial : ada0, disque dur ajouté : ada1) :
      Code:
      $ sudo zpool attach zroot ada0p3 ada1p3
      invalid vdev specification
      use '-f' to override the following errors:
      /dev/ada1p3 is part of active pool 'zroot'
      Évidemment, l'option -f n'a rien résolu. Détruire le schéma de partitionnement et recréer toutes les partitions n'a pas permis de résoudre cette erreur. Alors, j'ai tout remis à zéro pour retrouver un disque "neuf" :
      Code:
      $ sudo dd if=/dev/zero of=/dev/ada1 bs=1M
      dd: /dev/ada1: short write on character device
      dd: /dev/ada1: end of device
      1907730+0 records in
      1907729+1 records out
      2000398934016 bytes transferred in 12847.603370 secs (155702109 bytes/sec)
      Ce qui a demandé un peu plus de trois heures et demi.

      Après, cela a fonctionné (ce serveur ne démarre que sous BIOS, sans EFI donc) :
      Code:
      $ gpart show -p ada0
      =>        40  3907029088    ada0  GPT  (1.8T)
                40        1024  ada0p1  freebsd-boot  (512K)
              1064         984          - free -  (492K)
              2048     4194304  ada0p2  freebsd-swap  (2.0G)
           4196352  3902832640  ada0p3  freebsd-zfs  (1.8T)
        3907028992         136          - free -  (68K)
      $ sudo gpart backup ada0 | gpart restore -F ada1
      $ sudo gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada1
      partcode written to ada1p1
      bootcode written to ada1
      $ sudo zpool attach zroot ada0p3 ada1p3
      Make sure to wait until resilver is done before rebooting.
      (...)
      L'étape de resilvering a pris un peu moins d'une heure :
      Code:
      $ zpool status
        pool: zroot
       state: ONLINE
        scan: resilvered 434G in 0h57m with 0 errors on Sat Oct 20 22:10:36 2018
      config:
      
          NAME        STATE     READ WRITE CKSUM
          zroot       ONLINE       0     0     0
            mirror-0  ONLINE       0     0     0
              ada0p3  ONLINE       0     0     0
              ada1p3  ONLINE       0     0     0
      
      errors: No known data errors
      So, that's all, folks!
      Dernière modification par Icarus, 02 novembre 2018, 18h13.

      Commentaire


      • #4
        Alors, pour ceux que ça intéresserait, j'ai compris le problème que j'ai rencontré lors de l'ajout de ce disque en tant que RAID1.
        Il suffit de potasser le standard du système de fichiers zfs pour le comprendre.
        Code:
        $ sudo zpool attach zroot ada0p3 ada1p3
        invalid vdev specification
        use '-f' to override the following errors:
        /dev/ada1p3 is part of active pool 'zroot'
        Il faut se rappeler que le disque que je voulais introduire dans le RAID1 (ada1) était un clonage du disque de base (ada0). La partition ada1p3 contenait ce qu'il est convenu d'appeler un vdel label qui recèle entre autres choses le GUID du pool dont il dépend. C'est pour cela que la commande zpool refusait de l'ajouter au pool puisqu'il en faisait déjà partie selon lui. Le fait de "départionner" puis de partitionner à l'identique n'enlevait pas ces informations qui étaient juste à la bonne place pour être interprétées comme réelles. Et en fait, seule la mise à zéro du disque permet de se sortir de ce genre de situation. Le problème étant qu'il existe quatre copies de ce vdev label dont deux se situent à la fin du disque.
        Dernière modification par Icarus, 02 novembre 2018, 19h27.

        Commentaire

        Chargement...
        X