Labels ZFS corrompus : réparer correctement les échecs d’importation

Cet article vous a aidé ?

Rares sont les pannes de stockage aussi désagréables qu’un pool ZFS qui fonctionnait et qui refuse maintenant de s’importer. Le serveur démarre, les disques tournent, et ZFS vous regarde en disant : « non ». L’erreur varie — labels corrompus, vdevs manquants, GUID incorrects — mais le résultat est le même : vos applications sont indisponibles et votre estomac fait sa propre résilience.

Ce texte explique comment récupérer ce pool de la bonne manière : avec des preuves, en limitant les dégâts supplémentaires et avec un plan que vous pourrez expliquer à votre futur vous. Nous considérerons « labels corrompus » comme un symptôme, pas un diagnostic final. Les labels peuvent être réellement corrompus, ou « corrompus » parce que vos chemins de périphérique ont changé, votre HBA a menti, ou vous avez importé le mauvais pool sur le mauvais hôte. ZFS dit généralement la vérité. Les humains sont la pièce peu fiable.

Ce que sont les labels ZFS (et ce que « corrompu » signifie vraiment)

ZFS ne garde pas un unique « superbloc » en un endroit précieux. Il écrit la configuration critique du pool et l’identité des périphériques dans quatre labels par vdev : deux au début du disque (ou de la partition) et deux à la fin. Dans ces labels, vous trouverez des éléments tels que :

  • GUID et nom du pool
  • GUID du vdev et topologie
  • Pointeurs de transaction group (TXG) vers « où la vérité se trouve maintenant »
  • Uberblocks : un ensemble de points de contrôle qui permettent à ZFS de trouver l’état cohérent le plus récent

Quand ZFS indique qu’un label est corrompu, cela peut signifier plusieurs choses :

  • Le checksum du label ne se vérifie pas (corruption réelle).
  • Le périphérique ne contient pas les GUID attendus pour le pool/vdev (mauvais disque, disque obsolète, ou changement de mappage de périphérique).
  • Seuls certains labels sont lisibles (dommages partiels, problèmes en fin de disque, particularités d’armoire).
  • Le label est correct, mais le reste de l’arbre de métadonnées pointe vers des blocs illisibles (un problème d’E/S plus profond qui remonte comme un problème de label/uberblock).

Une nuance que beaucoup oublient sous pression : l’importation ZFS est une opération principalement en lecture. L’import peut échouer parce que les lectures expirent, pas parce que les métadonnées sont logiquement incorrectes. Un chemin qui « marche à peu près » sous faible charge peut s’effondrer lorsque ZFS scanne les labels, lit les uberblocks et tente d’ouvrir chaque vdev. Donc, quand vous voyez « label corrompu », ne saisissez pas immédiatement les outils destructeurs. D’abord, prouvez de quel type de « corrompu » il s’agit.

Faits intéressants et contexte historique

  1. Les labels ZFS sont redondants par conception : quatre par vdev. En perdre un est courant ; en perdre les quatre indique généralement un sérieux événement d’E/S ou d’écrasement.
  2. Les premières conceptions de ZFS évitaient les points de défaillance uniques : l’approche multi-label fait partie de la philosophie « pas de superblock » qui a façonné ZFS depuis le début.
  3. L’identité du pool est basée sur GUID, pas sur le nom : le nom du pool est convivial ; le GUID est ce en quoi ZFS a confiance.
  4. Les chemins de périphérique ne sont pas des identifiants stables : « /dev/sda » a toujours été une mauvaise idée pour des pools en production. Les chemins persistants comme by-id existent parce que le monde est chaotique.
  5. Les ZFS modernes conservent plusieurs uberblocks : il peut revenir à un état cohérent antérieur lorsque le dernier TXG est illisible.
  6. Le comportement d’import a évolué : des flags comme -F (rewind) et des fonctionnalités comme les checkpoints existent parce que les vrais systèmes plantent, et les métadonnées ont besoin de mécanismes de secours sûrs.
  7. La réalité des secteurs 4K a frappé fort : des erreurs d’ashift (par exemple 512e vs 4Kn) ont causé des pools qui « fonctionnaient » jusqu’à ce qu’on remplace un disque et que rien ne s’aligne comme prévu.
  8. Les HBAs et expanders peuvent mentir : des réinitialisations de lien transitoires et des bugs de firmware d’armoire ont historiquement pris l’apparence de corruptions.
  9. ZFS est conservateur à l’import : il préfère refuser d’importer plutôt que d’importer un pool d’une manière qui risque des dommages silencieux.

Import failures: the failure modes that matter

1) Real label corruption (overwrite or media damage)

Ce cas survient lorsqu’un élément écrit sur le début/la fin du périphérique (outil de partitionnement mal dirigé, « wipefs » malheureux, dd mal orienté, un contrôleur RAID initialisant des métadonnées), ou quand le disque ne peut plus lire de façon fiable ces régions. Dans le cas d’un écrasement, c’est souvent soudain et total : ZFS ne peut identifier aucunement le vdev. Dans le cas d’un média dégradé, c’est intermittent : labels lisibles un démarrage, illisibles au suivant.

2) Wrong device mapping (the classic)

Les noms de périphérique changent. L’ordre des contrôleurs change. Le multipath est à moitié configuré. Quelqu’un a déplacé des disques entre des étagères. L’OS présente maintenant vos disques différemment et ZFS ne trouve pas ce à quoi il s’attend. Cela ressemble à de la corruption parce que ZFS voit des disques, mais les labels qu’il lit ne sont pas ceux appartenant au pool que vous essayez d’importer.

3) Missing vdevs (single disk missing in a RAIDZ is not “optional”)

Les mirrors peuvent souvent boiter avec un membre manquant. Les vdevs RAIDZ sont plus exigeants : un disque manquant peut empêcher l’import, selon la redondance et quel disque est parti. Aussi : si vous avez construit le pool avec des partitions et qu’un disque apparaît maintenant comme périphérique entier, ZFS peut ne pas le reconnaître.

4) I/O path failure masquerading as metadata failure

L’import nécessite des lectures à travers la topologie. Un câble SAS instable, une alimentation marginale, des problèmes d’expander, ou un HBA mourant peuvent se transformer en erreurs « label corrompu » parce que les lectures expirent ou renvoient des données absurdes. C’est là que vous arrêtez de croire aux solutions logicielles et commencez à inspecter le matériel comme s’il vous devait de l’argent.

5) Feature flag / version mismatch (less common, still real)

Importer un pool créé sur une version OpenZFS plus récente dans une implémentation plus ancienne peut échouer. Typiquement, cela ne se présente pas comme un « label corrompu », mais dans des environnements désordonnés les messages peuvent être confus. Gardez-le sur la liste, mais pas en tête.

6) You imported the wrong pool (yes, this happens)

Laboratoires partagés, disques réutilisés, environnements de staging. La machine voit plusieurs pools. Vous importez le mauvais, puis vous vous demandez pourquoi les datasets attendus n’y sont pas. Ou vous exportez le mauvais et faites tomber la production d’une manière qui rend tout le monde soudainement « disponible pour un appel rapide ».

Blague #1 : Le moyen le plus rapide de découvrir que votre inventaire d’actifs est incomplet est d’essayer d’importer un pool ZFS pendant une panne.

Playbook de diagnostic rapide

Ceci est la séquence « ne pas se perdre ». L’objectif est de trouver rapidement le goulot d’étranglement : périphériques erronés, périphériques manquants, ou E/S défaillantes.

First: confirm what ZFS sees without changing anything

  • Lister les pools importables (zpool import).
  • Essayer un import en lecture seule si visible (zpool import -o readonly=on).
  • Capturer les erreurs mot à mot. Ne les résumez pas de mémoire. Votre mémoire n’est pas un journal.

Second: confirm device identity stability

  • Utilisez des chemins persistants : /dev/disk/by-id (Linux) ou des nœuds de périphérique stables sur votre OS.
  • Mappez les numéros de série aux emplacements/baies (via lsblk, udevadm, smartctl).
  • Vérifiez que chaque disque attendu est présent et que l’OS peut le lire sans erreurs.

Third: check for I/O errors and timeouts

  • Regardez les logs du noyau pour les réinitialisations et les timeouts (dmesg, journalctl).
  • Faites des contrôles SMART rapides et lisez les compteurs d’erreurs.
  • Si les lectures échouent, arrêtez la « chirurgie ZFS » et réparez d’abord le chemin matériel.

Fourth: inspect labels directly

  • Utilisez zdb -l sur les périphériques candidats pour voir les GUID pool/vdev.
  • Comparez ce que vous trouvez avec ce que l’import attend.

Fifth: only then attempt rewind/recovery imports

  • Essayez d’abord l’import en lecture seule.
  • Utilisez -F (rewind) avec précaution et comprenez le rollback.
  • N’utilisez les flags extrêmes que lorsque vous pouvez expliquer le rayon d’impact.

Tâches pratiques : commandes, sorties, décisions

Voici les actions de terrain. Chaque tâche inclut une commande, une sortie d’exemple, ce que cela signifie, et la décision à en tirer. Supposons Linux avec OpenZFS sauf indication contraire.

Task 1: List pools ZFS thinks exist

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

        tank                          ONLINE
          mirror-0                    ONLINE
            ata-ST8000VN004-2M2101_ZA1A2B3C  ONLINE
            ata-ST8000VN004-2M2101_ZD4E5F6G  ONLINE

   pool: prod
     id: 1692242210959834013
  state: FAULTED
 status: One or more devices contains corrupted data.
 action: The pool cannot be imported due to damaged devices or data.
   see: zpool(8)
 config:

        prod                          FAULTED  corrupted data
          raidz2-0                    FAULTED
            ata-WDC_WD120EMFZ-11A6JA0_9HGK1AAA  UNAVAIL  invalid label
            ata-WDC_WD120EMFZ-11A6JA0_9HGK2BBB  ONLINE
            ata-WDC_WD120EMFZ-11A6JA0_9HGK3CCC  ONLINE
            ata-WDC_WD120EMFZ-11A6JA0_9HGK4DDD  ONLINE
            ata-WDC_WD120EMFZ-11A6JA0_9HGK5EEE  ONLINE
            ata-WDC_WD120EMFZ-11A6JA0_9HGK6FFF  ONLINE

Ce que cela signifie : ZFS peut voir un pool nommé prod mais un périphérique est UNAVAIL invalid label. C’est soit un disque manquant, un périphérique erroné, ou un label illisible.

Décision : Ne lancez pas zpool import -f pour l’instant. D’abord, vérifiez que le disque existe et qu’il est lisible au niveau OS, puis inspectez les labels.

Task 2: Try a read-only import (safe first touch)

cr0x@server:~$ sudo zpool import -o readonly=on prod
cannot import 'prod': one or more devices is currently unavailable

Ce que cela signifie : La lecture seule n’outrepasse pas les exigences de vdev manquants. Le pool ne peut toujours pas s’assembler.

Décision : Identifiez le périphérique manquant/indisponible et s’il est vraiment absent ou simplement mal identifié.

Task 3: Verify the OS sees the expected block devices

cr0x@server:~$ lsblk -o NAME,SIZE,MODEL,SERIAL,WWN,TYPE | sed -n '1,12p'
NAME   SIZE MODEL              SERIAL      WWN                TYPE
sda  10.9T WDC WD120EMFZ-11A6  9HGK2BBB    0x50014ee2b1a2b222  disk
sdb  10.9T WDC WD120EMFZ-11A6  9HGK3CCC    0x50014ee2b1a2b333  disk
sdc  10.9T WDC WD120EMFZ-11A6  9HGK4DDD    0x50014ee2b1a2b444  disk
sdd  10.9T WDC WD120EMFZ-11A6  9HGK5EEE    0x50014ee2b1a2b555  disk
sde  10.9T WDC WD120EMFZ-11A6  9HGK6FFF    0x50014ee2b1a2b666  disk

Ce que cela signifie : Nous attendions six disques ; seuls cinq sont présents. Le périphérique marqué « invalid label » pourrait en réalité être absent, pas corrompu.

Décision : Vérifiez la connectivité physique, l’emplacement dans l’armoire, la visibilité HBA et les logs. N’écrasez pas de labels pour un disque que l’OS ne voit même pas.

Task 4: Check kernel logs for link resets and missing device events

cr0x@server:~$ sudo journalctl -k -b | egrep -i 'sd[a-z]|sas|ata|reset|timeout|I/O error' | tail -n 20
kernel: ata12: hard resetting link
kernel: ata12: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
kernel: sd 12:0:0:0: [sdf] tag#18 FAILED Result: hostbyte=DID_TIME_OUT driverbyte=DRIVER_OK
kernel: sd 12:0:0:0: [sdf] tag#18 CDB: Read(16) 88 00 00 00 00 00 00 00 00 10 00 00 00 08 00 00
kernel: blk_update_request: I/O error, dev sdf, sector 16 op 0x0:(READ) flags 0x80700 phys_seg 1 prio class 0
kernel: sd 12:0:0:0: [sdf] Synchronizing SCSI cache
kernel: sd 12:0:0:0: [sdf] Stopping disk

Ce que cela signifie : Il y avait un sdf, mais il a expiré sur des lectures proches du début du disque (le secteur 16 est le territoire des labels). C’est un « label corrompu » classique causé par une défaillance d’E/S.

Décision : Traitez cela d’abord comme un problème matériel/chemin. Reseat, changez le câble, essayez un autre port HBA, vérifiez l’alimentation. Si c’est une défaillance d’un seul disque dans un RAIDZ2, planifiez le remplacement du disque et laissez ZFS guérir — une fois que vous pourrez importer.

Task 5: Enumerate persistent device IDs to avoid /dev/sdX roulette

cr0x@server:~$ ls -l /dev/disk/by-id/ | egrep 'WDC_WD120EMFZ|ST8000' | head
lrwxrwxrwx 1 root root  9 Dec 26 10:12 ata-WDC_WD120EMFZ-11A6JA0_9HGK2BBB -> ../../sda
lrwxrwxrwx 1 root root  9 Dec 26 10:12 ata-WDC_WD120EMFZ-11A6JA0_9HGK3CCC -> ../../sdb
lrwxrwxrwx 1 root root  9 Dec 26 10:12 ata-WDC_WD120EMFZ-11A6JA0_9HGK4DDD -> ../../sdc
lrwxrwxrwx 1 root root  9 Dec 26 10:12 ata-WDC_WD120EMFZ-11A6JA0_9HGK5EEE -> ../../sdd
lrwxrwxrwx 1 root root  9 Dec 26 10:12 ata-WDC_WD120EMFZ-11A6JA0_9HGK6FFF -> ../../sde

Ce que cela signifie : Ces IDs survivent aux redémarrages et au renommage des périphériques mieux que les noms sdX.

Décision : Lors de l’importation ou du remplacement de périphériques, utilisez ces identifiants stables (ou leurs équivalents sur votre OS). Si votre pool a été construit avec des chemins instables, envisagez de migrer la configuration une fois que vous êtes redevenu stable.

Task 6: Inspect labels on a known-good disk

cr0x@server:~$ sudo zdb -l /dev/disk/by-id/ata-WDC_WD120EMFZ-11A6JA0_9HGK2BBB | sed -n '1,25p'
------------------------------------
LABEL 0
------------------------------------
    version: 5000
    name: 'prod'
    state: 0
    txg: 1984567
    pool_guid: 1692242210959834013
    vdev_guid: 15812007741234567890
    hostid: 1029384756
    hostname: 'fileserver-a'
    top_guid: 7321098765432109876
    guid_sum: 12345678901234567890

Ce que cela signifie : Ce disque appartient clairement au pool prod (le pool GUID correspond à la liste d’import). Les labels sont lisibles.

Décision : Utilisez ceci comme référence. Vérifiez maintenant le disque « mauvais » (s’il est visible) pour la lisibilité des labels et s’il appartient au même pool.

Task 7: Inspect labels on the suspect disk (if it appears at all)

cr0x@server:~$ sudo zdb -l /dev/sdf
failed to unpack label 0
failed to unpack label 1
failed to unpack label 2
failed to unpack label 3

Ce que cela signifie : Les quatre labels sont illisibles. Ce n’est pas « un bit flippé ». C’est habituellement des régions illisibles, un problème de traduction du contrôleur, ou le disque renvoie du non-sens.

Décision : Si c’est un vdev redondant (mirror/RAIDZ avec suffisamment de parité), planifiez le remplacement de sdf. Si la redondance est insuffisante, vous êtes maintenant en territoire de récupération de données et vous devriez éviter toute écriture sur le périphérique.

Task 8: Validate whether the disk is actually failing (SMART)

cr0x@server:~$ sudo smartctl -a /dev/sdf | egrep -i 'Reallocated|Pending|Uncorrect|Offline|CRC|SMART overall|Power_On_Hours'
SMART overall-health self-assessment test result: FAILED!
  5 Reallocated_Sector_Ct   0x0033   001   001   010    Pre-fail  Always       -       3120
197 Current_Pending_Sector  0x0012   001   001   000    Old_age   Always       -       128
198 Offline_Uncorrectable   0x0010   001   001   000    Old_age   Offline      -       128
199 UDMA_CRC_Error_Count    0x003e   200   199   000    Old_age   Always       -       12
Power_On_Hours             0x0032   062   062   000    Old_age   Always       -       31240

Ce que cela signifie : Le disque est en train de lâcher et le lien présente aussi des erreurs CRC (cela peut venir du câble/backplane). L’illisibilité des labels est cohérente avec cela.

Décision : Remplacez le disque. Envisagez aussi de changer le câble/le slot, car les erreurs CRC sont souvent liées au chemin. Réparez les deux ou vous reviendrez vite ici.

Task 9: Attempt import with device scanning limited (reduce confusion)

cr0x@server:~$ sudo zpool import -d /dev/disk/by-id prod
cannot import 'prod': one or more devices is currently unavailable

Ce que cela signifie : Même résultat, mais vous avez réduit la chance que ZFS corresponde à des nœuds de périphériques obsolètes ou inattendus ailleurs.

Décision : Si le périphérique manquant est réel et que la redondance le permet, envisagez d’importer en dégradé avec -m (si supporté/approprié), mais seulement après avoir confirmé quel vdev est manquant et quelle redondance vous avez réellement.

Task 10: Import the pool (degraded) when redundancy allows

cr0x@server:~$ sudo zpool import -o readonly=on -m prod
cannot import 'prod': I/O error
        Destroy and re-create the pool from
        a backup source.

Ce que cela signifie : Même l’import dégradé n’est pas possible parce que le pool a besoin de données qui ne peuvent pas être lues depuis les périphériques restants, ou le chemin d’E/S est malade au-delà d’un disque.

Décision : Arrêtez et réévaluez : vous pouvez avoir plus d’un disque défaillant, ou votre HBA/backplane laisse tomber des périphériques. Revenez au matériel et vérifiez que chaque disque restant est stable et lisible.

Task 11: Identify exactly which vdev GUID is missing using zdb (when import listing is vague)

cr0x@server:~$ sudo zdb -C -e prod | sed -n '1,80p'
MOS Configuration:
        pool_guid: 1692242210959834013
        pool_name: prod
        vdev_children: 1
        vdev_tree:
            type: 'root'
            id: 0
            guid: 7321098765432109876
            children[0]:
                type: 'raidz'
                id: 0
                guid: 882233445566778899
                nparity: 2
                children[0]:
                    type: 'disk'
                    id: 0
                    guid: 15812007741234567890
                    path: '/dev/disk/by-id/ata-WDC_WD120EMFZ-11A6JA0_9HGK2BBB'
                children[1]:
                    type: 'disk'
                    id: 1
                    guid: 15812007749876543210
                    path: '/dev/disk/by-id/ata-WDC_WD120EMFZ-11A6JA0_9HGK3CCC'
                children[2]:
                    type: 'disk'
                    id: 2
                    guid: 15812007740000111111
                    path: '/dev/disk/by-id/ata-WDC_WD120EMFZ-11A6JA0_9HGK1AAA'

Ce que cela signifie : ZFS attend un disque avec le numéro de série 9HGK1AAA qui est actuellement absent/illisible. Vous avez maintenant une cible concrète pour le travail physique.

Décision : Trouvez ce disque exact dans le châssis/armoire. S’il est présent mais non détecté, dépannez le chemin. S’il est parti ou mort, remplacez-le — puis importez et laissez resilver.

Task 12: If the pool imported, verify status before doing anything else

cr0x@server:~$ sudo zpool status -v prod
  pool: prod
 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: Replace the device using 'zpool replace'.
  scan: scrub repaired 0B in 0 days 00:42:17 with 0 errors on Sun Dec 22 03:12:19 2025
config:

        NAME                                                   STATE     READ WRITE CKSUM
        prod                                                   DEGRADED     0     0     0
          raidz2-0                                             DEGRADED     0     0     0
            ata-WDC_WD120EMFZ-11A6JA0_9HGK1AAA                 UNAVAIL      0     0     0  cannot open
            ata-WDC_WD120EMFZ-11A6JA0_9HGK2BBB                 ONLINE       0     0     0
            ata-WDC_WD120EMFZ-11A6JA0_9HGK3CCC                 ONLINE       0     0     0
            ata-WDC_WD120EMFZ-11A6JA0_9HGK4DDD                 ONLINE       0     0     0
            ata-WDC_WD120EMFZ-11A6JA0_9HGK5EEE                 ONLINE       0     0     0
            ata-WDC_WD120EMFZ-11A6JA0_9HGK6FFF                 ONLINE       0     0     0

errors: No known data errors

Ce que cela signifie : Le pool est monté en mode dégradé ; il vous indique exactement quoi faire ensuite.

Décision : Remplacez le périphérique manquant et laissez resilver. Ne pas scruber d’abord « par précaution ». Remplacez d’abord, puis lancez un scrub après resilver si vous voulez plus de confiance.

Task 13: Replace the failed disk with a new one (same slot, new serial)

cr0x@server:~$ sudo zpool replace prod \
  /dev/disk/by-id/ata-WDC_WD120EMFZ-11A6JA0_9HGK1AAA \
  /dev/disk/by-id/ata-WDC_WD120EMFZ-11A6JA0_NEW9SER1AL
cr0x@server:~$ sudo zpool status prod
  pool: prod
 state: DEGRADED
  scan: resilver in progress since Fri Dec 26 10:44:01 2025
        1.23T scanned at 1.12G/s, 220G issued at 201M/s, 10.9T total
        220G resilvered, 1.94% done, 0 days 15:10:22 to go
config:

        NAME                                                   STATE     READ WRITE CKSUM
        prod                                                   DEGRADED     0     0     0
          raidz2-0                                             DEGRADED     0     0     0
            replacing-0                                        DEGRADED     0     0     0
              ata-WDC_WD120EMFZ-11A6JA0_9HGK1AAA               UNAVAIL      0     0     0  cannot open
              ata-WDC_WD120EMFZ-11A6JA0_NEW9SER1AL             ONLINE       0     0     0  (resilvering)
            ata-WDC_WD120EMFZ-11A6JA0_9HGK2BBB                 ONLINE       0     0     0
            ata-WDC_WD120EMFZ-11A6JA0_9HGK3CCC                 ONLINE       0     0     0
            ata-WDC_WD120EMFZ-11A6JA0_9HGK4DDD                 ONLINE       0     0     0
            ata-WDC_WD120EMFZ-11A6JA0_9HGK5EEE                 ONLINE       0     0     0
            ata-WDC_WD120EMFZ-11A6JA0_9HGK6FFF                 ONLINE       0     0     0

errors: No known data errors

Ce que cela signifie : Le resilver progresse. S’il bloque, vous avez probablement d’autres problèmes de chemin ou un autre disque marginal sous charge.

Décision : Surveillez le resilver et les logs système. Si vous voyez des timeouts, arrêtez les manœuvres et corrigez la stabilité matérielle.

Task 14: If import complains about “active pool” or host ownership, verify and decide

cr0x@server:~$ sudo zpool import prod
cannot import 'prod': pool may be in use from other system
use '-f' to import anyway

Ce que cela signifie : ZFS pense que le pool a été importé ailleurs dernièrement (ou n’a pas été exporté proprement). Cela peut être légitime (stockage partagé) ou obsolète (crash).

Décision : Avant d’utiliser -f, confirmez que l’autre hôte n’utilise pas réellement le pool. Si vous importez en force le même pool deux fois sans support de clustering, vous allez générer de la corruption en un temps record.

Task 15: Use rewind (-F) only after measuring the rollback

cr0x@server:~$ sudo zpool import -F -n prod
Would be able to return pool to state as of TXG 1984501
Would discard approximately 12 seconds of transactions

Ce que cela signifie : -n est votre ceinture de sécurité. Il montre ce qui serait perdu si vous reveniez en arrière. Ici, c’est trivial (quelques secondes), ce qui signifie généralement un crash en cours de TXG ou un dernier uberblock illisible.

Décision : Si la fenêtre de rollback est acceptable, procédez avec zpool import -F prod. Si c’est des heures/jours, arrêtez et réévaluez ; vous importez peut-être les mauvais périphériques ou vous faites face à une corruption plus large.

Task 16: After import, verify mount behavior and avoid surprise writes

cr0x@server:~$ sudo zfs get -o name,property,value,mountpoint,mounted -r mountpoint,mounted prod | head -n 12
NAME                PROPERTY    VALUE    MOUNTPOINT   MOUNTED
prod                mountpoint  /prod    /prod        yes
prod/home           mountpoint  /home    /home        yes
prod/backups        mountpoint  /backups /backups     no
prod/backups        mounted     no       -            -

Ce que cela signifie : Tout ne se monte pas automatiquement, et cela peut être intentionnel. En mode récupération, cela peut aussi indiquer que vous avez importé en readonly ou avec des réglages d’altroot différents.

Décision : Confirmez les propriétés avant de remettre les services en ligne. Ne laissez pas une application écrire dans le mauvais point de montage parce que vous avez paniqué et utilisé un altroot temporaire hier.

Blague #2 : « Ça marchait en staging » est rassurant jusqu’à ce que vous vous rappeliez que staging est l’endroit où les données vont mourir en silence.

Trois mini-récits d’entreprise depuis le terrain

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

L’entreprise avait un cluster de stockage pour des artefacts internes — caches de build, couches de conteneurs, sorties CI. Pas glamour, mais tout en dépendait. Un matin, après une maintenance de routine, le nœud primaire a redémarré et le pool ne s’importait pas. L’alerte indiquait « invalid label » sur deux disques. L’ingénieur d’astreinte a supposé que les disques étaient morts parce que le tableau matériel montrait quelques voyants ambres. Histoire simple : remplacer les disques, resilver, passer à autre chose.

Ils ont remplacé le premier disque. Le pool ne s’importait toujours pas. Ils ont remplacé le second. Maintenant le pool non seulement ne s’importait pas ; il n’arrivait plus à assembler suffisamment de métadonnées pour tenter un rewind. La courbe de « confiance » avait l’allure d’une piste de ski.

La mauvaise hypothèse : les voyants ambres n’indiquaient pas une défaillance des disques ; c’étaient des problèmes de négociation de lien dans un backplane particulier. Les disques étaient bons. Le backplane présentait de façon intermittente de mauvaises adresses SAS, et l’OS renommait les périphériques au reboot. ZFS voyait des « disques différents » avec des « mauvais labels », ce qui ressemblait à de la corruption mais était en réalité une instabilité d’identité.

Quand ils ont enfin comparé les sorties de zdb -l avec les numéros de série, ils ont réalisé que les « mauvais » disques avaient été remplacés par de bons disques qui n’avaient jamais fait partie du pool. ZFS n’était pas têtu ; il avait raison. Le chemin de récupération a été moche mais instructif : réintroduire les disques originaux (maintenant sur un chemin HBA stable), importer en lecture seule, et remplacer un par un correctement.

Après coup, ils ont changé deux choses. D’abord, une règle : ne pas remplacer les disques avant d’avoir prouvé l’identité du périphérique et la stabilité du chemin de lecture. Ensuite, ils ont cessé de se fier aux noms sdX dans tout runbook. « /dev/sdb » est une ambiance, pas un identifiant.

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

Une autre organisation a décidé que le temps d’import après panne était trop long. Ils avaient un grand pool avec beaucoup de vdevs et de nombreux périphériques derrière des expanders. Quelqu’un a lu comment accélérer la découverte en limitant les chemins de scan et en cachant agressivement les mappages vdev. Ils ont affiné les scripts de démarrage pour importer en utilisant un ensemble restreint de nœuds de périphériques et ont réduit les règles udev pour « diminuer le bruit ». Les imports sont effectivement devenus plus rapides — jusqu’à ce que ce ne soit plus le cas.

Des mois plus tard, un petit incident d’alimentation a fait que certains disques sont montés plus lentement que d’habitude. Le script d’import est passé tôt, n’a scanné que les chemins « rapides », et a conclu que le pool avait des vdevs manquants. Puis il a tenté un import forcé avec des flags de récupération parce que « c’est ce que fait le script quand l’import échoue ». Le pool a importé en état dégradé avec un rewind. Les services ont repris. Tout le monde a félicité l’automatisation.

Le coût est apparu plus tard sous forme d’erreurs applicatives étranges : données récentes manquantes dans quelques datasets, des fichiers revenant à des versions plus anciennes. Le rewind avait supprimé une petite mais significative fenêtre de transactions. Ce n’était pas une grosse perte, mais du genre qui fait regarder les auditeurs comme si vous aviez avoué aimer les pannes surprises.

L’optimisation a échoué parce qu’elle a troqué la justesse contre la vitesse sans garde-fous. L’import n’est pas le moment d’être malin. ZFS assemble un état cohérent ; vos scripts ne devraient pas « aider » en sautant des disques qui sont simplement lents à apparaître.

Ils ont corrigé cela en rendant la logique de démarrage à nouveau ennuyeuse : attendre le settle udev, scanner les chemins by-id stables, et refuser d’utiliser automatiquement les flags de rewind. Les flags de récupération sont devenus une décision humaine avec un humain lisant d’abord l’estimation de rollback.

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

Une entreprise du secteur financier gérait un pool ZFS alimentant un ensemble d’archives de conformité. La charge était write-once, read-sometimes, avec des scrubs de vérification périodiques. C’était le genre de système qu’on oublie jusqu’au jour où on en a besoin — exactement quand on ne veut pas de surprises.

Ils avaient une règle peu sexy : chaque remplacement de disque nécessitait d’enregistrer le numéro de série du disque, l’emplacement en baie, et le mappage GUID vdev ZFS dans un ticket. Aucune exception. Ils avaient aussi un exercice trimestriel permanent : simuler un import sur un hôte de staging avec des pools exportés (lecture seule) pour vérifier que leur procédure de récupération correspondait toujours à la réalité.

Un jour, un contrôleur a rendu l’âme et a été remplacé sous garantie. Après remplacement, l’ordonnancement des périphériques a changé et quelques disques sont apparus avec des noms OS différents. L’import du pool a d’abord échoué avec « cannot open » et « invalid label » sur ce qui semblait être des périphériques aléatoires.

L’ingénieur d’astreinte n’a pas deviné. Il a extrait le dernier mappage du système de tickets, l’a comparé aux sorties de zdb -l sur l’hôte courant, et a reconstruit la liste correcte de périphériques en utilisant les chemins by-id. Le pool s’est importé proprement, sans rewind requis, sans commander de disques de remplacement dans la panique.

Ce n’était pas héroïque. C’était correct. Les pratiques ennuyeuses ne remportent pas d’applaudissements, mais elles vous laissent dormir.

Erreurs courantes (symptômes → cause racine → fix)

1) Symptom: “invalid label” on a disk after a reboot

Cause racine : Le disque est présent mais illisible au début/à la fin (erreurs d’E/S), ou l’OS a mappé un disque différent au chemin attendu.

Correction : Vérifiez les logs pour des timeouts d’E/S, confirmez les numéros de série via lsblk/udevadm, inspectez les labels avec zdb -l. Remplacez uniquement après avoir prouvé qu’il s’agit du bon disque et qu’il échoue réellement.

2) Symptom: Import shows “pool may be in use from other system”

Cause racine : Pool non exporté proprement, ou il est réellement importé ailleurs (JBOD partagé, disques réutilisés, risque de split-brain).

Correction : Confirmez que l’autre hôte est hors ligne ou a exporté le pool. N’utilisez zpool import -f qu’après vérification. Si le pool peut être actif ailleurs, arrêtez-vous. L’import double est une douleur auto-infligée.

3) Symptom: Import succeeds only with -F rewind

Cause racine : L’uberblock/TXG le plus récent est illisible (souvent à cause d’un disque défaillant ou d’une réinitialisation du contrôleur pendant l’écriture), ou des périphériques récents sont manquants lors de la tentative d’import.

Correction : Lancez zpool import -F -n d’abord et lisez la fenêtre de rollback. Si elle est petite, procédez. Si elle est grande, suspectez des périphériques erronés ou une corruption plus étendue. Vérifiez la stabilité matérielle avant de répéter les imports.

4) Symptom: Pool imports but datasets mount incorrectly or not at all

Cause racine : Import effectué avec altroot, readonly, ou un cachefile changé ; ou bien les propriétés mountpoint ont été modifiées dans la pagaille.

Correction : Inspectez zfs get mountpoint,mounted, confirmez zpool get cachefile, et évitez les « correctifs temporaires » qui persistent. Rendre le comportement de montage explicite avant de relancer les services.

5) Symptom: Import hangs for a long time

Cause racine : Un disque expire sur des lectures ; ZFS attend une E/S lente pendant la découverte des labels/métadonnées.

Correction : Vérifiez les logs du noyau, lancez SMART, et cherchez un périphérique isolé qui ralentit le système. Réparez le chemin ou retirez le périphérique défaillant si la redondance le permet.

6) Symptom: “corrupted data” immediately after someone “cleaned partitions”

Cause racine : Un outil a écrasé les zones de label (début/fin) ou a changé les offsets de partition.

Correction : Arrêtez d’écrire sur les disques. Identifiez quels disques ont encore des labels intacts via zdb -l. Si suffisamment de labels survivent et que la redondance le permet, importez et remplacez. Sinon, restaurez depuis une sauvegarde ou faites appel à une récupération spécialisée.

7) Symptom: After HBA swap, half the disks show as different sizes or 512/4K mismatch

Cause racine : Le contrôleur présente une taille de secteur logique différente ou une traduction changeante (512e vs 4Kn), ce qui perturbe les hypothèses sur ashift et l’alignement.

Correction : Confirmez avec lsblk -t et vérifiez les tailles de secteur logiques/physiques. Gardez des HBAs/firmwares cohérents quand c’est possible. Ne reconstruisez pas la topologie aveuglément ; validez d’abord, puis remplacez avec précaution.

Checklists / step-by-step plan

Checklist A: Before you touch anything (evidence collection)

  1. Capturez la sortie de zpool import et sauvegardez-la quelque part sûr.
  2. Capturez lsblk -o NAME,SIZE,MODEL,SERIAL,WWN.
  3. Capturez des extraits de logs du noyau autour de la découverte des disques et des erreurs.
  4. Si le pool est visible, essayez zpool import -o readonly=on (et enregistrez le résultat).

Checklist B: Decide if this is hardware/path or metadata

  1. Si les logs montrent des timeouts/réinitialisations/erreurs d’E/S : traitez d’abord comme matériel/chemin.
  2. Si les disques sont stables et lisibles mais que ZFS indique des labels invalides : suspectez un mauvais mappage de périphérique ou des labels écrasés.
  3. Utilisez zdb -l sur plusieurs disques pour confirmer la cohérence des pool GUID.

Checklist C: Safe import workflow

  1. Préférez importer via des chemins stables (-d /dev/disk/by-id).
  2. Tentez un import en lecture seule.
  3. Si « pool in use », confirmez l’état de l’autre hôte avant d’utiliser -f.
  4. Si nécessaire, évaluez le rewind avec -F -n, puis décidez.
  5. Une fois importé, vérifiez zpool status et les montages des datasets avant de relancer les applications.

Checklist D: Recovery after import (make it healthy)

  1. Remplacez les périphériques défaillants/indisponibles en utilisant des identifiants stables.
  2. Surveillez le resilver et les logs ; si des erreurs apparaissent, arrêtez et corrigez le chemin d’E/S.
  3. Après la fin du resilver, lancez un scrub dans une fenêtre contrôlée.
  4. Documentez ce qui s’est passé : quel disque, quel slot, quel GUID, ce que les logs ont montré.

One quote worth keeping in your head

Idée paraphrasée (attribuée à W. Edwards Deming) : Sans données, vous n’êtes qu’une autre personne avec une opinion.

C’est pourquoi vous collectez d’abord les sorties, puis vous agissez. La récupération ZFS n’est pas un sport basé sur les ressentis.

FAQ

1) What exactly is a “ZFS label”?

Une petite région de métadonnées stockée de façon redondante (quatre copies par vdev) au début et à la fin de chaque périphérique. Elle décrit l’identité du pool, la topologie, et les pointeurs nécessaires pour trouver l’état actif.

2) Does “corrupt label” always mean the disk is bad?

Non. Cela peut signifier que le disque est manquant, que le chemin du périphérique a changé, que le HBA renvoie des données invalides, ou que les zones de label ont été écrasées. Prouvez l’état du disque et l’identité avant de remplacer.

3) Can I repair labels manually?

En fonctionnement normal, vous ne « réparez » pas les labels en écrivant des octets magiques. Le schéma correct est : importer si possible, puis zpool replace le périphérique défaillant/manquant et laisser ZFS reconstruire la redondance. La réécriture manuelle des labels est pour les spécialistes et survient généralement après « on a déjà perdu ».

4) Is zpool import -f dangerous?

Ça peut l’être. Si le pool est réellement actif sur un autre hôte, forcer l’import risque des écritures simultanées et une corruption réelle. Si l’autre hôte est mort et que le pool n’a pas été exporté, -f est souvent la bonne option — après vérification.

5) What does zpool import -F actually do?

Il revient le pool à un transaction group (TXG) antérieur qui semble cohérent et lisible. Vous perdrez les transactions les plus récentes après ce point. Exécutez toujours avec -n d’abord pour voir l’estimation du rollback.

6) My pool imports, but it’s degraded. Should I scrub immediately?

Non. Remplacez d’abord les périphériques manquants/défaillants. Scruber un pool dégradé augmente la charge de lecture et peut pousser des disques marginaux au-delà de leurs limites. Resilver pour restaurer la redondance, puis scrub pour la confiance.

7) Why do imports sometimes hang?

Parce que ZFS attend de l’E/S. Un seul disque qui expire sur des lectures peut bloquer la découverte. Vérifiez les logs du noyau et SMART ; ne relancez pas indéfiniment les imports pendant que le matériel chauffe.

8) How do I avoid this next time?

Utilisez des identifiants de périphérique stables, documentez le mappage disque→slot, scrubez régulièrement, surveillez les réinitialisations de lien/erreurs CRC, et testez votre procédure de récupération quand vous n’êtes pas en train de paniquer.

9) If one disk’s labels are unreadable, can ZFS still import?

Ça dépend de la topologie et de la redondance. Les mirrors sont tolérants. RAIDZ dépend de la parité et de quel disque manque. Si ZFS ne peut pas assembler l’arbre vdev ou satisfaire les exigences de redondance, il refusera l’import.

10) Should I ever use zpool import -D (destroyed pools) in label-corruption cases?

Seulement lorsque vous avez des preuves solides que le pool a été accidentellement détruit/effacé et que vous faites une récupération intentionnelle. Ce n’est pas un outil de première ligne pour un « invalid label » et il peut compliquer la situation si utilisé à la légère.

Conclusion : quoi faire la prochaine fois

Quand ZFS dit « labels corrompus », ce n’est pas une invitation à commencer des tentatives de réparation au hasard. C’est une demande pour réduire l’incertitude. Vérifiez ce que ZFS voit, confirmez l’identité des périphériques, cherchez des défaillances de chemin d’E/S, et inspectez les labels avec zdb avant de changer quoi que ce soit.

Étapes pratiques suivantes :

  • Standardisez l’utilisation de noms de périphérique persistants pour les pools (by-id/WWN ou équivalent de votre plateforme).
  • Ajoutez une étape de runbook qui collecte zpool import, lsblk et les logs du noyau avant tout remplacement.
  • Surveillez les réinitialisations CRC/lien et traitez-les comme des précurseurs, pas des détails.
  • Exigez une approbation humaine pour les imports avec rewind (-F) et exécutez toujours -n d’abord.
  • Gardez un mappage simple serial disque → baie → GUID vdev. C’est ennuyeux, et c’est pour ça que ça marche.
← Précédent
Comment ne pas se laisser tromper par le « FPS marketing » : règles simples
Suivant →
ZFS pour PostgreSQL : la stratégie de dataset et de sync qui fonctionne

Laisser un commentaire