Il y a un moment dans la vie de tout administrateur ZFS où l’on réalise que le pool n’est pas juste « ZFS ». C’est un ensemble spécifique de capacités sur disque, négocié entre le code que vous exécutez et l’historique des mises à jour que vous avez autorisées. Et la façon la plus honnête de voir cette réalité est une commande qui ressemble à une faute de frappe jusqu’à ce qu’elle vous sauve le week-end : zpool get feature@*.
Ceci n’est pas un inventaire cosmétique. Les flags de fonctionnalités déterminent quelles métadonnées sont écrites, quelles opérations sont possibles et — surtout — quels autres systèmes peuvent importer ou répliquer le pool. Si vous vous êtes déjà demandé « pourquoi ce pool ne s’importe pas sur l’hôte plus ancien ? » ou « pourquoi la réplication a cassé après une mise à jour ? », vous avez déjà rencontré les flags de fonctionnalités. Vous n’avez juste pas été correctement présenté.
Ce que feature@* est réellement (et pourquoi c’est important)
Les flags de fonctionnalités ZFS sont des marqueurs sur disque de capacités spécifiques. Ils ont remplacé l’ancien schéma monolithique de « version du pool », où un entier unique tentait de représenter toute l’histoire de compatibilité. Les flags sont plus granulaires : un pool peut prendre en charge une fonctionnalité moderne mais pas une autre. Plus important encore, une fonctionnalité peut être :
- désactivée (non disponible et non utilisée)
- activée (disponible pour utilisation ; le pool en est informé)
- active (réellement utilisée sur disque ; vous avez franchi la ligne de compatibilité)
La nuance pour les opérateurs est la suivante : « activée » signifie généralement que vous pouvez encore revenir en arrière (en pratique : vous n’avez pas encore écrit de métadonnées incompatibles), tandis que « active » signifie que vous ne pouvez probablement pas — du moins pas sans détruire et recréer le pool ou effectuer des migrations complexes. C’est pourquoi un pool peut s’importer sur une machine plus ancienne jusqu’au jour où il ne le peut plus : vous n’avez pas « mis à niveau le pool », vous avez activé une fonctionnalité en utilisant quelque chose qui la nécessitait.
Deux autres termes que vous verrez dans les propriétés des flags :
- local : défini directement sur ce pool (souvent via
zpool upgradeou un comportement automatique) - received : défini parce que vous avez reçu un pool répliqué ou certaines métadonnées via send/receive (moins courant au niveau du pool que des datasets, mais peut apparaître selon les outils et le comportement de la plateforme)
Blague #1 (courte, pertinente) : Les flags de fonctionnalités ZFS sont comme un règlement d’entreprise — personne ne les lit jusqu’à ce qu’ils deviennent la raison pour laquelle vous ne pouvez pas « simplement revenir en arrière ».
Faits et historique : comment on en est arrivé là
Les spécialistes du stockage aiment faire comme si nous étions intemporels, mais ZFS a une lignée très précise. Voici des faits concrets et des points de contexte historique qui changent la façon d’interpréter feature@* dans le monde réel :
- Les versions de pool étaient une impasse. Au début, ZFS suivait un seul numéro de « version » pour le pool. Les fournisseurs se sont éloignés ; la compatibilité est devenue autant politique que technique.
- Les flags de fonctionnalités ont rendu la compatibilité composable. Au lieu de « version 28 », vous obtenez une liste : améliorations du spacemap, classes d’allocation, prise en charge du chiffrement, etc.
- OpenZFS a unifié un écosystème fragmenté. Différents systèmes d’exploitation livraient des implémentations ZFS différentes ; les flags ont été un mécanisme de survie pour la portabilité.
- « Activée » vs « active » est de l’or opérationnel. Cela vous permet de planifier une mise à niveau sans immédiatement engager des modifications incompatibles sur disque.
- Certaines fonctionnalités sont des portes à sens unique. Une fois « active », vous ne pouvez généralement pas revenir en arrière sans reconstruire. Ce n’est pas une bizarrerie de ZFS ; c’est le coût de l’évolution sûre des formats de métadonnées.
- Les flags affectent la réplication. Les flux
zfs sendpeuvent nécessiter que la cible prenne en charge les fonctionnalités représentées dans le flux. Cela devient visible lorsque vous mélangez des versions d’OS ou des vendeurs d’appliances. - Les pools de démarrage sont spéciaux. Sur certaines plateformes, le support du chargeur d’amorçage prend du retard par rapport aux fonctionnalités du système de fichiers. Un pool de démarrage peut devenir non amorçable même si l’OS peut l’importer sans problème.
- Le chiffrement n’est pas « juste une propriété de dataset ». Le chiffrement natif ZFS dépend du support des fonctionnalités ; les pools créés sur des piles plus anciennes ne le gagnent pas magiquement sans que les flags correspondants soient présents.
- Les gros blocs ont changé l’économie des charges séquentielles. La possibilité d’utiliser en toute sécurité des tailles d’enregistrement plus grandes (et les fonctionnalités de gros blocs sous-jacentes) peut réduire les frais de métadonnées et améliorer le débit — jusqu’à ce que cela heurte des E/S aléatoires petites.
Comment lire la sortie de zpool get feature@* comme un opérateur
Démystifions la sortie. Sur un système OpenZFS, vous verrez des propriétés comme :
cr0x@server:~$ sudo zpool get -H -o name,property,value,source feature@* tank
tank feature@async_destroy enabled local
tank feature@empty_bpobj active local
tank feature@lz4_compress active local
tank feature@spacemap_histogram active local
tank feature@enabled_txg enabled local
tank feature@extensible_dataset enabled local
tank feature@bookmarks enabled local
tank feature@filesystem_limits enabled local
tank feature@device_removal disabled -
tank feature@allocation_classes enabled local
tank feature@embedded_data active local
tank feature@hole_birth active local
tank feature@large_blocks active local
tank feature@sha512 enabled local
tank feature@skein enabled local
tank feature@encryption enabled local
Trois colonnes importent au quotidien :
- property : le nom de la fonctionnalité, comme
feature@large_blocks - value :
disabled,enabled, ouactive - source : d’où provient ce réglage (
local,-, etc.)
La lecture opérationnelle est :
- disabled : cette fonctionnalité n’est pas disponible sur ce pool. Soit votre implémentation ZFS ne la connait pas, soit le pool n’a pas été mis à niveau pour l’annoncer.
- enabled : le pool annonce la fonctionnalité et peut l’activer si nécessaire. Vous pouvez encore être compatible avec des systèmes plus anciens si rien n’a rendu la fonctionnalité « active ».
- active : quelque chose l’a utilisée et a écrit de nouvelles métadonnées. Votre « surface d’import » a rétréci : les systèmes dépourvus de cette fonctionnalité n’importeront pas.
Il y a une distinction subtile mais cruciale : zpool upgrade peut passer de nombreuses fonctionnalités en « enabled » sans les rendre « active ». Mais dès que vous faites certaines opérations — activer des types de compression, utiliser des bookmarks, créer des datasets chiffrés, activer la suppression de périphérique, etc. — vous pouvez passer en « active ». Le « basculement » n’est pas dramatique ; c’est un écrit de métadonnées. ZFS ne fait pas de cinéma. Il fait des formats de métadonnées irrévocables avec d’excellents checksums.
Blague #2 (courte, pertinente) : La manière la plus rapide d’apprendre les flags de fonctionnalités est de les ignorer une fois — rien n’enseigne comme un pool qui refuse de s’importer à 2h du matin.
Tâches pratiques (commandes + interprétation)
Ci‑dessous se trouvent des tâches d’opérateur que j’ai réellement utilisées en environnements proches de la production. Chaque tâche inclut des commandes et ce que vous devriez en conclure.
Task 1: Dump de tous les flags de pool (la baseline)
cr0x@server:~$ sudo zpool get feature@* tank
NAME PROPERTY VALUE SOURCE
tank feature@async_destroy enabled local
tank feature@empty_bpobj active local
tank feature@lz4_compress active local
tank feature@spacemap_histogram active local
tank feature@enabled_txg enabled local
tank feature@extensible_dataset enabled local
tank feature@bookmarks enabled local
tank feature@filesystem_limits enabled local
tank feature@device_removal disabled -
tank feature@allocation_classes enabled local
tank feature@embedded_data active local
tank feature@hole_birth active local
tank feature@large_blocks active local
tank feature@sha512 enabled local
tank feature@skein enabled local
tank feature@encryption enabled local
Interprétation : Ce pool est déjà au‑delà de la « compatibilité legacy » parce que plusieurs fonctionnalités sont active. Si vous comptiez importer ce pool sur un hôte plus ancien (ou une appliance d’un autre fournisseur), vous devriez vérifier que cet hôte prend en charge l’ensemble des fonctionnalités actives, pas seulement les activées.
Task 2: Afficher seulement les fonctionnalités “active” (la ligne de compatibilité que vous avez franchie)
cr0x@server:~$ sudo zpool get -H -o property,value feature@* tank | awk '$2=="active"{print}'
feature@empty_bpobj active
feature@lz4_compress active
feature@spacemap_histogram active
feature@embedded_data active
feature@hole_birth active
feature@large_blocks active
Interprétation : Cette liste est votre ensemble « must support » pour tout système devant importer le pool. Si un site DR ne peut pas importer, commencez par comparer ses fonctionnalités supportées avec cette liste active.
Task 3: Afficher seulement les “enabled mais pas active” (ce qui pourrait devenir votre prochain problème)
cr0x@server:~$ sudo zpool get -H -o property,value feature@* tank | awk '$2=="enabled"{print}'
feature@async_destroy enabled
feature@enabled_txg enabled
feature@extensible_dataset enabled
feature@bookmarks enabled
feature@filesystem_limits enabled
feature@allocation_classes enabled
feature@sha512 enabled
feature@skein enabled
feature@encryption enabled
Interprétation : Ce sont des capacités « armées ». Vous ne les utilisez pas nécessairement encore, mais une action d’un futur administrateur (ou un futur comportement par défaut) pourrait les activer. Si vous maintenez des cibles de compatibilité strictes (par ex. un récepteur de réplication plus ancien), vous voudrez peut‑être mettre en place des politiques autour des fonctionnalités autorisées à devenir actives.
Task 4: Capturer un « snapshot de capacité du pool » pour revue des changements
cr0x@server:~$ sudo zpool get -H -o property,value,source feature@* tank | sort > /var/tmp/tank.features.$(date +%F).txt
cr0x@server:~$ tail -n 5 /var/tmp/tank.features.$(date +%F).txt
feature@spacemap_histogram active local
feature@userobj_accounting disabled -
feature@zilsaxattr disabled -
feature@zpool_checkpoint disabled -
feature@zstd_compress disabled -
Interprétation : Traitez l’état des flags comme des migrations de schéma dans une base de données. Sauvez‑le avant les mises à niveau, avant les déplacements de plateforme et avant d’activer de nouvelles capacités comme le chiffrement ou des vdevs spéciaux.
Task 5: Vérifier la version du pool / infos sur le système de fonctionnalités ensemble (réduire les suppositions)
cr0x@server:~$ sudo zpool status -x
all pools are healthy
cr0x@server:~$ modinfo zfs 2>/dev/null | head -n 5
filename: /lib/modules/6.8.0/kernel/zfs/zfs.ko
version: 2.2.4-1
license: CDDL
description: ZFS
author: OpenZFS
Interprétation : Savoir « quel ZFS vous avez » importe quand vous comparez le support des fonctionnalités entre hôtes. Même pool, modules ZFS différents, fonctionnalités supportées différentes. Évitez la pensée « c’est Linux donc tout va bien » — la disponibilité des fonctionnalités OpenZFS dépend de la version livrée.
Task 6: Voir ce que zpool upgrade ferait avant de le faire
cr0x@server:~$ sudo zpool upgrade
This system supports ZFS pool feature flags.
All pools are formatted using feature flags.
Some supported features are not enabled on the following pools.
Note that the pool may be upgraded to use these features, but doing so
may prevent the pool from being imported on other systems that do not
support the features.
POOL FEATURE
tank project_quota
tank spacemap_v2
Interprétation : C’est votre « diff ». Il vous indique les fonctionnalités que votre logiciel actuel supporte mais que votre pool n’a pas encore activées. Si votre site DR ou la cible de réplication est en retard, cette sortie est une étiquette d’avertissement, pas une suggestion.
Task 7: Mettre à niveau un pool délibérément (et comprendre l’impact)
cr0x@server:~$ sudo zpool upgrade tank
This system supports ZFS pool feature flags.
Enabled the following features on 'tank':
project_quota
spacemap_v2
Interprétation : Cela marque typiquement des fonctionnalités comme enabled, pas nécessairement active. Mais vous avez maintenant rendu possible que des opérations futures les activent — et vous avez peut‑être réduit la compatibilité avec des systèmes qui ne reconnaissent même pas les fonctionnalités activées, selon l’implémentation. Hypothèse sûre : après avoir activé de nouvelles fonctionnalités, testez l’import sur tous les systèmes « must import ».
Task 8: Trouver des échecs d’import liés aux fonctionnalités (lire l’erreur, ne pas improviser)
cr0x@drhost:~$ sudo zpool import
pool: tank
id: 1234567890123456789
state: UNAVAIL
status: The pool uses the following feature(s) not supported on this system:
spacemap_histogram
embedded_data
action: Upgrade the system to support the pool features, or recreate the pool from backup.
see: zpool-features(7)
config:
tank UNAVAIL unsupported feature(s)
raidz2-0 ONLINE
sda ONLINE
sdb ONLINE
sdc ONLINE
sdd ONLINE
Interprétation : Cette sortie vous donne la liste des coupables. Croisez‑la avec les « active features » sur la source. Si l’hôte DR ne peut pas être mis à jour, vos options sont : conserver un pool de compatibilité pour la réplication, utiliser des copies au niveau fichier, ou reconstruire un pool sans ces fonctionnalités (ce qui nécessite généralement une migration des données).
Task 9: Mapper les flags de pool au comportement des datasets qui vous importent (exemple chiffrement)
cr0x@server:~$ sudo zpool get -H -o value feature@encryption tank
enabled
cr0x@server:~$ sudo zfs create -o encryption=on -o keyformat=passphrase tank/secret
Enter new passphrase:
Re-enter new passphrase:
cr0x@server:~$ sudo zfs get -H -o property,value encryption,keystatus tank/secret
encryption on
keystatus available
Interprétation : Le support de la fonctionnalité au niveau du pool est un prérequis. Le pool peut annoncer feature@encryption comme activé, mais cela devient opérationnellement pertinent une fois que vous créez des datasets chiffrés. Cela peut aussi affecter les flux de réplication et la gestion des clés au démarrage.
Task 10: Vérifier l’alignement des fonctionnalités de compression (zstd vs lz4)
cr0x@server:~$ sudo zpool get -H -o value feature@lz4_compress tank
active
cr0x@server:~$ sudo zpool get -H -o value feature@zstd_compress tank
disabled
cr0x@server:~$ sudo zfs set compression=lz4 tank/data
cr0x@server:~$ sudo zfs get -H -o value compression tank/data
lz4
Interprétation : Si vous répliquez vers une cible qui ne supporte pas zstd, utiliser zstd en source peut devenir un piège de migration. Les flags de fonctionnalités peuvent vous prévenir avant que vous ne commenciez à « optimiser » avec le codec le plus récent.
Task 11: Détecter si les gros blocs sont en jeu (et pourquoi ça change le tuning)
cr0x@server:~$ sudo zpool get -H -o value feature@large_blocks tank
active
cr0x@server:~$ sudo zfs get -H -o property,value recordsize tank/data
recordsize 128K
cr0x@server:~$ sudo zfs set recordsize=1M tank/data
cr0x@server:~$ sudo zfs get -H -o value recordsize tank/data
1M
Interprétation : Les gros blocs peuvent être un gros gain pour les E/S séquentielles (sauvegardes, médias, analyses), mais ce n’est pas gratuit. Une fois que vous commencez à augmenter recordsize, les charges d’écritures aléatoires peuvent vous punir par une amplification read-modify-write. Les flags de fonctionnalités vous disent si le pool peut supporter les métadonnées nécessaires pour les gros blocs en toute sécurité.
Task 12: Confirmer ce qui a changé après une opération risquée (diff avant/après)
cr0x@server:~$ sudo zpool get -H -o property,value feature@* tank | sort > /var/tmp/features.before
cr0x@server:~$ sudo zfs set compression=zstd tank/data
cannot set property for 'tank/data': 'compression' feature is not enabled
cr0x@server:~$ sudo zpool get -H -o property,value feature@* tank | sort > /var/tmp/features.after
cr0x@server:~$ diff -u /var/tmp/features.before /var/tmp/features.after
Interprétation : ZFS a refusé le changement parce que le pool n’annonce pas la fonctionnalité zstd. C’est le chemin heureux : vous apprenez sans activer quoi que ce soit. Faites ce genre de « test d’échec intentionnel » pendant une fenêtre de changement quand vous considérez de nouvelles fonctionnalités.
Task 13: Relier les flags aux comptes d’espace et au comportement de l’allocateur (spacemap histogram)
cr0x@server:~$ sudo zpool get -H -o value feature@spacemap_histogram tank
active
cr0x@server:~$ sudo zdb -bbbbb tank 2>/dev/null | head -n 20
Interprétation : Quand vous êtes profond dans des discussions sur les performances de l’allocateur ou la fragmentation, les fonctionnalités liées au spacemap importent. Si vous comparez deux pools et que l’un a des fonctionnalités de spacemap plus récentes actives, leur comportement sous churn peut différer suffisamment pour invalider des benchmarks naïfs.
Task 14: Vérifier que le récepteur de réplication ne va pas décrocher (contrôle pratique de compatibilité)
cr0x@source:~$ sudo zpool get -H -o property,value feature@* tank | awk '$2=="active"{print $1}' | sort > /var/tmp/source.active
cr0x@receiver:~$ sudo zpool get -H -o property,value feature@* backup | awk '$2!="disabled"{print $1}' | sort > /var/tmp/recv.known
cr0x@receiver:~$ comm -23 /var/tmp/source.active /var/tmp/recv.known
feature@embedded_data
feature@spacemap_histogram
Interprétation : Ce n’est pas un oracle de compatibilité parfait (les flux de datasets et le support de propriétés importent aussi), mais c’est un fort avertissement précoce. Si le récepteur ne reconnaît même pas une fonctionnalité active sur la source, attendez‑vous à des problèmes d’import et possiblement de send/receive.
Trois mini-histoires du monde de l’entreprise
Mini-histoire 1 : Un incident causé par une mauvaise hypothèse
Le scénario était classique de « maturité hybride ». La production tournait sur un Linux plus récent avec un module OpenZFS moderne. Le DR tournait sur une appliance fournisseur plus ancienne qui n’avait pas été mise à jour depuis un moment parce que « le stockage est stable » et personne ne voulait rouvrir la conversation d’achats. La réplication était basée sur des fichiers pour certains datasets et sur ZFS send/receive pour d’autres, et ça fonctionnait la plupart du temps — jusqu’au jour où ça n’a plus marché.
Une défaillance matérielle de routine en production a dégénéré en un problème d’installation. Le runbook DR disait : « Importez le pool répliqué sur le DR et remettez les services en route. » L’astreinte a fait exactement cela, et l’import du pool a échoué avec « unsupported feature(s) ». La réaction humaine immédiate était prévisible : se méfier de la boîte DR, soupçonner un câble, réinsérer les disques, essayer encore, remplacer les contrôleurs, essayer encore. Le temps a disparu dans le vide où l’espoir va mourir.
La cause racine était ennuyeuse : à un moment, la production avait activé de nouvelles fonctionnalités pendant une fenêtre de maintenance — rien de dramatique, juste « rester à jour ». Ces fonctionnalités sont restées activées silencieusement, puis sont devenues actives quand quelqu’un a utilisé une capacité qui en dépendait (le genre d’action qui ressemble à un ajustement de dataset, pas à un événement de compatibilité de pool). Le DR n’a jamais été mis à jour, et personne n’a comparé les flags de fonctionnalités entre environnements.
La correction n’a pas été un hack brillant. Ils ont mis à jour la plateforme DR (après un processus d’exception d’urgence qui a pris moins de temps que le dépannage raté), ont ré‑importé et ont récupéré. L’action de postmortem qui a vraiment tenu était simple : les snapshots des flags de fonctionnalités sont devenus partie de chaque revue de préparation DR. Pas comme un exercice de feuille de calcul — la sortie réelle des commandes stockée avec les enregistrements de changement.
Mini-histoire 2 : Une optimisation qui s’est retournée contre eux
Une autre organisation avait un problème de performance : les jobs analytiques nocturnes prenaient trop de temps, et l’équipe stockage était sous pression pour « rendre ZFS plus rapide ». Quelqu’un a suggéré d’augmenter la taille des enregistrements et d’utiliser une compression plus récente. Idées raisonnables, et en labo ça avait l’air super : meilleur débit, moins d’I/O par gigaoctet. L’équipe a programmé le changement et l’a déployé en confiance.
Puis les tickets de support sont arrivés. Des services sensibles à la latence partageant le pool ont commencé à manquer leurs SLO. Les jobs analytiques étaient plus heureux, mais la charge mixte s’est transformée en combat à l’arme blanche : les écritures aléatoires et réécritures ont commencé à payer le prix de l’amplification read-modify-write, et le comportement du cache est devenu bizarre. En plus, ils étaient passés dans un territoire de fonctionnalités plus récentes, ce qui a rendu leur plan de rollback « au cas où » fantaisiste. Ils pouvaient revenir sur des propriétés ; ils ne pouvaient pas revenir dans le temps.
L’échec technique n’était pas « les gros blocs sont mauvais ». C’était de supposer que le pool était une charge unique. Les flags de fonctionnalités faisaient partie de l’histoire parce qu’ils ont rendu l’optimisation durable : une fois que le pool et les datasets vivaient dans le nouveau monde des métadonnées, déplacer les données vers des systèmes plus anciens — ou même mettre en place un environnement parallèle avec une compatibilité plus ancienne — est devenu un projet.
La résolution finale a été plus architecturale qu’héroïque : séparer les charges de travail en pools distincts (ou au moins classes de vdev séparées quand approprié), utiliser les gros enregistrements où le pattern d’accès est vraiment séquentiel, et garder des valeurs par défaut conservatrices pour les datasets à usage général. La leçon rédigée en clair par l’équipe était : « Chaque bouton de performance est aussi un bouton de compatibilité, même s’il n’en a pas l’air. »
Mini-histoire 3 : Une pratique ennuyeuse mais correcte qui a sauvé la mise
Celle‑ci n’a rendu personne célèbre, ce qui est exactement pourquoi ça a marché. Une équipe plateforme avait une règle : avant toute mise à jour liée à ZFS — noyau, paquet OpenZFS ou upgrade de pool — ils capturaient un « bundle d’état de stockage » standard. Il incluait zpool status, zpool get feature@*, des propriétés clés de datasets et un test de réplication rapide vers un récepteur de staging. Aucune exception, pas de « on le fera plus tard ».
Pendant une actualisation d’infrastructure, ils devaient déplacer un pool sur du nouveau matériel rapidement. Le plan était d’exporter, déplacer les disques, importer. Simple. L’équipe a exécuté son bundle d’état et a remarqué un détail inconfortable : une poignée de fonctionnalités étaient activées mais pas actives, et un des consommateurs en aval était un système plus ancien utilisé pour une archive de conformité. Ce système n’avait pas de chemin de mise à jour dans le calendrier.
Parce qu’ils l’ont détecté tôt, ils ont pris une décision délibérée : n’activer aucune nouvelle fonctionnalité pendant la fenêtre de migration, garder le chemin de réplication de l’archive stable, et programmer une mise à jour à plus long terme du système d’archive. Ils ont aussi vérifié que l’environnement de boot cible pouvait gérer l’ensemble des fonctionnalités du pool, évitant un piège de pool de démarrage.
La migration a eu lieu, rien n’a cassé, et personne en dehors de l’équipe n’a remarqué — ce qui est le plus grand compliment en opérations. Dans la rétrospective, le « geste héroïque » était littéralement un fichier texte contenant la sortie de zpool get feature@*, capturée au bon moment.
Feuille de route de diagnostic rapide
Quand quelque chose sent le roussi — échecs d’import, erreurs de réplication, régressions de performance — les flags de fonctionnalités ne sont pas toujours la cause, mais ils sont souvent le moyen le plus rapide d’arrêter de deviner. Voici une feuille de route pragmatique qui vous amène rapidement à « est‑ce un problème de compatibilité de fonctionnalités ? » puis pivote vers la chasse au goulot.
Étape 1 : Déterminez si vous avez un problème de compatibilité ou de performance
Si le problème est « impossible d’importer », c’est presque certainement de la compatibilité. Si le problème est « lent », les flags peuvent contribuer indirectement (comportement de l’allocateur, tailles de blocs, etc.), mais vous devez toujours identifier le goulot.
cr0x@server:~$ sudo zpool import
cr0x@server:~$ sudo zpool status -x
cr0x@server:~$ sudo zpool get -H -o property,value feature@* tank | awk '$2!="disabled"{print}' | head
Interprétation : Les erreurs d’import listent explicitement les fonctionnalités non supportées. Si l’import fonctionne, passez aux vérifications de performance.
Étape 2 : Pour les problèmes d’import/réplication, comparez les fonctionnalités « active » avec l’autre hôte
cr0x@source:~$ sudo zpool get -H -o property,value feature@* tank | awk '$2=="active"{print $1}' | sort
cr0x@target:~$ sudo zpool get -H -o property,value feature@* backup | awk '$2!="disabled"{print $1}' | sort
Interprétation : Toute fonctionnalité active sur la source inconnue/désactivée sur la cible est un signal rouge. Ne dépannez pas des câbles quand vos métadonnées parlent clairement.
Étape 3 : Pour la performance, vérifiez les goulots classiques ZFS dans l’ordre
- État du pool et erreurs de vdev (un pool dégradé peut être « fonctionnel » mais lent)
- Saturation I/O (un vdev accroché pendant que les autres sont inactifs)
- Pression ARC (misses de cache provoquant de l’activité disque)
- Comportement des écritures sync (SLOG ou absence de SLOG ; applis faisant des fsync massifs)
- Mauvais alignement recordsize/compression (workload non aligné)
cr0x@server:~$ sudo zpool status -v tank
cr0x@server:~$ sudo zpool iostat -v tank 1 10
cr0x@server:~$ sudo arcstat 1 10
cr0x@server:~$ sudo zpool get -H -o property,value ashift,autotrim,feature@* tank | head -n 20
cr0x@server:~$ sudo zfs get -r -H -o name,property,value recordsize,compression,atime,sync tank/data | head -n 20
Interprétation : Les flags ne vous diront pas « ce vdev est saturé », mais ils vous diront si vous êtes dans un monde où certaines optimisations sont possibles ou déjà actives. Combinez les deux : capacités et comportement actuel.
Erreurs courantes : symptômes et corrections
Erreur 1 : Considérer « enabled » comme « sûr » sans comprendre l’activation
Symptôme : « Nous avons mis à niveau le pool il y a des semaines et tout allait bien ; maintenant l’import DR échoue. »
Pourquoi ça arrive : Vous avez activé des fonctionnalités, puis plus tard effectué une action qui en a activé une. La rupture apparaît avec retard.
Correction : Suivez les fonctionnalités active dans le temps. Mettez en place une politique : si la cible DR/replication est en retard, limitez les opérations susceptibles d’activer des fonctionnalités incompatibles tant que les cibles ne sont pas mises à niveau.
Erreur 2 : Mettre à niveau un pool de boot comme s’il s’agissait d’un pool de données
Symptôme : Le système importe le pool correctement depuis un environnement de secours, mais ne démarre pas normalement.
Pourquoi ça arrive : Le support du chargeur d’amorçage n’est pas identique au support ZFS en runtime sur certaines plateformes.
Correction : Validez les contraintes du chargeur d’amorçage avant d’activer de nouvelles fonctionnalités sur les pools de boot. Gardez les pools de boot conservateurs ; mettez‑les à niveau uniquement avec confirmation explicite de la plateforme et un plan de rollback.
Erreur 3 : Supposer que send/receive fonctionnera « tout seul » entre versions mixtes
Symptôme : La réplication échoue avec des erreurs sur des fonctionnalités non supportées, des bookmarks ou l’incompatibilité de flux.
Pourquoi ça arrive : La source crée des flux nécessitant des fonctionnalités non supportées sur le récepteur (au niveau du pool et du dataset).
Correction : Standardisez les versions des récepteurs ou utilisez un hôte de mise en scène de compatibilité qui peut recevoir depuis la source puis renvoyer dans un format contraint (quand possible). Le plus souvent, la correction est « mettre à niveau le récepteur ».
Erreur 4 : Activer des fonctionnalités brillantes pendant un incident
Symptôme : Une tentative de récupération empire la situation : le nouveau pool ne peut pas être importé ailleurs, la chaîne de réplication casse, ou les options de rollback disparaissent.
Pourquoi ça arrive : Sous pression, quelqu’un exécute zpool upgrade -a ou change des propriétés pour « améliorer la performance », activant des fonctionnalités involontairement.
Correction : En mode incident, geler l’état des fonctionnalités. Faites de « pas de mise à niveau de pool pendant un incident » une règle permanente sauf si la mise à niveau est la solution explicite avec un plan de compatibilité confirmé.
Erreur 5 : Utiliser les flags comme proxy de tuning de performance
Symptôme : « Nous avons activé tout et c’est toujours lent », ou la performance régresse après « mise à niveau ».
Pourquoi ça arrive : Les fonctionnalités sont des capacités, pas des multiplicateurs de débit. La performance dépend de la disposition des vdevs, du workload, de l’ARC, du comportement sync, de la fragmentation, et plus encore.
Correction : Utilisez la feuille de route de diagnostic rapide : prouvez le goulot avec iostat/latence/statistiques ARC d’abord, puis décidez si les fonctionnalités et propriétés sont pertinentes.
Listes de contrôle / plan étape par étape
Checklist : Avant d’exécuter zpool upgrade en production
- Capturer l’état actuel des fonctionnalités.
- Identifier chaque système qui doit importer ou recevoir depuis ce pool.
- Confirmer leurs versions ZFS/OpenZFS et les fonctionnalités supportées.
- Exécuter
zpool upgrade(sans arguments) pour voir ce qui changerait. - Décider : mettre à niveau maintenant, plus tard, ou sélectionner par pool.
- Mettre en scène et tester l’import/receive sur un hôte non‑prod si possible.
cr0x@server:~$ sudo zpool get -H -o property,value,source feature@* tank | sort > /var/tmp/tank.features.pre
cr0x@server:~$ sudo zpool upgrade
cr0x@server:~$ sudo zpool upgrade tank
cr0x@server:~$ sudo zpool get -H -o property,value,source feature@* tank | sort > /var/tmp/tank.features.post
cr0x@server:~$ diff -u /var/tmp/tank.features.pre /var/tmp/tank.features.post | head -n 50
Checklist : Quand vous planifiez une migration de plateforme
- Sur la source : lister les fonctionnalités actives.
- Sur la cible : confirmer qu’elle reconnaît/supporte ces fonctionnalités.
- Confirmer les contraintes du pool de boot si le pool est critique pour le démarrage.
- Exporter/importer dans une fenêtre contrôlée ; vérifier avec un calendrier de scrub.
cr0x@source:~$ sudo zpool get -H -o property,value feature@* tank | awk '$2=="active"{print $1}' | sort > /var/tmp/tank.active
cr0x@target:~$ sudo zpool get -H -o property,value feature@* tank 2>/dev/null | awk '$2!="disabled"{print $1}' | sort > /var/tmp/target.known
cr0x@target:~$ comm -23 /var/tmp/tank.active /var/tmp/target.known
Checklist : Construire un « contrat de compatibilité » pour le DR
- Définir le système le plus ancien qui doit pouvoir importer des pools.
- Geler l’activation des fonctionnalités de pool au-delà de ce que ce système supporte.
- Planifier les mises à jour du DR en parallèle avec la production, pas « plus tard ».
- Auditer trimestriellement : comparer les fonctionnalités actives et exécuter un test d’import/receive.
cr0x@prod:~$ sudo zpool get -H -o property,value feature@* tank | awk '$2=="active"{print $1}' | sort > /var/tmp/prod.active
cr0x@dr:~$ sudo zpool import 2>&1 | sed -n '1,30p'
FAQ
1) Que montre réellement zpool get feature@* ?
Il montre les propriétés des flags de fonctionnalités du pool : quelles fonctionnalités sur disque sont désactivées, activées ou actives. C’est la vue la plus directe de ce que le pool peut faire et des formats de métadonnées qu’il utilise peut‑être déjà.
2) Quelle est la différence entre « enabled » et « active » ?
Enabled signifie que le pool annonce la fonctionnalité et peut l’utiliser. Active signifie que la fonctionnalité est utilisée sur disque — des métadonnées ont été écrites qui la nécessitent. Active est la ligne qui casse typiquement la compatibilité d’import avec des systèmes plus anciens.
3) Exécuter zpool upgrade rend‑il immédiatement les fonctionnalités actives ?
Généralement cela les active (enabled), mais l’activation a lieu typiquement quand vous exécutez des opérations qui nécessitent ces fonctionnalités. Le risque opérationnel est différé : vous pouvez activer aujourd’hui et casser l’import DR le mois suivant quand une fonctionnalité devient active.
4) Puis‑je « rétrograder » un pool ou désactiver une fonctionnalité active ?
Pas en pratique générale. Une fois active, l’état sur disque du pool en dépend. La voie pratique de rétrogradation est de migrer les données vers un nouveau pool créé avec les contraintes de compatibilité souhaitées.
5) Pourquoi un pool n’importe‑t‑il pas sur un autre système ?
Parce que l’implémentation ZFS de ce système ne supporte pas une ou plusieurs fonctionnalités actives sur le pool. L’erreur d’import liste typiquement les noms exacts des fonctionnalités.
6) Les flags de fonctionnalités sont‑ils identiques sur toutes les implémentations ZFS ?
Dans l’écosystème OpenZFS ils sont en grande partie alignés, mais toutes les plateformes ne livrent pas la même version d’OpenZFS, et certains fournisseurs d’appliances retardent ou restreignent les mises à jour. Traitez « ZFS » comme un nom de famille ; le support des fonctionnalités dépend du build spécifique.
7) Les flags de fonctionnalités m’expliquent‑ils pourquoi la performance est lente ?
Pas directement. Ils vous indiquent quelles capacités existent (ou sont en cours d’utilisation) et qui peuvent influencer des caractéristiques de performance — comme le comportement du spacemap ou le support des gros blocs. Pour les goulots réels, utilisez zpool iostat, les stats ARC et des métriques spécifiques au workload.
8) Comment les flags se rapportent‑ils aux propriétés des datasets comme la compression ou le chiffrement ?
Certaines propriétés de dataset nécessitent un support de fonctionnalité au niveau du pool. Si le pool n’a pas la fonctionnalité pertinente activée, ZFS refusera de définir la propriété (meilleur cas) ou vous activerez une fonctionnalité quand vous commencerez à utiliser la capacité (cas courant).
9) Si une fonctionnalité est « enabled » mais pas « active », dois‑je m’inquiéter ?
Vous devriez au moins en être conscient. Les fonctionnalités enabled sont une capacité que vous pourriez activer accidentellement par des opérations normales. Si vous avez des exigences d’interopérabilité strictes, enabled-but-not-active est un point de gestion des changements.
10) Quelle est la chose la plus utile à conserver pour le dépannage futur ?
Un snapshot daté de la sortie de zpool get feature@* (plus zpool status) pris avant et après les mises à jour. C’est une preuve peu coûteuse qui évite des conjectures coûteuses plus tard.
Conclusion
zpool get feature@* est la chose la plus proche d’un sérum de vérité que ZFS ait. Il vous dit de quoi votre pool est capable, à quoi il s’est déjà engagé sur disque, et où les lignes de compatibilité sont tracées — que vous ayez voulu les tracer ou non. En production, ce n’est pas du trivia ; c’est la différence entre une mise à niveau contrôlée et un projet de migration surprise.
Si vous ne retenez qu’une habitude opérationnelle : suivez les fonctionnalités active comme vous suivez les versions de schéma. Sauvez la sortie, difflez‑la pendant les changements, et faites‑en partie intégrante de la préparation DR. ZFS fera volontiers la bonne chose pendant des années — jusqu’au moment où vous demanderez à un système plus ancien de comprendre un futur qu’il n’a jamais appris.