
ZFS a une qualité rare : il sait détecter et réparer la corruption silencieuse : ces bits qui se dégradent sur le disque sans qu'aucune application ne s'en aperçoive. Mais cette vérification, le scrub, ne se déclenche pas toute seule : elle doit être planifiée. Et c'est là qu'un piège discret attend les installations minimales : la planification déposée par les paquets ZFS suppose un composant qui n'est pas toujours là.
Le piège : des tâches cron sans cron
Sur Debian, le paquet zfsutils dépose un fichier dans /etc/cron.d/ qui lance un scrub mensuel de chaque pool. Tout repose donc sur une hypothèse : qu'un démon cron lit ce dossier. Or sur une installation minimale (et nous l'avons constaté sur des hyperviseurs Proxmox de notre propre parc), le paquet cron peut ne pas être installé du tout. Les fichiers de /etc/cron.d/ sont alors du texte mort : rien ne les lit, rien ne s'exécute, et rien ne le signale. Le pool affiche fièrement state: ONLINE pendant que la corruption silencieuse s'accumule sans jamais être cherchée.
C'est un défaut de conception classique : une maintenance qui échoue en silence est pire qu'une absence de maintenance, parce qu'elle donne l'illusion d'être couvert. Trente secondes suffisent pour savoir où vous en êtes :
# Le démon cron est-il seulement installé ?
dpkg -l cron 2>/dev/null | grep ^ii || echo 'cron ABSENT'
# Qu'attend-on de lui ?
ls /etc/cron.d/
# Date du dernier scrub réellement exécuté :
zpool status | grep scan
# 'scrub repaired 0B in ... ' + date récente = OK
# 'none requested' = aucun scrub n'a JAMAIS tournéSi la ligne scan affiche none requested sur un pool en service depuis des mois, vous venez de trouver le même problème que nous.
La solution propre : des timers systemd
Plutôt que d'installer cron pour deux tâches, autant confier la planification à ce qui est déjà là et supervisable : systemd. Deux unités modèles (@) suffisent pour tous les pools ; ici le scrub, mensuel :
# /etc/systemd/system/zfs-scrub@.service
[Unit]
Description=Scrub ZFS du pool %i
[Service]
Type=oneshot
ExecStart=/usr/sbin/zpool scrub -w %i
# /etc/systemd/system/zfs-scrub@.timer
[Unit]
Description=Scrub ZFS mensuel du pool %i
[Timer]
OnCalendar=*-*-01 03:00
RandomizedDelaySec=6h
Persistent=true
[Install]
WantedBy=timers.targetMême schéma pour le TRIM des pools sur SSD (zpool trim), hebdomadaire chez nous. Activation par pool, puis vérification, et c'est là que systemd paie : la planification devient observable :
systemctl enable --now zfs-scrub@rpool.timer
systemctl enable --now zfs-trim@rpool.timer
# La preuve, à tout moment :
systemctl list-timers 'zfs-*'
# NEXT = prochaine exécution, LAST = dernière : plus d'angle mortDernier maillon : être prévenu
Un scrub qui trouve des erreurs ne sert à rien si personne ne le lit. ZFS fournit ZED (ZFS Event Daemon), qui sait notifier sur événement, mais sa configuration par défaut n'envoie rien, et sa notification par mail suppose un MTA local fonctionnel, ce que les serveurs modernes n'ont plus. Chez nous, la boucle est fermée autrement : l'état des pools et des timers remonte dans la supervision centrale, qui alerte par les canaux déjà en place. Peu importe l'outil : le principe est le même que pour les sauvegardes : toute maintenance doit prouver qu'elle a tourné, et crier quand elle échoue.
C'est typiquement le genre de vérification que couvre notre infogérance : pas de la magie, juste une liste de choses qui doivent tourner, et la preuve qu'elles tournent. Un doute sur vos pools ZFS ? Les trois commandes du début vous donneront la réponse ; nous aussi, si besoin.


