
🌐 También en: English · Deutsch · Français
Un breve apéndice al montaje del NAS RAIDZ1. La chuleta de aquel artículo te dabazpool scrub storage como un comando que puedes ejecutar. Lo que no respondía es si algo lo ejecuta por ti y, como un scrub solo sirve de algo si te enteras de que ha encontrado algo, si el sistema te avisa cuando eso ocurre. Ambas preguntas resultaron tener respuestas más interesantes que «sí, obviamente».🔍 Scrub y trim, un párrafo para cada uno
zpool scrub lee cada bloque asignado del pool y lo compara con su suma de comprobación almacenada. Una discrepancia —un bit que se ha volteado en silencio en algún punto del soporte físico— se reconstruye a partir de la paridad RAIDZ y se reescribe automáticamente. Este es todo el mecanismo que hace a ZFS inmune al problema de la corrupción silenciosa de datos (el famoso bit rot) al que el artículo original dedicó varios párrafos: no es que la corrupción no pueda ocurrir, es que el scrub convierte «una corrupción que nadie notará jamás» en «una corrupción que se repara antes de que nadie la note». zpool trim es específico de los SSD. Le indica al firmware de la unidad qué bloques ha dejado de usar ZFS (archivos borrados, datos sobrescritos), para que el SSD pueda borrar y preparar ese espacio por adelantado en lugar de hacerlo a la carrera en mitad de una escritura. Si te lo saltas el tiempo suficiente, el rendimiento de escritura se degrada en silencio a medida que la unidad se queda sin bloques preborrados: el equivalente SSD de no sacar nunca la basura y preguntarte por qué cada vez cuesta más moverse por la cocina. Ninguno de los dos sirve de mucho como acción puntual. La gracia está en que se ejecuten de forma programada.📅 ¿Quién aprieta realmente el gatillo?
Fui a buscar la respuesta en lugar de darla por supuesta, y menos mal: el sitio obvio donde mirar era el equivocado. En Debian, OpenZFS trae dos mecanismos de programación en paralelo, y solo uno de ellos estaba haciendo algo:$ systemctl list-unit-files | grep zfs-scrub
zfs-scrub-monthly@.timer disabled enabled
zfs-scrub-weekly@.timer disabled enabledAmbos desactivados. Si me hubiera quedado aquí, la respuesta honesta habría sido «no, nada lo ejecuta». Pero zfsutils-linux también deja un simple archivo de cron, independiente de esos timers, y ese sí está activo:# /etc/cron.d/zfsutils-linux
# TRIM the first Sunday of every month.
24 0 1-7 * * root if [ $(date +\%w) -eq 0 ] && [ -x /usr/lib/zfs-linux/trim ]; then /usr/lib/zfs-linux/trim; fi
# Scrub the second Sunday of every month.
24 0 8-14 * * root if [ $(date +\%w) -eq 0 ] && [ -x /usr/lib/zfs-linux/scrub ]; then /usr/lib/zfs-linux/scrub; fiTrim el primer domingo, scrub el segundo, ambos a las 00:24. El script /usr/lib/zfs-linux/scrub al que llama tampoco es un zpool scrub $everything a ciegas: recorre cada pool, comprueba que su estado sea ONLINE y lee, por cada pool, una propiedad definida por el usuario llamada org.debian:periodic-scrub para decidir si lo incluye:$ zfs get -H -o value org.debian:periodic-scrub storage
-- significa sin definir, y el script lo trata como auto: el scrub se ejecuta. Ponerla en disable en un pool concreto lo excluiría sin tocar el propio cron job, lo cual es un ajuste más limpio que editar el script. En resumen: hay dos sistemas de programación instalados, solo el más antiguo, basado en cron, está activado, y la decisión real por pool es una propiedad, no un nombre de pool fijado en el código. Nada de eso se puede descubrir con zpool status: tienes que ir a mirar directamente systemctl, /etc/cron.d y la propiedad, que es justo lo que acabé haciendo después de que me hicieran la pregunta, muy razonable, de «¿esto está realmente automatizado o solo me has enseñado el comando manual?». Por cierto, mensual es también el intervalo correcto aquí: son SSD, y una cadencia de scrub semanal es más bien un valor por defecto de la era de los discos duros que en flash sobre todo añade desgaste sin ningún beneficio extra.🔔 ¿Te avisa algo cuando el scrub encuentra un problema?
Esta es la parte que de verdad me sorprendió. La infraestructura para avisarte existe, está instalada y está en marcha:$ systemctl status zfs-zed
● zfs-zed.service - ZFS Event Daemon (zed)
Active: active (running)ZED (el ZFS Event Daemon) vigila los eventos del pool —un scrub que termina, un resilver que se completa, un dispositivo que cambia de estado— y su configuración incluso nombra a un destinatario:# /etc/zfs/zed.d/zed.rc
ZED_EMAIL_ADDR="root"
ZED_NOTIFY_INTERVAL_SECS=3600Parece configurado. Y lo está, al menos desde el punto de vista del propio ZED. Pero el mecanismo real de entrega, enterrado en zed-functions.sh, no tiene nada de glamuroso:: "${ZED_EMAIL_PROG:="mail"}"zed_notify_email invoca un binario que se llama literalmente mail. Y en esta máquina:$ which mail mailx msmtp
$Nada. Ni mailutils, ni msmtp, ningún MTA de ningún tipo instalado. zpool create nunca arrastra uno como dependencia, así que, a menos que se te ocurra instalar por separado algo para entregar correo, ZED tiene un destinatario y ninguna forma de llegar a él. El zedlet scrub_finish-notify.sh se dispararía correctamente en el próximo scrub, construiría su mensaje y se lo pasaría a zed_notify_email, que intentaría ejecutar mail, recibiría «command not found» y fallaría; en silencio, desde el punto de vista de cualquiera que esté esperando que llegue un correo de verdad. journalctl -u zed tendrá el fallo registrado si vas a buscarlo. Nada te lo hará saber si no lo haces. Quiero detenerme en esto un segundo, porque es un remate realmente bueno: todo el primer artículo trataba de un sistema de archivos que se niega a dejar que la corrupción pase desapercibida —sumas de comprobación en lugar de confianza ciega, autorreparación en lugar de fallos silenciosos—. Y la capa que tiene encima, cuyo único trabajo es avisar a un humano cuando esa maquinaria hace su trabajo, fallaba ella misma exactamente de la forma silenciosa que ZFS se diseñó para evitar. La lección del último artículo llega más lejos de lo que esperaba: «parecer que todo va bien en silencio» es una propiedad de la infraestructura, no solo de los discos.🛠️ Arreglándolo de verdad
El hueco es solo un MTA que falta, no una mala configuración de ZED, así que el arreglo son de verdad tres pasos: instalar un cliente de correo, apuntarlo a un relay y decirle a ZED a quién escribir.apt-get install -y msmtp msmtp-mta bsd-mailxmsmtp-mta enlaza msmtp como /usr/sbin/sendmail, que es justo lo que mail/mailx —y, por tanto, ZED— invocan por debajo. Este homelab ya tiene un relay saliente que funciona (Strato, que ya se usa en otros sitios para notificaciones de otros hosts), así que apunté /etc/msmtprc a la misma cuenta en lugar de montar algo nuevo:# /etc/msmtprc — root-owned, chmod 600 (it holds a password)
defaults
auth on
tls on
tls_starttls on
logfile /var/log/msmtp.log
account homelab
host smtp.strato.de
port 587
from homelab@apt-upgrade.me
user homelab@apt-upgrade.me
password ██████████████████
account default : homelabchown root:root /etc/msmtprc && chmod 600 /etc/msmtprc justo después: ese archivo contiene una contraseña en texto plano, y zfs-zed.service se ejecuta como root de todos modos, así que «solo root» es a la vez correcto y suficiente. El mismo trato para el archivo de log. Y luego, el verdadero objetivo de todo el ejercicio: decirle a ZED que deje de enviar el correo a una cuenta root local que nadie va a leer nunca y que lo mande a algún sitio donde de verdad lo vea:sed -i 's/^ZED_EMAIL_ADDR=.*/ZED_EMAIL_ADDR="you@example.com"/' /etc/zfs/zed.d/zed.rc
systemctl restart zfs-zedSin alias, sin spool de correo local, sin reglas de reenvío que vigilar: ZED_EMAIL_ADDR es literalmente el destinatario con el que se invoca mail, así que apuntarlo directamente a un buzón real es más sencillo que hacer funcionar primero la entrega local y luego apilar un reenvío encima.✅ Funcionamiento confirmado
En lugar de esperar al segundo domingo del mes para averiguar si todo esto funciona de verdad, envié una prueba manual por exactamente el mismo camino que usa ZED:mail, que se resuelve en msmtp, que se autentica en Strato:$ echo "This is a test message from the storage NAS (192.168.10.x) confirming that
msmtp + ZED mail delivery is now working via the Strato relay." |
\
mail -s "ZFS ZED delivery check - storage NAS" you@example.com
$ tail -1 /var/log/msmtp.log
host=smtp.strato.de tls=on auth=on user=homelab@apt-upgrade.me from=homelab@apt-upgrade.me
recipients=you@example.com mailsize=436 smtpstatus=250
smtpmsg='250 2.0.0 OK queued with id 990330282JJ9ENX' exitcode=EX_OKsmtpstatus=250 / exitcode=EX_OK significa que Strato aceptó el mensaje para su entrega: esa es la parte de msmtp. El buzón lo confirmó unos segundos después:From: homelab@apt-upgrade.me
To: you@example.com
Subject: ZFS ZED delivery check - storage NAS
Date: Wed, 2 Sep 2026 21:19
This is a test message from the storage NAS (192.168.10.x) confirming that
msmtp + ZED mail delivery is now working via the Strato relay.De extremo a extremo, del relay al buzón, en más o menos lo que se tarda en leer la línea del log. Todo el arreglo verificado: no un «ahora debería funcionar», sino un correo real que llegó de verdad. Algo pequeño, pero que vale la pena decir claramente: el arreglo aquí no es en realidad «instalar msmtp». Es darse cuenta de que un componente cuyo único trabajo es dar la alarma puede fallar tan silenciosamente como aquello que se supone que vigila, y de que la única forma de saber que funciona de verdad es dispararlo y comprobarlo, no leer la configuración y darlo por hecho.



