Le point de montage ZFS : le piège de montage qui fait ‘disparaître’ les jeux de données
ZFS ne “perd” pas vraiment vos jeux de données. Il devient juste extrêmement doué pour vous faire croire qu’il l’a fait. Une minute vos données sont sous /srv/app, la minute suivante elles sont « parties », votre service est vide, et votre cerveau essaie de se souvenir si vous avez fâché les dieux du stockage.
Ceci est le piège du point de montage : un ensemble de comportements étonnamment ordinaires — overlays de montage, points de montage legacy, réglages canmount, ordre de démarrage et quelques outils d’automatisation bien intentionnés — qui peuvent cacher un jeu de données parfaitement sain derrière un autre système de fichiers. En production, cela peut ressembler exactement à une perte de données jusqu’à ce que vous vous rappeliez une règle : sous Unix, le dernier montage l’emporte.
Ce qu’est le piège du point de montage (et pourquoi il trompe les gens intelligents)
Le piège du point de montage survient quand un dataset ZFS est monté quelque part où vous ne l’attendiez pas — ou ne peut pas être monté où vous l’attendez — parce que l’emplacement de montage est déjà occupé. Un autre système de fichiers (un autre dataset ZFS, un tmpfs, une ancienne partition ext4, un bind mount d’un conteneur, une unité systemd, bref) est monté « par-dessus » le répertoire où vous pensiez que votre dataset résidait.
Depuis le shell, on dirait que vos données ont disparu :
lsaffiche un répertoire vide.- Les applications commencent à créer de nouveaux répertoires et fichiers, joyeusement, au mauvais endroit.
- Les données « manquantes » réapparaissent si vous démontez le système de fichiers qui recouvre — ou disparaissent à nouveau quand quelque chose est monté au démarrage.
C’est pourquoi le piège est si convaincant : ce n’est pas un bug ZFS. C’est le noyau qui fait exactement ce qu’il doit faire. Le jeu de données est toujours là, toujours cohérent, toujours référencé par son pool. Il n’est simplement pas visible pour le chemin sur lequel vous fixez les yeux.
Première blague (obligatoire, courte et méritée) : ZFS n’a pas mangé vos données ; il a juste posé une couverture dessus et vous a regardé paniquer.
Ce que « disparaître » signifie habituellement en pratique
La plupart du temps, l’une des situations suivantes est vraie :
- Le dataset est monté, mais pas là où vous le pensez (
mountpointa changé ou est hérité). - Le dataset n’est pas monté parce qu’on a demandé à ZFS de ne pas le monter (
canmount=offounoauto). - Le dataset est défini avec
mountpoint=legacy, donc ZFS ne le montera pas à moins que/etc/fstab(ou l’équivalent de votre distribution) ne le fasse. - Le dataset souhaite se monter à un chemin qui est déjà un point de montage pour autre chose (overlay).
- Le pool a été importé, mais le montage a échoué à cause de clés manquantes (chiffrement), de répertoires de montage absents, ou de l’ordre de démarrage.
Le danger opérationnel n’est pas que de la confusion. C’est un état de split-brain du système de fichiers au niveau applicatif : votre service commence à écrire de nouvelles données dans un répertoire sous-jacent (généralement sur le système root), tandis que le vrai dataset reste tranquillement ailleurs. Vous avez alors deux réalités : celle que voit votre appli, et celle que ZFS protège.
Comment fonctionne réellement le montage ZFS
Les datasets ZFS sont des systèmes de fichiers dotés de propriétés. La propriété au centre de notre drame est mountpoint, associée à canmount. Comprendre leur interaction est la moitié de la bataille ; l’autre moitié est de se souvenir que ZFS vit dans un OS plus vaste qui peut monter d’autres choses quand bon lui semble.
Les trois piliers : mountpoint, canmount, et « qui le monte »
mountpoint est le chemin où ZFS montera un dataset si c’est ZFS qui le monte. Valeurs courantes :
- Un chemin réel, p.ex.
/srv/db none(ne jamais monter)legacy(ZFS délègue aux mécanismes classiques de montage comme/etc/fstab)
canmount contrôle si le dataset est éligible au montage :
on: montable (par défaut)off: ne jamais monter (même s’il a un mountpoint)noauto: ne pas monter automatiquement au démarrage, mais autoriserzfs mountmanuel
Qui le monte dépend de l’intégration sur votre OS. Sur beaucoup de systèmes, le montage ZFS est géré par des scripts d’init ou des services systemd qui s’exécutent après l’import du pool. Pour les datasets legacy, les unités de montage du système ou mount -a s’en chargent. Sur les plateformes de conteneurs, les namespaces de montage et les bind mounts peuvent ajouter une seconde couche de « c’est monté, juste pas à l’endroit que vous regardez ».
Overlays : la loi Unix qui cause la plupart des actes de « disparition »
Quand vous montez le système de fichiers B sur le répertoire /srv/app, tout ce qui était précédemment visible à /srv/app est caché jusqu’à ce que vous démontiez B. Cela inclut :
- des fichiers créés dans ce répertoire sur le système de fichiers root,
- ou un montage antérieur (comme votre dataset ZFS),
- ou un bind mount venu d’un autre endroit.
Ce n’est pas spécifique à ZFS ; c’est le comportement du VFS Unix. ZFS rend simplement facile la création de nombreux systèmes de fichiers montables, ce qui augmente la probabilité d’empiler des montages par accident.
Deuxième blague (également obligatoire, courte) : Si les montages avaient une appli de rencontres, leur bio serait « Je cache les choses. »
Héritage : la pierre d’achoppement silencieuse
Les propriétés ZFS peuvent être héritées dans l’arbre de datasets. C’est une fonctionnalité — jusqu’à ce que vous oubliiez qu’elle existe. Si vous réglez mountpoint sur un dataset parent, les enfants l’héritent sauf si on le définit explicitement autrement. Vous pouvez vous retrouver avec des points de montage imbriqués comme :
pool/servicesmonté sur/srvpool/services/appmonté sur/srv/apppool/services/app/logsmonté sur/srv/app/logs
Ça peut être parfaitement sensé. Ça peut aussi devenir le chaos quand quelqu’un change le mountpoint du parent lors d’une migration et oublie que les enfants héritent — soudainement tout bouge, ou tente de se monter sur des chemins qui entrent maintenant en collision avec des montages existants.
legacy : contrôle à l’ancienne, confusion à l’ère moderne
mountpoint=legacy signifie : « ZFS, ne montez pas automatiquement ceci. Je m’en occupe via le système de montage de l’OS. » C’est parfois utilisé pour un contrôle strict, un ordonnancement particulier ou la compatibilité avec des outils de gestion.
Le piège : si vous comptez sur legacy, mais que votre entrée /etc/fstab est manquante, incorrecte ou retardée au démarrage, le dataset existera mais ne sera pas monté. Pendant ce temps, le répertoire n’est qu’un répertoire — donc votre application démarre et écrit là comme si de rien n’était.
Faits intéressants et contexte historique
Un peu de contexte aide, parce que le comportement de montage de ZFS n’est pas aléatoire — il résulte de décisions de conception qui datent de plusieurs décennies.
- ZFS a fait ses débuts chez Sun au milieu des années 2000 avec l’idée que « les systèmes de fichiers sont peu coûteux » et devraient être gérés comme des jeux de données, pas comme des partitions.
- Contrairement aux systèmes traditionnels, ZFS encourage de nombreux points de montage (un par dataset), ce qui augmente la surface d’erreurs liée à l’ordre de montage.
- Le point de montage
legacyexiste principalement pour la compatibilité avec les anciens outils Unix de montage et les séquences de démarrage où ZFS n’était pas le gestionnaire de fichiers par défaut. canmount=noautoest devenu populaire dans les environnements de démarrage afin que plusieurs datasets puissent coexister sans tous se monter en même temps.- Les overlays de montage sont plus anciens que ZFS de plusieurs décennies ; ils sont un comportement fondamental du VFS Unix. ZFS rend simplement les scénarios d’overlay plus faciles à créer par accident.
- Beaucoup de tickets de “perte de données” au début des déploiements ZFS étaient des bugs de visibilité : les datasets existaient, mais étaient cachés par des montages erronés ou des pools non importés.
- OpenZFS s’est répandu sur Linux, illumos et BSD, et chaque plateforme a intégré le montage au démarrage différemment — mêmes propriétés, chorégraphies différentes.
- Le chiffrement a ajouté un nouveau mode d’échec : des datasets peuvent être présents et sains mais non montés parce que les clés n’ont pas été chargées au démarrage.
Les symptômes : jeux de données « disparaissant » dans le monde réel
En réponse aux incidents, « le dataset a disparu » arrive généralement emballé dans l’un de ces scénarios :
Symptôme 1 : Le répertoire est vide (ou semble fraîchement créé)
Vous faites cd dans /srv/app et il est vide, alors que vous savez qu’il devrait contenir des gigaoctets. Ou pire : il contient un ensemble de fichiers différent créés récemment par une application qui n’a pas reçu la note.
Symptôme 2 : Le dataset existe dans les métadonnées ZFS
zfs list affiche le dataset, avec une taille utilisée non nulle, et peut-être même le mountpoint attendu. Pourtant le chemin ne montre pas les données.
Symptôme 3 : Après un reboot, le problème apparaît (ou disparaît)
Si ça change au reboot, suspectez l’ordre de démarrage, les montages legacy, les unités systemd, ou le chargement des clés de chiffrement.
Symptôme 4 : L’utilisation disque ne correspond pas à ce que vous voyez
zfs list indique des centaines de gigaoctets utilisés, mais du sur le point de montage montre presque rien. Ou l’inverse : df indique un petit système root en train de se remplir parce que l’appli a écrit dans le répertoire sous-jacent.
Symptôme 5 : Les conteneurs voient quelque chose de différent que l’hôte
Les namespaces de montage signifient que l’hôte peut avoir le dataset monté tandis qu’un conteneur voit un répertoire non monté (ou un bind mount différent). C’est une saveur spéciale de « ça a disparu », souvent attribuée à tort à ZFS parce que c’est le nom que les gens reconnaissent.
Tâches pratiques : commandes que vous pouvez exécuter aujourd’hui
Voici des tâches adaptées à la production que j’ai réellement utilisées sous pression. Chacune inclut ce que la sortie signifie et la décision qu’elle éclaire. Les commandes supposent Linux avec OpenZFS ; ajustez les chemins pour votre OS.
Tâche 1 : Lister les datasets et leurs points de montage (la réalité de base)
cr0x@server:~$ zfs list -o name,used,avail,mountpoint,canmount -r tank
NAME USED AVAIL MOUNTPOINT CANMOUNT
tank 320G 1.4T /tank on
tank/services 210G 1.4T /srv on
tank/services/app 180G 1.4T /srv/app on
tank/services/db 30G 1.4T /srv/db on
Interprétation : Si un dataset a un mountpoint réel et canmount=on, ZFS a l’intention de le monter. S’il n’est pas visible, suspectez des overlays ou une erreur de montage.
Tâche 2 : Voir ce que ZFS pense être actuellement monté
cr0x@server:~$ zfs mount
tank
tank/services
tank/services/app
tank/services/db
Interprétation : Si votre dataset est absent ici, il n’est pas monté par ZFS. S’il est listé mais que vous ne voyez toujours pas les fichiers au chemin, suspectez des namespaces de montage ou que vous regardez le mauvais répertoire sur l’hôte.
Tâche 3 : Confirmer ce que le noyau a monté au chemin (détecter les overlays)
cr0x@server:~$ findmnt -T /srv/app
TARGET SOURCE FSTYPE OPTIONS
/srv/app tank/services/app zfs rw,xattr,noacl
Interprétation : C’est la commande la plus utile pour le piège du montage. Si findmnt montre autre chose (ext4, overlayfs, tmpfs), votre dataset ZFS est caché.
Tâche 4 : Montrer tous les montages qui pourraient s’empiler dans l’arborescence
cr0x@server:~$ findmnt -R /srv
TARGET SOURCE FSTYPE OPTIONS
/srv tank/services zfs rw,xattr
└─/srv/app tank/services/app zfs rw,xattr
└─/srv/db tank/services/db zfs rw,xattr
Interprétation : Si vous voyez des entrées inattendues (comme /srv/app étant overlayfs), vous avez trouvé l’endroit qui cache le dataset.
Tâche 5 : Vérifier si le dataset est configuré en legacy (cause fréquente du « pourquoi il ne s’est pas monté ? »)
cr0x@server:~$ zfs get -H -o name,property,value,source mountpoint tank/services/app
tank/services/app mountpoint legacy local
Interprétation : Avec legacy, ZFS ne montera pas automatiquement. Si vous n’avez pas une entrée OS correspondante, votre service écrira sur le répertoire sous-jacent à la place.
Tâche 6 : Vérifier canmount (l’interrupteur « ça existe mais ne se montera pas »)
cr0x@server:~$ zfs get -H -o name,property,value,source canmount tank/services/app
tank/services/app canmount noauto local
Interprétation : noauto signifie qu’il ne se montera pas au démarrage via le chemin d’automontage habituel ; vous devez le monter explicitement (ou via un outil). off signifie que vous ne le montez pas du tout à moins de le changer.
Tâche 7 : Tenter un montage manuel et lire l’erreur (ne devinez pas)
cr0x@server:~$ sudo zfs mount tank/services/app
cannot mount 'tank/services/app': mountpoint or dataset is busy
Interprétation : « Busy » signifie souvent que /srv/app est déjà un point de montage pour autre chose. C’est le scénario d’overlay. Exécutez findmnt -T /srv/app pour identifier le fautif.
Tâche 8 : Identifier ce qui occupe le point de montage
cr0x@server:~$ findmnt -T /srv/app -o TARGET,SOURCE,FSTYPE,OPTIONS
TARGET SOURCE FSTYPE OPTIONS
/srv/app /dev/nvme0n1p2[/app] ext4 rw,relatime
Interprétation : Vous ne regardez pas du tout ZFS ; ext4 est monté là. Votre dataset n’est pas perdu — votre point de montage est pris.
Tâche 9 : Localiser le dataset en scannant les mountpoints (si vous suspectez qu’il est monté ailleurs)
cr0x@server:~$ zfs list -o name,mountpoint -r tank | grep app
tank/services/app /srv/app
Interprétation : Si le mountpoint est correct ici mais que le noyau montre autre chose à ce chemin, vous avez une collision de montage.
Tâche 10 : Détecter les « données d’ombre » écrites quand le dataset n’était pas monté
cr0x@server:~$ sudo zfs unmount tank/services/app
cr0x@server:~$ ls -lah /srv/app | head
total 56K
drwxr-xr-x 14 root root 4.0K Dec 24 09:10 .
drwxr-xr-x 6 root root 4.0K Dec 24 09:09 ..
-rw-r--r-- 1 root root 2.1K Dec 24 09:10 app.log
drwxr-xr-x 2 root root 4.0K Dec 24 09:10 cache
Interprétation : Ces fichiers sont sur le système de fichiers sous-jacent (souvent votre disque root), créés pendant que ZFS n’était pas monté. C’est ainsi que les systèmes root se remplissent mystérieusement lors d’un échec de montage ZFS.
Tâche 11 : Vérifier l’import du pool et les services de montage (échecs au démarrage)
cr0x@server:~$ systemctl status zfs-import-cache zfs-mount
● zfs-import-cache.service - Import ZFS pools by cache file
Loaded: loaded (/lib/systemd/system/zfs-import-cache.service; enabled)
Active: active (exited)
● zfs-mount.service - Mount ZFS filesystems
Loaded: loaded (/lib/systemd/system/zfs-mount.service; enabled)
Active: failed (Result: exit-code)
Interprétation : Le pool est importé, mais le montage ZFS a échoué. Ne poursuivez pas des fantômes dans le dataset ; examinez les logs du service et la raison de l’échec.
Tâche 12 : Lire la raison de l’échec de montage dans les logs
cr0x@server:~$ journalctl -u zfs-mount -b --no-pager | tail -n 20
Dec 24 09:01:12 server zfs[1123]: cannot mount 'tank/services/app': directory is not empty
Dec 24 09:01:12 server systemd[1]: zfs-mount.service: Main process exited, code=exited, status=1/FAILURE
Interprétation : « Directory is not empty » est généralement un indice qu’il existe des données d’ombre créées avant que ZFS ne monte, ou qu’un autre montage/bind occupe le chemin. Cela peut aussi signifier que vous montez sur un répertoire non vide et que l’outil ZFS de votre système refuse de le faire automatiquement.
Tâche 13 : Vérifier que les clés de chiffrement sont chargées (l’invisible « pas monté »)
cr0x@server:~$ zfs get -H -o name,property,value keystatus,encryptionroot tank/services/app
tank/services/app keystatus unavailable
tank/services/app encryptionroot tank
Interprétation : Si keystatus est unavailable, le dataset peut exister mais ne pas pouvoir être monté. Chargez la clé, puis montez.
Tâche 14 : Charger la clé et monter (avec précaution)
cr0x@server:~$ sudo zfs load-key -a
cr0x@server:~$ sudo zfs mount -a
cr0x@server:~$ zfs get -H -o name,property,value keystatus tank/services/app
tank/services/app keystatus available
Interprétation : Si cela résout le problème, votre « dataset disparu » était un problème de gestion de clés / ordre de démarrage, pas un problème de propriété de point de montage.
Tâche 15 : Trouver les propriétés héritées vs locales (pour repérer les changements surprises)
cr0x@server:~$ zfs get -r -o name,property,value,source mountpoint,canmount tank/services | sed -n '1,8p'
NAME PROPERTY VALUE SOURCE
tank/services mountpoint /srv local
tank/services canmount on default
tank/services/app mountpoint /srv/app inherited from tank/services
tank/services/app canmount on default
Interprétation : Si un enfant hérite d’un mountpoint, un changement sur le parent change aussi le mountpoint effectif de l’enfant. C’est à la fois puissance et danger en une ligne.
Tâche 16 : Changer un mountpoint en toute sécurité (et vérifier)
cr0x@server:~$ sudo zfs set mountpoint=/srv/app2 tank/services/app
cr0x@server:~$ sudo zfs mount tank/services/app
cr0x@server:~$ findmnt -T /srv/app2
TARGET SOURCE FSTYPE OPTIONS
/srv/app2 tank/services/app zfs rw,xattr
Interprétation : ZFS rend simples les changements de mountpoint, mais vous devez confirmer que le nouveau chemin n’est pas déjà utilisé et mettre à jour les applications, les entrées fstab (si legacy) et la supervision.
Trois petites histoires en milieu professionnel
1) Incident causé par une mauvaise hypothèse : « Le dataset est vide, donc le déploiement l’a effacé »
Ça a commencé comme beaucoup de problèmes du vendredi : un déploiement s’est terminé, l’application a redémarré, et soudain la couche web servait du contenu par défaut — comme si le site entier avait été réinitialisé. L’ingénieur de garde a fait la chose sensée en premier : vérifier le répertoire de données. Il était vide. La conclusion est venue rapidement et avec assurance : la pipeline de déploiement avait dû supprimer le volume.
Quelqu’un a lancé un rollback. Quelqu’un d’autre a commencé à rédiger l’état d’incident avec des phrases comme « suppression irrécupérable » et « restauration depuis les sauvegardes ». La personne stockage a été rappelée et a posé une question calme qui a fait dérailler le récit : « Que dit findmnt à propos de ce chemin ? »
Il s’est avéré que le chemin avait deux montages se battant pour le même répertoire. Le serveur avait une ancienne partition ext4 toujours listée dans une unité de montage système, et elle monta tard dans la séquence de boot — juste après que ZFS ait monté avec succès le dataset. Le montage ext4 n’a rien effacé ; il a simplement recouvert le montage ZFS. Les données n’ont jamais bougé. Elles étaient simplement cachées derrière un système de fichiers d’une ère antérieure de cet hôte.
La correction a été douloureusement simple : supprimer l’unité de montage obsolète et redémarrer. Mais la vraie correction a été culturelle : arrêter d’assimiler « le répertoire semble vide » à « les données sont supprimées ». Cette hypothèse provoque des décisions rapides, coûteuses et inutiles, y compris des rollbacks qui introduisent un nouveau risque.
2) Une optimisation qui s’est retournée contre eux : « Utilisons mountpoint=legacy pour plus de contrôle »
Une équipe plateforme voulait des montages déterministes. Ils en avaient assez du « magique » et visaient l’explicite : mettre les datasets ZFS sur mountpoint=legacy, puis tout gérer dans /etc/fstab pour que le système decide de l’ordre. Sur le papier, ça semblait être du bon ingénierie : un endroit pour lire les montages, une manière de tout monter, audit facile.
En pratique, c’était une optimisation pour les humains au détriment de la fiabilité. Lors d’une fenêtre de maintenance, ils ont renommé un dataset et mis à jour le côté ZFS mais ont raté la ligne fstab correspondante sur deux serveurs. Ces deux machines ont démarré « normalement », mais le dataset ne s’est pas monté. Le répertoire existait, donc l’application a démarré et a écrit sur le filesystem root sous-jacent. En quelques heures, les disques root se sont remplis, journald a commencé à perdre des logs, et l’incident est passé de « pourquoi les métriques manquent ? » à « pourquoi les nœuds meurent ? »
Ça s’est empiré : quand le dataset a finalement été monté correctement, les nouveaux fichiers « manquants » ont disparu — parce que ces fichiers n’avaient jamais été dans le dataset ; ils étaient sur le système de fichiers sous-jacent. Maintenant l’appli avait deux états créés à deux endroits, et les concilier a demandé du travail humain soigné et beaucoup de prudence.
Le postmortem n’a pas conclu à « ne jamais utiliser legacy ». Il a conclu : n’utiliser legacy que lorsque vous pouvez prouver que le montage est appliqué (via des dépendances systemd, des vérifications précoces au boot et de la supervision), et lorsque votre modèle opérationnel prend en compte le mode d’échec : l’application écrit sur le mauvais disque.
3) Une pratique ennuyeuse mais correcte qui a sauvé la mise : « Nous supervisons la réalité des montages, pas seulement les propriétés ZFS »
Dans une autre entreprise, un cluster de bases de données tournait sur des datasets ZFS avec des mountpoints soigneusement conçus. Ils avaient vécu trop de matins effrayants où le pool s’importait mais un dataset ne montait pas à cause de délais de chargement des clés. Ils ont donc implémenté une vérification banale qui s’exécutait sur chaque nœud après le boot et après les changements de configuration : vérifier que des chemins spécifiques sont bien supportés par la source de système de fichiers attendue.
La vérification ne demandait pas à ZFS ce qu’il avait l’intention de faire. Elle demandait au noyau ce qu’il avait effectivement fait : findmnt -T /var/lib/postgresql, et comparer la source au dataset attendu. Si ce n’était pas conforme, le nœud était marqué non sain et retiré du service avant de prendre du trafic. Rien de fancy. Pas d’IA. Juste refuser d’exécuter des services stateful sur un montage ambigu.
Un jour, une mise à jour système routinière a introduit un nouveau tmpfs pour un chemin legacy utilisé par un agent. Il s’est monté par erreur sur un répertoire parent et a masqué un montage enfant. Le nœud est revenu du reboot, et les montages ZFS semblaient « corrects » à première vue, mais la vérification de chemin a échoué instantanément. Le nœud n’a jamais rejoint le cluster. Pas de divergence de données, pas de restauration d’urgence, pas de bataille « pourquoi root est plein ? ».
C’est le genre de victoire que personne ne célèbre parce que rien ne s’est passé — ce qui est le plus beau compliment qu’on puisse faire à l’ingénierie opérationnelle.
Mode opératoire de diagnostic rapide
Voici l’ordre que j’utilise quand un dataset « manque ». L’objectif est la vitesse : réduire l’espace de recherche en moins de cinq minutes, puis décider si vous avez affaire à un overlay, un échec de montage ou un problème de visibilité entre namespaces/boot.
Étape 1 : Demandez au noyau ce qui est monté au chemin
cr0x@server:~$ findmnt -T /srv/app -o TARGET,SOURCE,FSTYPE,OPTIONS
TARGET SOURCE FSTYPE OPTIONS
/srv/app tank/services/app zfs rw,xattr
Si ce n’est pas ZFS : vous avez un overlay ou un mauvais montage. Identifiez et supprimez/déplacez le montage qui occupe le chemin.
Étape 2 : Demandez à ZFS s’il croit que le dataset est monté
cr0x@server:~$ zfs mount | grep -F tank/services/app || echo "not mounted"
not mounted
Si ce n’est pas monté : vérifiez canmount, mountpoint, le keystatus du chiffrement et les logs. Ne supposez pas que c’est une faute de frappe du mountpoint avant d’avoir vérifié les éléments ennuyeux.
Étape 3 : Vérifiez les propriétés de montage du dataset et l’héritage
cr0x@server:~$ zfs get -H -o property,value,source mountpoint,canmount tank/services/app
mountpoint /srv/app local
canmount on default
Si mountpoint=legacy : allez voir les montages OS. Si canmount=off/noauto : inspectez la logique de montage et les scripts de démarrage.
Étape 4 : Cherchez les échecs de montage dans les logs (ne passez pas ça sous silence)
cr0x@server:~$ journalctl -u zfs-mount -b --no-pager | tail -n 50
Cas fréquents : « directory is not empty », « mountpoint busy », clé non disponible, problèmes de permissions dans le répertoire de montage, ou parent manquant.
Étape 5 : Vérifiez les données d’ombre et empêchez la divergence
Si le dataset n’a pas pu être monté, votre appli a peut-être écrit dans le répertoire sous-jacent. Avant de remonter, arrêtez le service, inspectez les répertoires sous-jacents et planifiez une fusion contrôlée ou un nettoyage. Le pire mouvement est « juste le monter et espérer ». C’est comme ça qu’on crée un état en split.
Étape 6 : Ce n’est qu’après que vous vous inquiétiez des performances
Les gens sautent sur « ZFS est lent » alors que le vrai problème est « vous écrivez sur le disque root ». Confirmez d’abord la source du montage. Déboguer les performances sur le mauvais système de fichiers est un excellent moyen de devenir extrêmement occupé et extrêmement dans l’erreur.
Erreurs courantes, symptômes et correctifs
Erreur 1 : Collision de point de montage (deux systèmes de fichiers veulent le même répertoire)
Symptômes :
zfs mountéchoue avec « dataset is busy »findmnt -T /pathmontre ext4/tmpfs/overlayfs au lieu de ZFS- Les données « réapparaissent » après le démontage de quelque chose d’apparemment sans rapport
Correctif : Identifiez le montage actuel qui occupe le chemin (findmnt). Supprimez ou déplacez le montage en conflit. S’il s’agit d’une entrée /etc/fstab obsolète ou d’une unité systemd, supprimez/la désactivez et redémarrez ou remontez proprement.
Erreur 2 : mountpoint=legacy sans entrée OS fonctionnelle
Symptômes :
zfs listmontre le dataset, maiszfs mountne le monte pas- Les applications écrivent dans les répertoires sous-jacents ; le filesystem root se remplit
Correctif : Soit (a) ajoutez la configuration de montage OS correcte, soit (b) changez pour un mountpoint normal et laissez ZFS le gérer : set mountpoint=/desired/path et assurez-vous que canmount=on. Puis validez avec findmnt.
Erreur 3 : canmount=off ou noauto sans automatisation explicite
Symptômes :
- Le dataset ne se monte jamais après un reboot
zfs mount datasetmanuel fonctionne (pournoauto)
Correctif : Si vous avez besoin qu’il soit monté au démarrage, définissez canmount=on. Si vous avez besoin de noauto (environnements de boot, datasets de staging), assurez-vous qu’une unité systemd le montera avant le démarrage des services.
Erreur 4 : Le mountpoint du parent a changé et les enfants ont hérité d’une nouvelle réalité
Symptômes :
- Plusieurs datasets « ont bougé » en même temps
- Les tentatives de montage échouent parce que les chemins hérités entrent en collision
Correctif : Passez en revue l’héritage avec zfs get -r mountpoint. Définissez des mountpoints explicites sur les enfants qui doivent rester stables, ou repensez l’arborescence des datasets pour qu’elle corresponde à votre hiérarchie de répertoires.
Erreur 5 : Clés de chiffrement non chargées au démarrage
Symptômes :
- Le dataset existe,
keystatus=unavailable - Le montage échoue jusqu’à ce que quelqu’un exécute
zfs load-key
Correctif : Implémentez le chargement des clés dans la séquence de démarrage (avec les contrôles de sécurité appropriés), et ajoutez une vérification post-boot de montage pour empêcher les services de démarrer sur des répertoires vides.
Erreur 6 : Conteneurs et namespaces de montage cachent la vérité de l’hôte
Symptômes :
- L’hôte voit le dataset monté ; le conteneur voit un répertoire vide
- Contenu différent visible selon l’endroit où vous exécutez
ls
Correctif : Validez les montages à l’intérieur du namespace du conteneur, pas seulement sur l’hôte. Assurez-vous que les bind mounts référencent le bon chemin hôte et que le chemin hôte est bien soutenu par le dataset ZFS attendu au moment où le conteneur démarre.
Listes de contrôle / plan étape par étape
Checklist A : Quand les données « disparaissent » d’un point de montage
- Exécutez
findmnt -T /pathpour voir le véritable système de fichiers à ce chemin. - Exécutez
zfs mountetzfs list -o name,mountpoint,canmountpour le dataset. - Si
zfs mountéchoue, lisez l’erreur ; n’improvisez pas. - Vérifiez
zfs get mountpoint,canmountet si les valeurs sont héritées. - Consultez les logs pour les échecs du service de montage.
- Arrêtez les applications qui écrivent sur le chemin jusqu’à ce que le montage soit correct.
- Si le dataset n’était pas monté, recherchez des données d’ombre dans le répertoire sous-jacent après l’avoir démontré / vous être assuré qu’il est démonté.
- Ce n’est qu’après que la visibilité est correcte que vous pouvez reprendre les services et valider l’état applicatif.
Checklist B : Migration sûre d’un point de montage (changement en production)
- Choisissez un nouveau chemin qui n’est pas actuellement un point de montage : vérifiez avec
findmnt -T. - Arrêtez les services qui écrivent dans le dataset.
- Confirmez que le dataset est sain et monté là où vous le pensez.
- Changez le mountpoint :
zfs set mountpoint=/new/path dataset. - Montez explicitement :
zfs mount datasetet vérifiez avecfindmnt. - Mettez à jour la configuration applicative, les unités systemd, les bind mounts de conteneurs, les sauvegardes et les vérifications de supervision.
- Démarrez les services et validez que les écritures vont bien sur ZFS (surveillez les octets utilisés dans
zfs list, pas seulement les logs applicatifs). - Nettoyez les anciens répertoires sur le système de fichiers sous-jacent s’ils ont accumulé des fichiers d’ombre.
Checklist C : Prévenir le piège (garde-fous ennuyeux mais efficaces)
- Supervisez la réalité des montages : pour les chemins critiques, alertez si la source de
findmnt -Tn’est pas le dataset attendu. - Faites dépendre les services des montages ZFS (ordonnancement systemd) pour qu’ils ne démarrent pas sur des répertoires vides.
- Évitez de mélanger la gestion
legacyet non-legacy à moins d’avoir une raison documentée et des tests. - Documentez l’arbre des datasets et les règles d’héritage des mountpoints pour votre équipe.
- Pendant la réponse à incident, considérez « répertoire vide » comme « ambiguïté de montage » jusqu’à preuve du contraire.
FAQ
1) Un dataset ZFS peut-il réellement « disparaître » ?
Rarement au sens littéral. La plupart du temps il n’est pas monté, est monté ailleurs, ou est caché par un autre montage. Les métadonnées ZFS le montrent généralement toujours dans zfs list.
2) Quelle est la commande la plus rapide pour confirmer le piège du point de montage ?
findmnt -T /your/path. Elle vous dit ce que le noyau a réellement monté là, ce qui est la réalité dans laquelle vivent vos applications.
3) Pourquoi ZFS refuse-t-il parfois de monter en disant « directory is not empty » ?
Certaines solutions de montage ZFS sont conservatrices quant au montage sur des répertoires non vides pour éviter de cacher des fichiers écrits là (souvent par erreur). Cette erreur est un cadeau : elle vous dit qu’il existe des données d’ombre ou que quelque chose d’autre possède ce chemin.
4) Est-ce que mountpoint=legacy est mauvais ?
Non. C’est utile quand vous avez besoin du contrôle par l’OS. C’est risqué quand les équipes oublient que ZFS ne le montera pas automatiquement et que les applis écriront dans le répertoire sous-jacent si le montage OS n’a pas lieu.
5) Quelle est la différence entre canmount=off et canmount=noauto ?
off signifie « ne jamais monter ». noauto signifie « ne pas monter automatiquement, mais autoriser le montage manuel ». noauto est courant dans les environnements de boot ou pour les datasets en staging.
6) Comment savoir si un dataset enfant a hérité d’un mountpoint ?
Utilisez zfs get -o name,property,value,source mountpoint -r pool/dataset. Si la source indique « inherited from … » alors changer le parent modifiera le mountpoint effectif de l’enfant.
7) Pourquoi un reboot a-t-il « réparé » le dataset manquant ?
Parce que la séquence de démarrage a changé l’ordre ou le timing des montages. Peut-être que ZFS s’est monté avant le montage en conflit la fois précédente, ou que les clés se sont chargées correctement au second démarrage, ou qu’une unité de montage défaillante a réessayé.
8) Comment empêcher les applications d’écrire au mauvais endroit quand ZFS n’est pas monté ?
Deux couches : (1) dépendances systemd pour que les services ne démarrent pas tant que le montage correct n’existe pas, et (2) supervision qui vérifie la source du montage (encore : findmnt) et retire les nœuds de rotation si c’est incorrect.
9) Les snapshots peuvent-ils aider avec le piège du point de montage ?
Les snapshots protègent les données à l’intérieur du dataset. Ils ne vous protègent pas d’une application écrivant au mauvais endroit sous-jacent quand le dataset n’est pas monté. Vous pouvez très bien snapshotter le mauvais système de fichiers aussi — avec succès.
10) Que faire si le dataset est monté mais que le répertoire ressemble toujours à quelque chose d’anormal ?
Vous êtes peut-être dans un namespace de montage différent (conteneurs), vous regardez un lien symbolique qui pointe ailleurs, ou vous confondez deux chemins similaires. Confirmez avec findmnt dans le même contexte où l’application s’exécute.
Conclusion
Le piège du point de montage ZFS n’est pas un cas limite rare. C’est une conséquence prévisible d’un système qui rend facile la création et le montage de systèmes de fichiers, vivant dans un OS qui permet aux montages de s’empiler et de se cacher les uns les autres sans cérémonie.
Si vous ne retenez qu’une seule habitude : cessez de faire confiance aux listings de répertoires quand les enjeux sont élevés. Faites confiance à la réalité des montages. Demandez au noyau ce qui est monté au chemin, demandez à ZFS ce qu’il pense devoir être monté, et faites en sorte que vos services refusent de démarrer lorsque ces réponses divergent. C’est ainsi que vous transformez un « mon dataset a disparu » en une réparation de deux minutes.