ZFS zdb -C : Lire la configuration du pool directement depuis le disque

Cet article vous a aidé ?

Les pires incidents de stockage ne sont pas bruyants. Ils sont discrets, polis et pleins de répertoires vides :
zpool import n’affiche rien, la direction veut « reboot encore une fois », et votre cerveau d’astreinte commence à négocier avec la physique.

Quand ZFS ne vous dit pas la vérité via les outils habituels, zdb -C le fera. Il lit la configuration du pool directement depuis les labels disque — pas de cachefile, pas d’espoir naïf, pas de « peut-être dans /etc/zfs ». C’est l’outil à utiliser quand vous voulez des faits, pas des impressions.

Ce que fait réellement zdb -C (et pourquoi ça vous concerne)

zdb est le débogueur ZFS. Traitez-le comme vous traitez fsck sur des systèmes de fichiers qui en ont besoin : puissant,
pas routinier, et à n’utiliser que rarement en production pendant un pic de trafic parce que vous étiez curieux.
L’option -C demande à zdb d’afficher la configuration du pool telle qu’elle est trouvée sur le disque.

Crucialement, cette configuration n’est pas la même chose que « ce que cet hôte pense actuellement que le pool est ».
C’est la config stockée dans les labels ZFS sur chaque vdev (disque, partition ou périphérique basé sur fichier), écrite par ZFS lui‑même. Cela fait de zdb -C un contrôle de réalité quand :

  • Le pool ne s’importe pas ou s’importe dégradé et vous ne faites pas confiance à l’interface graphique.
  • Vous avez déplacé des disques entre machines et le cachefile est obsolète ou manquant.
  • Les noms de périphériques ont changé (/dev/sda roulette), mais les GUID n’ont pas bougé.
  • Vous suspectez un split‑brain / situation multi‑hôtes et avez besoin de preuves sur disque.
  • Vous devez mapper des « disques mystères » aux vdevs sans risquer un import.

zpool import est plus haut niveau et opinionné. Il tente d’assembler un pool et de rapporter un état.
zdb -C est plus bas niveau et direct. Il imprime ce que disent les labels ZFS, même si le système est confus.

Posture de sécurité : comment ne pas empirer une mauvaise journée

Utilisez zdb -C pour l’inspection en lecture seule. En général il n’écrit pas, mais l’action d’importer un pool peut le faire.
Si vous êtes en situation d’analyse médico‑légale ou de récupération, privilégiez :

  • zpool import -N pour importer sans monter les datasets, réduisant le rayon d’action.
  • zpool import -o readonly=on si votre plateforme le supporte pour votre flux de travail.
  • Déconnecter tout autre hôte qui pourrait importer le même pool (oui, même « ça ne devrait pas »).

Blague #1 : ZFS ne perd pas votre pool. Les humains le cachent juste dans l’espace de noms des périphériques puis font semblant d’être surpris.

Où se trouve la vérité : labels ZFS, uberblocks et arbres de configuration

ZFS stocke les métadonnées du pool sur chaque vdev de niveau supérieur. Chaque vdev a plusieurs labels à offsets fixes (historiquement
quatre labels), contenant une config sérialisée et d’autres métadonnées. Quand vous exécutez zdb -C, il lit ces
labels et affiche l’arbre de configuration que ZFS utilisera pour assembler le pool.

La config est une structure imbriquée : pool → arbre vdev → enfants → feuilles. Les feuilles représentent les périphériques
réels (disques, partitions, fichiers), chacun avec un GUID. Les vdevs de premier niveau (mirror, raidz, draid) ont aussi leurs GUID.
C’est pourquoi les GUID sont votre ancre quand les chemins de périphérique changent.

Éléments clés que vous verrez dans zdb -C

  • pool_guid : l’identité du pool. Si cela change, vous n’êtes pas en train de regarder le même pool.
  • vdev_guid : identité d’un nœud vdev dans l’arbre.
  • path et devid : dépendants de l’OS, souvent obsolètes entre machines.
  • txg : transaction group. Plus élevé signifie « état plus récent ».
  • state : si les labels pensent que le périphérique était sain, offline, removed, etc.
  • ashift : alignement de secteur puissance de deux. Un mauvais ashift n’est pas fatal, mais il est irréversible.
  • features : flags de fonctionnalités qui affectent la compatibilité.
  • hostid et hostname : indices pour les imports multi‑hôtes.

Pourquoi zdb -C est différent du cachefile et de zpool.cache

Beaucoup d’administrateurs font trop confiance à /etc/zfs/zpool.cache ou à ce que leur distribution utilise. Ce cachefile est une
commodité. Il peut être manquant, obsolète ou erroné après un recâblage, un échange de HBA, des migrations de VM, ou « quelqu’un a nettoyé /etc parce que c’était sale ».

Les labels sur disque ne sont pas optionnels. S’ils sont intacts, ZFS peut reconstruire la config du pool. S’ils sont endommagés,
ZFS devient opinionné de manière peu utile — et vous êtes en terrain de récupération.

Faits intéressants et contexte historique

  • ZFS a été créé chez Sun Microsystems et livré dans Solaris au milieu des années 2000, construit autour des checksums de bout en bout et des métadonnées copy‑on‑write.
  • Les labels sur disque sont redondants par conception : plusieurs labels par vdev, plus plusieurs vdevs, parce que les points uniques de défaillance des métadonnées sont pour d’autres systèmes de fichiers.
  • L’identité basée sur GUID fut un choix délibéré pour éviter la dépendance aux noms de périphérique. Le renommage Linux de sda n’est pas une surprise ; c’est un mardi.
  • L’ère des feature flags a remplacé les versions monolithiques de « ZFS » pour permettre aux pools d’évoluer progressivement, mais a aussi rendu les imports cross‑plateforme plus négociés.
  • L’enregistrement du hostid existe parce que les imports multi‑hôtes peuvent corrompre silencieusement les pools ; ZFS essaie de détecter « ce pool a été importé ailleurs récemment ».
  • zdb est volontairement tranchant : il expose des structures internes (MOS, uberblocks, block pointers) et suppose que vous savez ce que vous faites.
  • zpool.cache est arrivé plus tard comme commodité de démarrage, important surtout pour les boot root‑on‑ZFS qui ne peuvent pas tout scanner lentement à chaque démarrage.
  • L’alignement sectoriel 4K (ashift) est devenu un point douloureux quand les disques « 512e » et « 4Kn » sont apparus ; ZFS l’a rendu explicite plutôt que de deviner.
  • OpenZFS moderne s’étend sur plusieurs plateformes (Linux, FreeBSD, illumos) avec le même format sur disque de base, mais les feature flags limitent encore la compatibilité.

Lire la sortie de zdb -C comme il faut

La sortie de zdb -C est dense parce que la vérité est dense. Votre boulot est de la réduire à des réponses :
« Quels disques appartiennent à quels vdev ? », « Est‑ce le txg le plus récent ? », « Ce pool a‑t‑il été importé ailleurs en dernier ? »,
et « Qu’est‑ce que ZFS tentera d’assembler si j’importe ? »

Schémas à rechercher

  • Configs multiples en désaccord : si différents disques montrent des txg différents et des arbres légèrement différents, vous pouvez avoir des périphériques manquants, un écrit partiel ou un événement de split.
  • Chemins qui n’existent plus : les valeurs /dev/disk/by-id/... peuvent être anciennes. C’est acceptable. Les GUID comptent plus.
  • State et aux_state : un périphérique peut être OFFLINE volontairement, ou UNAVAIL parce qu’il a disparu.
  • Feature flags : un pool peut être parfaitement sain et pourtant non importable sur un système plus ancien.
  • hostid/hostname : s’il indique que le pool a été importé en dernier sur un autre hôte, croyez‑y et enquêtez.

Une citation à tatouer sur vos runbooks

« L’espoir n’est pas une stratégie. » — idée paraphrasée souvent attribuée à la culture de fiabilité en opérations.

Tâches pratiques : commandes, sorties et décisions (12+)

Voici les tâches que j’exécute réellement quand un pool manque, est dégradé ou suspect. Chaque tâche inclut :
une commande, ce que la sortie signifie, et la décision suivante à prendre.

Tâche 1 : Confirmer ce que ZFS considère importable

cr0x@server:~$ sudo zpool import
   pool: tank
     id: 5486843001296116957
  state: ONLINE
 action: The pool can be imported using its name or numeric identifier.
 config:

        tank        ONLINE
          mirror-0  ONLINE
            sdb     ONLINE
            sdc     ONLINE

Sens : Le scan ZFS a trouvé un pool appelé tank et peut l’assembler.
Décision : Si le pool est listé, vous avez probablement un problème de points de montage, de cache obsolète ou de features ;
lancez zdb -C tank pour confirmer la config et le hostid, puis envisagez zpool import -N pour un import plus sûr.

Tâche 2 : Dumper la config sur disque d’un pool par nom

cr0x@server:~$ sudo zdb -C tank
MOS Configuration:
        pool_guid: 5486843001296116957
        vdev_tree:
            type: 'root'
            id: 0
            guid: 5486843001296116957
            children[0]:
                type: 'mirror'
                id: 0
                guid: 15320114977311041256
                ashift: 12
                children[0]:
                    type: 'disk'
                    id: 0
                    guid: 1183942225006373321
                    path: '/dev/disk/by-id/ata-SAMSUNG_SSD_870_QVO_1TB_S5R8...'
                children[1]:
                    type: 'disk'
                    id: 1
                    guid: 10622090183881642744
                    path: '/dev/disk/by-id/ata-SAMSUNG_SSD_870_QVO_1TB_S5R8...'
        features_for_read:
            com.delphix:hole_birth
            org.openzfs:project_quota
        hostid: 0x8d3f2a11
        hostname: 'db-node-02'

Sens : C’est l’arbre faisant autorité que ZFS a enregistré. Notez ashift, les feature flags et le dernier importeur.
Décision : Si hostname n’est pas votre machine actuelle, arrêtez‑vous et vérifiez que vous n’êtes pas sur le point de faire un import double du pool.

Tâche 3 : Dumper les configs en scannant les périphériques (nom de pool non requis)

cr0x@server:~$ sudo zdb -C
zdb: can't open 'tank': no such pool
zdb: examining /dev/sdb ...
MOS Configuration:
        pool_guid: 5486843001296116957
        vdev_tree:
            type: 'root'
            children[0]:
                type: 'mirror'
                children[0]:
                    path: '/dev/sdb'
                children[1]:
                    path: '/dev/sdc'

Sens : Même si la résolution du nom du pool échoue, zdb -C peut toujours trouver des labels sur des périphériques bloc.
Décision : Utilisez ceci quand zpool import n’affiche rien. Ça vous dit si des labels existent au moins.

Tâche 4 : Vérifier le mappage d’identité du disque via by-id

cr0x@server:~$ ls -l /dev/disk/by-id/ | egrep 'SAMSUNG_SSD_870_QVO|wwn|scsi'
lrwxrwxrwx 1 root root  9 Dec 26 10:11 ata-SAMSUNG_SSD_870_QVO_1TB_S5R8... -> ../../sdb
lrwxrwxrwx 1 root root  9 Dec 26 10:11 ata-SAMSUNG_SSD_870_QVO_1TB_S5R8... -> ../../sdc
lrwxrwxrwx 1 root root  9 Dec 26 10:11 wwn-0x5002538f4123abcd -> ../../sdb
lrwxrwxrwx 1 root root  9 Dec 26 10:11 wwn-0x5002538f4fedcba -> ../../sdc

Sens : Les chemins dans zdb -C peuvent être en by-id ; assurez‑vous qu’ils résolvent vers des périphériques réels.
Décision : Si les liens by-id n’existent plus, prévoyez d’importer en utilisant -d /dev/disk/by-id et fiez‑vous aux GUID, pas à /dev/sdX.

Tâche 5 : Vérifier le cachefile qui peut vous induire en erreur

cr0x@server:~$ sudo zpool get cachefile tank
NAME  PROPERTY   VALUE                       SOURCE
tank  cachefile  /etc/zfs/zpool.cache         local

Sens : Le pool est configuré pour utiliser un chemin de cachefile.
Décision : Si vous avez déplacé des disques vers un nouvel hôte ou changé d’HBA, envisagez d’importer temporairement avec zpool import -o cachefile=none pour éviter d’être empoisonné par un cache obsolète.

Tâche 6 : Importer sans monter pour réduire le risque

cr0x@server:~$ sudo zpool import -N tank

Sens : Pool importé ; datasets non montés.
Décision : Lancez zpool status et zfs mount de façon intentionnelle. C’est la posture sûre quand vous suspectez une défaillance partielle ou un décalage de features.

Tâche 7 : Inspecter la santé et les compteurs d’erreurs vdev après import

cr0x@server:~$ sudo zpool status -v tank
  pool: tank
 state: DEGRADED
status: One or more devices could not be opened.  Sufficient replicas exist for
        the pool to continue functioning in a degraded state.
config:

        NAME                        STATE     READ WRITE CKSUM
        tank                        DEGRADED     0     0     0
          mirror-0                  DEGRADED     0     0     0
            wwn-0x5002538f4123abcd  ONLINE       0     0     0
            10622090183881642744    UNAVAIL      0     0     0  was /dev/sdc

errors: No known data errors

Sens : Un membre est manquant ; ZFS s’en souvient par GUID et chemin précédent.
Décision : Si c’est un mirror et que vous avez le disque, trouvez‑le via l’inventaire matériel et rattachez‑le ; sinon, prévoyez un replace après avoir vérifié que vous ne cherchez pas le mauvais disque.

Tâche 8 : Faire correspondre le GUID manquant de zpool status au GUID feuille dans zdb -C

cr0x@server:~$ sudo zdb -C tank | egrep "guid:|path:"
                    guid: 1183942225006373321
                    path: '/dev/disk/by-id/wwn-0x5002538f4123abcd'
                    guid: 10622090183881642744
                    path: '/dev/disk/by-id/wwn-0x5002538f4fedcba'

Sens : Vous pouvez mapper le GUID manquant à son identité attendue.
Décision : Utilisez‑le pour éviter l’erreur classique : remplacer le mauvais disque parce que /dev/sdX a changé.

Tâche 9 : Vérifier les feature flags qui peuvent bloquer l’import sur cet hôte

cr0x@server:~$ sudo zdb -C tank | sed -n '/features_for_read:/,/hostid:/p'
        features_for_read:
            com.delphix:hole_birth
            org.openzfs:embedded_data
            org.openzfs:project_quota
        hostid: 0x8d3f2a11

Sens : Ces fonctionnalités doivent être supportées pour un import en lecture‑écriture ; parfois un import en lecture seule est possible selon la plateforme/outillage.
Décision : Si votre OpenZFS est plus ancien, mettez à jour les paquets/modules ZFS avant d’essayer l’import. N’« forcez » pas les imports à travers un écart de features à moins d’aimer parier votre poste.

Tâche 10 : Vérifier le mismatch hostid (risque multi‑hôtes)

cr0x@server:~$ hostid
7f3a19c2

Sens : Le hostid courant diffère de celui enregistré dans les labels.
Décision : Enquêtez pour savoir si un autre hôte a encore accès. Si ce pool était partagé via shelf SAS, LUN iSCSI cloné ou snapshot VM, arrêtez et assurez la sémantique single‑writer.

Tâche 11 : Importer depuis un répertoire de périphériques spécifique pour éviter les mauvaises correspondances

cr0x@server:~$ sudo zpool import -d /dev/disk/by-id -N tank

Sens : L’import ne considère que les périphériques trouvés sous le répertoire donné.
Décision : Utilisez‑le quand le système a beaucoup de disques et que vous voulez éviter d’importer le mauvais pool par erreur (oui, ça arrive en lab et sur des VM de récupération « temporaires »).

Tâche 12 : Inspecter les labels directement (lorsque vous suspectez une corruption de labels)

cr0x@server:~$ sudo zdb -l /dev/sdb
------------------------------------
LABEL 0
------------------------------------
    version: 5000
    name: 'tank'
    state: 0
    txg: 1483921
    pool_guid: 5486843001296116957
    guid: 1183942225006373321

Sens : Vous pouvez voir si le label existe, quel txg il annonce, et à quel pool/vdev il appartient.
Décision : Si des labels manquent sur certains vdevs (ou affichent des txg très différents), traitez la situation comme une perte partielle de métadonnées et procédez avec prudence : tentez l’import avec l’ensemble de périphériques le plus complet, et évitez d’écrire tant que vous n’avez pas compris la divergence.

Tâche 13 : Comparer les txg entre périphériques pour trouver la config cohérente la plus récente

cr0x@server:~$ for d in /dev/sdb /dev/sdc; do echo "== $d =="; sudo zdb -l $d | egrep "LABEL|txg:|pool_guid:"; done
== /dev/sdb ==
LABEL 0
    txg: 1483921
    pool_guid: 5486843001296116957
LABEL 1
    txg: 1483921
    pool_guid: 5486843001296116957
== /dev/sdc ==
LABEL 0
    txg: 1481200
    pool_guid: 5486843001296116957
LABEL 1
    txg: 1481200
    pool_guid: 5486843001296116957

Sens : /dev/sdb a un txg plus récent que /dev/sdc.
Décision : Cela peut indiquer que sdc était offline ou en retard. Ne détachez/remplacez pas à l’aveugle ; essayez de remettre l’ancien membre en ligne et de resilver, mais validez d’abord la santé matérielle.

Tâche 14 : Trouver quel slot physique contient un disque (pour retirer le bon)

cr0x@server:~$ sudo udevadm info --query=all --name=/dev/sdb | egrep "ID_SERIAL=|ID_WWN=|ID_PATH="
E: ID_SERIAL=SAMSUNG_SSD_870_QVO_1TB_S5R8...
E: ID_WWN=0x5002538f4123abcd
E: ID_PATH=pci-0000:3b:00.0-scsi-0:0:10:0

Sens : Cela met en corrélation le périphérique Linux avec un WWN stable et un chemin bus.
Décision : Utilisez‑le pour faire correspondre ce que zdb -C dit à ce que vos mains en DC peuvent toucher. Dans un châssis dense, « retirer le disque sdb » n’est pas un plan suffisant.

Tâche 15 : Valider la taille du secteur et les attentes d’alignement (sanité ashift)

cr0x@server:~$ sudo blockdev --getss /dev/sdb
512

Sens : C’est la taille logique du secteur ; le physique peut différer.
Décision : Si zdb -C montre ashift: 12 (4K) mais que le dispositif rapporte 512, ce n’est pas un problème (512e). Si vous voyez ashift: 9 sur des disques modernes, attendez‑vous à des douleurs de performance — ne reconstruisez pas le pool juste pour ça, mais évitez de répéter l’erreur sur de nouveaux pools.

Feuille de diagnostic rapide

Quand vous avez cinq minutes pour arrêter l’hémorragie, il vous faut un ordre d’opérations qui évite les trous de lapin.
Voici la séquence qui trouve le goulot rapidement et vous empêche de « réparer » la mauvaise chose.

1) Confirmer la visibilité : les disques existent‑ils et sont‑ils les bons ?

  • Exécutez lsblk et ls -l /dev/disk/by-id pour confirmer la présence des périphériques.
  • Si SAN/LUN : confirmez que multipath est stable avant de toucher à ZFS.
cr0x@server:~$ lsblk -o NAME,SIZE,MODEL,SERIAL,WWN,TYPE
NAME   SIZE MODEL              SERIAL           WWN                  TYPE
sdb  931.5G Samsung SSD 870    S5R8...          0x5002538f4123abcd   disk
sdc  931.5G Samsung SSD 870    S5R8...          0x5002538f4fedcba    disk

Décision : Si les disques ne sont pas visibles, arrêtez. Réparez le câblage/HBA/multipath d’abord. ZFS ne peut pas importer des disques invisibles.

2) Demandez poliment à ZFS : que voit zpool import ?

cr0x@server:~$ sudo zpool import -d /dev/disk/by-id
   pool: tank
     id: 5486843001296116957
  state: ONLINE
 action: The pool can be imported using its name or numeric identifier.

Décision : S’il apparaît, votre problème n’est probablement pas « le pool a disparu ». C’est souvent des points de montage, des clés ou des avertissements hostid.

3) Si le scan d’import est vide ou suspect, passez à la vérité disque avec zdb -C et zdb -l

cr0x@server:~$ sudo zdb -C | head -n 30
zdb: examining /dev/sdb ...
MOS Configuration:
        pool_guid: 5486843001296116957
        vdev_tree:
            type: 'root'
            children[0]:
                type: 'mirror'

Décision : Si zdb voit des labels mais que zpool import ne voit rien, suspectez un problème de cachefile, de permissions d’accès aux périphériques, ou d’incompatibilité de features.

4) Identifier le type de goulot

  • Non visible : découverte matériel/OS.
  • Visible mais non importable : feature flags, hostid, vdevs manquants ou labels corrompus.
  • Importable mais dégradé : disques manquants, mauvais chemins ou erreurs I/O intermittentes.
  • Importé mais lent : piste distincte — scrubs, resilvers, mauvais recordsize, ou regrets d’ashift.

Erreurs courantes : symptômes → cause → correctif

1) « zpool import n’affiche rien » alors que des disques sont présents

Symptômes : zpool import ne retourne aucun pool ; lsblk montre des disques.

Cause : modules ZFS non chargés, mauvais répertoire de périphériques scanné, ou problèmes de permissions/udev au démarrage dans un initramfs.

Correctif : Chargez ZFS, scannez le bon endroit et vérifiez les labels.

cr0x@server:~$ sudo modprobe zfs
cr0x@server:~$ sudo zpool import -d /dev/disk/by-id
cr0x@server:~$ sudo zdb -l /dev/sdb | head

2) « zpool import avertit : dernier accès par un autre système »

Symptômes : Avertissement d’import concernant un autre hôte ; zdb -C affiche un hostid/hostname différents.

Cause : Le pool a été importé ailleurs récemment (ou un clone a des labels identiques). Risque d’accès double.

Correctif : Confirmez le single‑writer. Éteignez l’autre nœud ou retirez les chemins d’accès. Si vous importez un clone intentionnellement, suivez les procédures appropriées pour éviter les collisions GUID (la gestion des clones varie selon la plateforme).

3) « Il s’importe mais montre des périphériques UNAVAIL avec d’anciens chemins /dev »

Symptômes : vdevs affichent was /dev/sdX ; le nouvel hôte utilise une autre dénomination.

Cause : Les chemins de périphérique ne sont pas stables ; ZFS a stocké un chemin qui ne se résout plus.

Correctif : Utilisez /dev/disk/by-id et laissez ZFS faire la correspondance par GUID ; ensuite nettoyez/remplacez si nécessaire.

4) « Les feature flags empêchent l’import après un rollback OS »

Symptômes : L’import échoue à cause de fonctionnalités non supportées ; zdb -C montre des features que votre pile ne reconnaît pas.

Cause : Vous avez mis à jour ZFS, activé de nouvelles features, puis démarré un ZFS plus ancien (fréquent après démarrage sur un média de secours).

Correctif : Démarrez un système avec OpenZFS égal ou plus récent. Ne touchez pas aux features à la légère ; considérez‑les comme des migrations de schéma.

5) « Un disque montre un txg plus ancien et flappe sans cesse »

Symptômes : Membre mirror hors ligne fréquemment ; txg de label en retard ; zpool status montre des erreurs intermittentes.

Cause : Problèmes I/O réels : câble défectueux, port HBA instable, alimentation intermittente, ou SSD en fin de vie.

Correctif : Remplacez les pièces suspectes. Ne « clear » pas les erreurs en boucle en prétendant que c’est guéri. Lancez un scrub après stabilisation du matériel.

6) « Pool importé sur le mauvais hôte parce que le cachefile pointait vers le mauvais élément »

Symptômes : Import inattendu d’un pool ; le pool ne correspond pas aux vdevs attendus.

Cause : Cachefile obsolète, images VM clonées avec le même zpool.cache, ou plusieurs pools avec des noms similaires.

Correctif : Importez avec -d /dev/disk/by-id, vérifiez avec zdb -C avant de monter, et envisagez -o cachefile=none pendant la récupération.

Trois mini-récits du monde corporate

Mini-récit 1 : Un incident causé par une mauvaise hypothèse

Une PME SaaS a migré une étagère de stockage d’un nœud de base de données à un autre pendant une maintenance.
Le plan était simple : arrêter le nœud A, déplacer les câbles SAS, démarrer le nœud B, importer le pool, terminé. L’opérateur a
fait le travail physique proprement. Le démarrage s’est déroulé correctement. zpool import n’affichait rien.

L’astreinte a supposé, à voix haute, que « ZFS a dû perdre le pool parce que le cachefile n’était pas transféré ».
Ils ont copié /etc/zfs/zpool.cache depuis la dernière sauvegarde du nœud A vers le nœud B. Toujours rien. Puis ils ont rebooté,
parce que bien sûr ils l’ont fait.

Le problème réel était plus banal : le HBA du nœud B a énuméré l’étagère comme un ensemble différent de nœuds de périphériques,
mais les règles udev qui créaient les liens /dev/disk/by-id manquaient dans l’environnement initramfs utilisé pendant le démarrage précoce.
ZFS ne « perdait » rien ; il ne pouvait simplement pas voir d’identifiants stables au moment où il a tenté d’importer.

Quelqu’un a finalement exécuté zdb -C contre les périphériques blocs bruts après le démarrage, a vu des labels intacts et le bon
pool_guid. Ils ont importé avec zpool import -d /dev une fois l’OS pleinement opérationnel, puis corrigé l’initramfs
afin que les chemins by-id existent tôt. L’hypothèse erronée n’était pas que les cachefiles existent ; c’était de croire qu’ils sont
autoritatifs. Ils ne le sont pas.

Mini-récit 2 : Une optimisation qui s’est retournée contre eux

Une entreprise avec un grand cluster d’analytics a estimé que le temps de démarrage était trop long. Leurs nœuds avaient un zoo de disques :
SSD OS, NVMe éphémères, et un ensemble d’étagères JBOD partagées. Quelqu’un a « optimisé » en fixant les imports ZFS à un
répertoire de périphériques restreint et en désactivant les scans larges. Ça a retiré quelques secondes au démarrage. Tout le monde a applaudi.

Des mois plus tard, une étagère a été remplacée sous garantie. Même modèle, même capacité, WWN différents. Les liens udev
sous /dev/disk/by-id ont changé. Le script d’import au démarrage pointait toujours vers un répertoire obsolète et,
pire, filtrait selon un pattern de nommage dépassé.

Le pool ne s’est pas importé automatiquement, mais le système est monté « sain » par ailleurs. La supervision était liée aux
datasets montés, donc les alertes sont arrivées tard. Quand l’astreinte a essayé l’import manuel, il a partiellement assemblé le pool
en utilisant les disques qu’il trouvait, laissant certains vdevs manquants. ZFS a correctement refusé un import propre.

zdb -C a sauvé la situation en rendant le mismatch évident : la config sur disque listait des GUID vdev qui n’existaient
pas dans l’ensemble de périphériques filtré. La solution a été d’arrêter d’être trop malin : scanner largement /dev/disk/by-id,
et alerter explicitement sur « pool non importé », pas seulement « filesystem non monté ». L’optimisation n’était pas mauvaise ; elle
supposait seulement que l’identité matérielle ne changerait jamais. Le matériel adore vous prouver le contraire.

Mini-récit 3 : Une pratique ennuyeuse mais correcte qui a sauvé la mise

Une équipe de services financiers gérait des pools boot mirrorés et un pool raidz séparé pour les données. Ils avaient aussi une habitude stricte et ennuyeuse : chaque baie de disque portait une étiquette physique correspondant au WWN, et chaque ticket de changement incluait un extrait de zdb -C archivé avec le pool_guid et les GUID vdev.

Un trimestre, après un déménagement de datacenter précipité, un pool de données est arrivé dégradé. Deux disques apparaissaient, un manquait.
Le technicien junior sur site insistait sur le fait qu’ils avaient installé tous les disques. L’OS montrait un disque dans la baie,
mais ZFS ne le voyait pas comme faisant partie du pool.

L’astreinte a utilisé le snapshot zdb -C archivé pour identifier le GUID de la feuille manquante et le WWN attendu. Puis ils
l’ont comparé avec udevadm info pour le disque physiquement installé. C’était la bonne taille, le mauvais WWN : quelqu’un avait
inséré une spare d’une autre étagère, même fournisseur, même couleur d’étiquette. Suffisamment similaire pour les humains. Pas assez pour ZFS.

Ils ont remplacé par le bon disque, laissé resilver, et tout est rentré dans l’ordre. Pas d’héroïsme. Pas de perte de données. Juste la sorte
de procédure ennuyeuse qui rend le stockage fiable. Blague #2 : La fonctionnalité de stockage la plus puissante reste « étiquetez vos disques », regrettablement absente de la plupart des brochures marketing.

Listes de contrôle / plan étape par étape

Checklist A : Vous ne pouvez pas importer le pool et vous avez besoin d’abord de réponses

  1. Confirmer les périphériques : lsblk, dmesg pour des resets de lien, et vérifier que /dev/disk/by-id existe.
  2. Exécuter sudo zpool import -d /dev/disk/by-id. Si vide, continuer.
  3. Exécuter sudo zdb -C (mode scan). Confirmer que vous voyez le pool_guid attendu.
  4. Exécuter sudo zdb -l pour chaque disque candidat et comparer pool_guid et txg.
  5. Vérifier features_for_read et confirmer que votre plateforme les supporte.
  6. Vérifier hostid/hostname dans les labels et s’assurer qu’aucun autre hôte ne peut importer.
  7. Décider du mode d’import : d’abord zpool import -N, éventuellement avec -o cachefile=none.

Checklist B : Vous avez trouvé le pool, mais des périphériques sont UNAVAIL

  1. Exécuter zpool status -v et noter les GUID manquants.
  2. Mapper les GUID aux chemins via zdb -C poolname et localiser les WWN correspondants.
  3. Vérifier la présence physique et le chemin bus avec udevadm info.
  4. Corriger d’abord les problèmes de chemin matériel (câbles/HBA/backplane). Puis tenter des actions online/replace.
  5. Après modifications, lancer un scrub ou au moins surveiller la complétion du resilver et les compteurs d’erreurs.

Checklist C : Vous effectuez une migration planifiée (médecine préventive)

  1. Avant l’arrêt, capturez : zpool status -v, zdb -C pool, et les WWN des périphériques.
  2. S’assurer que la cible a une prise en charge OpenZFS compatible des features.
  3. Utiliser des noms de périphériques stables (/dev/disk/by-id) sur la cible ; éviter /dev/sdX dans les scripts.
  4. Importer d’abord avec -N, valider, puis monter intentionnellement.
  5. Ce n’est qu’après un import réussi qu’il faut mettre à jour le cachefile si vous en utilisez un.

FAQ

1) Est‑ce que zdb -C est sûr à exécuter en production ?

C’est orienté lecture et typiquement sûr, mais la « sécurité » dépend de votre contexte opérationnel. Si votre stockage est
déjà en défaillance et que chaque I/O provoque des timeouts, même la lecture des labels peut ajouter de la charge. Utilisez‑le délibérément.

2) Pourquoi zdb -C affiche des chemins qui n’existent pas ?

Parce que les chemins sont des indices, pas l’identité. ZFS stocke le dernier chemin qu’il connaissait. L’identité est le GUID, souvent
corrélé au WWN/devid. Utilisez les liens by-id et le mapping GUID pour réconcilier.

3) Quelle est la différence entre zdb -C et zpool import ?

zpool import tente d’assembler et de présenter les pools importables en utilisant la découverte OS et des heuristiques.
zdb -C extrait la configuration stockée dans les labels, même quand l’assemblage échoue.

4) zdb -C peut‑il aider si le nom du pool est inconnu ?

Oui. Exécutez zdb -C sans nom de pool pour scanner les périphériques et imprimer les configs trouvées. Associez‑le à zdb -l
sur des périphériques spécifiques pour plus de clarté.

5) Que m’indique txg pendant une récupération ?

Un txg plus élevé signifie généralement des métadonnées plus récentes. Si certains labels de vdev annoncent un txg beaucoup plus ancien, ce périphérique
a probablement raté des écritures (offline, défaillant ou déconnecté). C’est un indice, pas un verdict.

6) Si je vois un mismatch hostid, que faire ?

Considérez le risque comme réel tant que l’inverse n’est pas prouvé. Vérifiez que l’autre hôte est hors tension ou n’a aucun chemin d’accès.
Puis importez prudemment (souvent avec -N) et validez avant de monter ou d’écrire.

7) Comment les feature flags dans zdb -C se rapportent‑ils aux échecs d’import ?

Les pools peuvent exiger que certaines features soient comprises. Si votre système ne supporte pas une feature requise, l’import
peut échouer net. La solution est généralement de mettre à jour OpenZFS, pas de « forcer » quoi que ce soit.

8) Pourquoi ZFS se souvient‑il d’un disque manquant par un numéro (GUID) au lieu d’un nom de périphérique ?

Parce que les noms de périphérique ne sont pas stables entre les boots et les hôtes. Les GUID sont des identités stables écrites dans les labels.
C’est l’un des meilleurs choix de conception de ZFS — surtout quand il est 03:00 et que vous êtes fatigué.

9) Puis‑je utiliser zdb -C pour planifier un remplacement de disque en toute sécurité ?

Oui. Utilisez‑le pour mapper le GUID feuille et le chemin by-id/WWN attendu, puis faites correspondre cela à l’inventaire physique via
udevadm info. Cela réduit le risque de remplacer le mauvais disque dans un mirror/raidz.

10) Et si les labels sont corrompus sur un disque ?

Si la redondance existe (mirror/raidz) et que d’autres labels sont intacts, ZFS peut généralement importer et reconstruire.
Si plusieurs périphériques ont des labels endommagés, arrêtez d’improviser et traitez‑le comme une récupération de données : stabilisez le matériel,
clonez les disques si nécessaire, et travaillez à partir de l’ensemble de labels le plus complet que vous pouvez lire.

Conclusion : étapes pratiques suivantes

zdb -C est la façon d’arrêter de deviner. Il lit la configuration du pool directement depuis les labels disque et vous donne
les faits nécessaires quand les imports échouent, que les périphériques sont renommés, ou que quelqu’un jure « rien n’a changé ».

Prochaines étapes que vous pouvez faire aujourd’hui, avant la prochaine panne :

  • Ajoutez une section dans votre runbook : zpool importzdb -Czdb -l avec un arbre de décision.
  • Standardisez l’utilisation de /dev/disk/by-id pour les imports et la supervision, pas /dev/sdX.
  • Archivez la sortie de zdb -C après des changements majeurs de stockage. C’est une assurance peu coûteuse et une excellente preuve sans blâme.
  • Formez votre équipe à mapper GUID → WWN → emplacements physiques. C’est ainsi que l’on évite les incidents « on a remplacé le mauvais disque ».
← Précédent
AVX : instructions qui accélèrent les charges de travail — et calent les CPU
Suivant →
WordPress « Temps d’exécution maximal dépassé » : pourquoi cela arrive et correctifs sûrs

Laisser un commentaire