Si ejecutas ZFS en producción, una actualización del kernel no es “aplicar parches, reiniciar y listo.” Es “aplicar parches, verificar la plomería y luego reiniciar.” Porque ZFS no es solo otro sistema de ficheros: es un acoplamiento estrecho entre módulo de kernel, herramientas de espacio de usuario, comportamiento de initramfs, supuestos del gestor de arranque y compatibilidad de flags de pool.
El modo de fallo siempre es el mismo: reinicias con confianza y vuelves a un equipo que no puede importar su pool, no puede montar root, o está atascado en un prompt de initramfs con cara de traicionado. Esta es la lista de verificación que te evita esa reunión.
El modelo mental: qué puede fallar y dónde
Un fallo en la actualización del kernel de ZFS rara vez proviene de un solo bug. Proviene de una suposición. Normalmente tuya. La “actualización del kernel” es en realidad un cambio coordinado entre:
- ABI del kernel que cambia (incluso mínimamente) y requiere un módulo ZFS coincidente.
- DKMS o kmods preconstruidos que compilan el módulo en el momento de la instalación.
- Contenido de initramfs: si incluye los módulos y scripts de ZFS para que el sistema pueda importar pools en el arranque.
- Configuración del gestor de arranque: si puedes seleccionar un kernel anterior rápidamente cuando las cosas van mal.
- Flags de características del pool: si un pool creado o actualizado en una máquina puede importarse en otra (incluido en modo rescue).
- Versiones de herramientas de espacio de usuario: desajustes que no siempre evitan el arranque, pero pueden hacer las operaciones engañosas.
Tu tarea es probar, antes del reinicio, que:
- El módulo ZFS se compilará (o ya está compilado) para el nuevo kernel.
- El módulo se cargará limpiamente.
- El initramfs contiene lo necesario para importar y montar.
- Los pools están lo bastante saludables como para que un reinicio no convierta “ligeramente degradado” en “no importable bajo presión.”
- Puedes revertir rápidamente sin manos remotas ni una larga indisponibilidad.
Una cita que vale la pena pegar en tu monitor:
“La esperanza no es una estrategia.” — Gene Kranz
Esa cita aplica a las actualizaciones de kernel más que al vuelo espacial. Las naves no ejecutan DKMS. Tú sí.
Hechos e historia interesantes que realmente importan operativamente
Esto no es trivia; explican por qué las actualizaciones de ZFS se sienten diferentes a las de ext4.
- ZFS fue diseñado para poseer la pila de almacenamiento. Fusiona la gestión de volúmenes y la semántica del sistema de ficheros, por eso las fallas pueden afectar tanto la “detección de discos” como la capa de “montaje” a la vez.
- Los feature flags de OpenZFS reemplazaron las “versiones de pool”. Los flags permiten que los pools evolucionen sin un número de versión monolítico, pero también crean trampas de compatibilidad sutiles en escenarios de rescate.
- ZFS en Linux está fuera del árbol del kernel. Eso significa que las actualizaciones del kernel pueden romper compilaciones de módulos o el comportamiento de carga incluso cuando el kernel en sí está bien.
- DKMS se inventó para reducir el dolor de recompilar manualmente. Ayuda—hasta que falla de forma no interactiva durante actualizaciones unattended, dejándote con un nuevo kernel y sin módulo.
- Los arranques root-on-ZFS dependen mucho de scripts en initramfs. Si los scripts o módulos no están incluidos, el kernel puede arrancar perfectamente y aun así no encontrar root.
- ZFS cachea los mapeos device→vdev. Eso es estupendo para velocidad, pero archivos de cache obsoletos o nombres de dispositivo cambiados pueden complicar las importaciones durante el arranque temprano.
- El “hostid” existe por una razón. ZFS lo usa para prevenir imports simultáneos en almacenamiento compartido; un hostid incorrecto o ausente puede cambiar el comportamiento de import de maneras sorprendentes.
- La compresión y el checksum son conceptos siempre activos en el modelo de ZFS. Eso mejora la integridad de datos, pero también significa que “simplemente montarlo” es menos tolerante cuando los metadatos están dañados.
- Las distribuciones empresariales suelen parchear los kernels agresivamente. Una actualización “menor” todavía puede afectar el ABI para módulos externos.
Guion de diagnóstico rápido (cuando ya estás sudando)
Esto es para el momento después del reinicio cuando algo no se monta, ZFS no importa, o estás frente a un prompt de initramfs. No improvises; malgastarás tiempo de la ventana de outage en ansiedad.
Primero: prueba si el módulo ZFS existe y puede cargarse
- Pregunta: ¿Está presente el módulo del kernel ZFS para este kernel?
- Por qué: Si falta, nada más importa todavía.
cr0x@server:~$ uname -r
6.5.0-28-generic
cr0x@server:~$ modinfo zfs | sed -n '1,8p'
filename: /lib/modules/6.5.0-28-generic/updates/dkms/zfs.ko
version: 2.2.3-1ubuntu1
license: CDDL
description: ZFS filesystem
author: OpenZFS
srcversion: 1A2B3C4D5E6F7A8B9C0D
depends: znvpair,zcommon,zunicode,zzstd,icp,spl
Decisión: Si modinfo falla con “not found”, estás en territorio de módulos. Arranca con un kernel antiguo o recompila/instala ZFS para este kernel. Si existe, intenta cargarlo y lee el error.
cr0x@server:~$ sudo modprobe zfs
modprobe: ERROR: could not insert 'zfs': Unknown symbol in module, or unknown parameter (see dmesg)
cr0x@server:~$ dmesg | tail -n 15
[ 12.841234] zfs: disagrees about version of symbol module_layout
[ 12.841250] zfs: Unknown symbol spl_kmem_cache_alloc (err -22)
Decisión: “Unknown symbol” suele significar incompatibilidad de ABI: módulo construido para otro kernel, o módulos obsoletos. Recompila DKMS o instala el paquete kmod correcto para el kernel en ejecución. No intentes “forzar la importación.” No hay flag de fuerza para símbolos faltantes.
Segundo: prueba visibilidad del pool vs importabilidad
cr0x@server:~$ sudo zpool import
pool: tank
id: 1234567890123456789
state: ONLINE
action: The pool can be imported using its name or numeric identifier.
config:
tank ONLINE
mirror-0 ONLINE
sda3 ONLINE
sdb3 ONLINE
Decisión: Si el pool aparece listado, ZFS está funcionando y puede ver los vdevs. Si no aparece, estás en detección de dispositivos (drivers faltantes, cableado incorrecto, HBA muerto, rutas /dev equivocadas) o ZFS no está en ejecución.
Tercero: si tienes root en ZFS, revisa las suposiciones del initramfs
Si estás en initramfs sin root, la pregunta más rápida es: ¿incluyó initramfs ZFS y los scripts correctos?
cr0x@server:~$ lsmod | grep -E 'zfs|spl'
zfs 6209536 0
spl 163840 1 zfs
Decisión: Si ZFS no está cargado en initramfs, probablemente enviaste un initramfs roto. Arranca el kernel/initramfs antiguo desde GRUB y recompila el initramfs correctamente.
Broma #1 (corta, relevante): Una actualización de kernel sin plan de rollback es como un paracaídas con “v2” en el nombre — técnicamente mejor, espiritualmente aterrador.
Preflight antes del reinicio: tareas con comandos, salidas y decisiones
El resto de este artículo es un conjunto de comprobaciones aburridas que previenen outages dramáticos. Cada tarea incluye: comando, salida de ejemplo, qué significa y la decisión que tomas.
Nota de alcance: Los comandos abajo asumen un entorno Debian/Ubuntu-ish con OpenZFS on Linux. La lógica se generaliza a otras distros; los detalles de empaquetado no.
Tarea 1: Confirma en qué kernel estás y cuál vas a arrancar
cr0x@server:~$ uname -r
6.2.0-39-generic
cr0x@server:~$ ls -1 /boot/vmlinuz-* | tail -n 3
/boot/vmlinuz-6.2.0-39-generic
/boot/vmlinuz-6.5.0-28-generic
/boot/vmlinuz-6.5.0-31-generic
Qué significa: Tienes múltiples kernels instalados; bien. El más nuevo normalmente será el predeterminado según la configuración de GRUB.
Decisión: Si solo tienes un kernel instalado, para. Instala al menos un kernel previo conocido antes de arriesgarte a reiniciar.
Tarea 2: Verifica la alineación de versiones entre userspace ZFS y el módulo del kernel
cr0x@server:~$ zfs --version
zfs-2.2.3-1ubuntu1
zfs-kmod-2.2.3-1ubuntu1
Qué significa: Las herramientas de espacio de usuario y el paquete del módulo del kernel coinciden en versión. Esto no garantiza que el módulo esté compilado para el nuevo kernel, pero es una comprobación básica de cordura.
Decisión: Si userspace y kmod difieren mucho, espera sorpresas. Alinea versiones con tu gestor de paquetes antes de reiniciar.
Tarea 3: Comprueba el estado de DKMS para ZFS contra los kernels instalados
cr0x@server:~$ dkms status | grep -i zfs
zfs/2.2.3, 6.2.0-39-generic, x86_64: installed
zfs/2.2.3, 6.5.0-31-generic, x86_64: installed
Qué significa: DKMS compiló ZFS para ambos kernels, el actual y el objetivo.
Decisión: Si el kernel objetivo falta aquí, no reinicies aún. Arregla la compilación DKMS primero, mientras todavía tienes un sistema funcional donde hacerlo.
Tarea 4: Fuerza una prueba de compilación para el kernel nuevo (porque DKMS a veces miente por omisión)
cr0x@server:~$ sudo dkms autoinstall -k 6.5.0-31-generic
Sign command: /lib/modules/6.5.0-31-generic/build/scripts/sign-file
Signing key: /var/lib/shim-signed/mok/MOK.priv
Public certificate (MOK): /var/lib/shim-signed/mok/MOK.der
zfs.ko:
Running module version sanity check.
- Original module
- No original module exists within this kernel
- Installation
- Installing to /lib/modules/6.5.0-31-generic/updates/dkms/
depmod...
Qué significa: La compilación tuvo éxito; el módulo se instaló; depmod se ejecutó.
Decisión: Si ves errores de compilación, headers faltantes o “bad return status,” considéralo un stop duro. Reiniciar convertirá un error de compilación en un outage.
Tarea 5: Confirma que existen los headers para el kernel nuevo
cr0x@server:~$ dpkg -l | grep -E 'linux-headers-6.5.0-31-generic'
ii linux-headers-6.5.0-31-generic 6.5.0-31.31~22.04.1 amd64 Linux kernel headers for version 6.5.0 on 64 bit x86 SMP
Qué significa: Los headers están instalados, así que DKMS tiene una posibilidad razonable.
Decisión: Si los headers no están, instálalos ahora y vuelve a ejecutar la prueba DKMS.
Tarea 6: Comprueba la firma de módulos en Secure Boot (si aplica)
cr0x@server:~$ mokutil --sb-state
SecureBoot enabled
cr0x@server:~$ sudo modprobe zfs
modprobe: ERROR: could not insert 'zfs': Key was rejected by service
Qué significa: El módulo existe pero no se puede cargar porque no está firmado con una clave confiable por el sistema (MOK/UEFI).
Decisión: Firma el módulo ZFS apropiadamente e inscribe la clave, o desactiva Secure Boot si tu política lo permite. “Lo arreglaremos después del reinicio” no es un plan; es una trampa.
Tarea 7: Verifica la salud del pool y contadores de errores (un reinicio no sana)
cr0x@server:~$ sudo zpool status -x
all pools are healthy
cr0x@server:~$ sudo zpool status tank
pool: tank
state: ONLINE
status: One or more devices has experienced an unrecoverable error. An
attempt was made to correct the error. Applications are unaffected.
action: Determine if the device needs to be replaced, and clear the errors
using 'zpool clear' or replace the device with 'zpool replace'.
scan: scrub repaired 0B in 00:17:21 with 0 errors on Thu Dec 12 03:27:01 2025
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
sda3 ONLINE 0 0 0
sdb3 ONLINE 1 0 0
errors: No known data errors
Qué significa: Incluso si el pool está ONLINE, tienes al menos un error de lectura en un dispositivo. Eso es una luz amarilla.
Decisión: Si cualquier dispositivo muestra contadores READ/WRITE/CKSUM en aumento, investiga antes de reiniciar. Los reinicios son cuando los discos marginales deciden convertirse en performance art.
Tarea 8: Estado y timing del scrub: ¿has validado el pool recientemente?
cr0x@server:~$ sudo zpool get -H -o name,value,source autotrim tank
tank on local
cr0x@server:~$ sudo zpool status tank | sed -n '1,12p'
pool: tank
state: ONLINE
scan: scrub repaired 0B in 00:17:21 with 0 errors on Thu Dec 12 03:27:01 2025
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
Qué significa: Tienes un scrub reciente con 0 errores, que es lo más cercano a “conocido bueno” que ofrece ZFS.
Decisión: Si el último scrub es antiguo y esta máquina importa, ejecuta uno antes de la ventana de mantenimiento. Si no tienes tiempo para un scrub completo, al menos acepta que reinicias a ciegas.
Tarea 9: Revisa los feature flags para evitar “funciona aquí, falla en rescue”
cr0x@server:~$ sudo zpool get -H -o name,property,value all tank | grep -E 'feature@|compatibility' | head -n 12
tank feature@async_destroy enabled
tank feature@spacemap_histogram enabled
tank feature@extensible_dataset enabled
tank feature@bookmarks enabled
tank feature@embedded_data active
tank feature@device_removal enabled
tank feature@obsolete_counts enabled
tank feature@zstd_compress active
Qué significa: Algunas características están “active” (en uso). Un entorno de rescue con OpenZFS más antiguo podría negarse a importar, o importar en modo solo lectura con advertencias.
Decisión: Antes de upgrades, evita habilitar nuevos feature flags a la ligera. Si debes hacerlo, asegúrate de que tu media de rescate y hosts de rollback puedan importar el pool.
Tarea 10: Valida que los servicios ZFS arrancarán limpiamente en el arranque
cr0x@server:~$ systemctl status zfs-import-cache.service --no-pager
● zfs-import-cache.service - Import ZFS pools by cache file
Loaded: loaded (/lib/systemd/system/zfs-import-cache.service; enabled)
Active: active (exited) since Thu 2025-12-26 01:12:09 UTC; 2h 11min ago
cr0x@server:~$ systemctl status zfs-mount.service --no-pager
● zfs-mount.service - Mount ZFS filesystems
Loaded: loaded (/lib/systemd/system/zfs-mount.service; enabled)
Active: active (exited) since Thu 2025-12-26 01:12:11 UTC; 2h 11min ago
Qué significa: Tu ruta de arranque actual es sensata: pools importados, datasets montados.
Decisión: Si estos están deshabilitados o fallan, arréglalos antes de cambiar el kernel. Las actualizaciones de kernel no son la ocasión para descubrir que tu método de importación ZFS era “alguien lo hace manualmente.”
Tarea 11: Confirma tu método de importación: cachefile vs rutas by-id
cr0x@server:~$ sudo zpool get cachefile tank
NAME PROPERTY VALUE SOURCE
tank cachefile /etc/zfs/zpool.cache local
cr0x@server:~$ ls -l /etc/zfs/zpool.cache
-rw-r--r-- 1 root root 2270 Dec 26 01:12 /etc/zfs/zpool.cache
Qué significa: El sistema usa un cachefile para acelerar imports y preservar el mapeo de dispositivos. Bien—si se mantiene actualizado.
Decisión: Si mueves discos/HBAs o clonas VMs, regenera el cachefile intencionalmente. Los cachefiles obsoletos pueden causar comportamiento confuso en el arranque.
Tarea 12: Inspecciona el contenido del initramfs para módulos y scripts ZFS (especialmente root en ZFS)
cr0x@server:~$ lsinitramfs /boot/initrd.img-6.5.0-31-generic | grep -E 'zfs|spl|zpool' | head -n 12
usr/sbin/zpool
usr/sbin/zfs
usr/share/initramfs-tools/scripts/zfs
usr/share/initramfs-tools/hooks/zfs
lib/modules/6.5.0-31-generic/updates/dkms/zfs.ko
lib/modules/6.5.0-31-generic/updates/dkms/spl.ko
Qué significa: El initramfs incluye las herramientas de userspace ZFS, scripts y módulos para ese kernel.
Decisión: Si faltan piezas de ZFS en el initramfs, recompílalo ahora y vuelve a comprobar. De lo contrario estás a punto de arrancar un kernel que no puede montar los sistemas de ficheros que te importan.
Tarea 13: Recompila initramfs tras cualquier cambio en ZFS/módulos del kernel
cr0x@server:~$ sudo update-initramfs -u -k 6.5.0-31-generic
update-initramfs: Generating /boot/initrd.img-6.5.0-31-generic
Qué significa: initramfs regenerado para el kernel objetivo.
Decisión: Siempre regenera initramfs tras builds DKMS o actualizaciones de paquetes ZFS en sistemas con root en ZFS. Trátalo como parte de la instalación del módulo, no como un extra opcional.
Tarea 14: Confirma que GRUB tiene entradas para al menos un kernel previo
cr0x@server:~$ grep -n "menuentry 'Ubuntu" -n /boot/grub/grub.cfg | head -n 6
148:menuentry 'Ubuntu' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-simple-11111111-2222-3333-4444-555555555555' {
166:menuentry 'Ubuntu, with Linux 6.5.0-31-generic' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-6.5.0-31-generic-advanced-11111111-2222-3333-4444-555555555555' {
184:menuentry 'Ubuntu, with Linux 6.5.0-28-generic' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-6.5.0-28-generic-advanced-11111111-2222-3333-4444-555555555555' {
Qué significa: El menú de arranque incluye múltiples kernels.
Decisión: Si no hay kernels antiguos disponibles en GRUB, añádelos ahora. Durante un outage, tus dedos se olvidarán de escribir “chroot”. La selección de GRUB es la vía de escape más rápida.
Tarea 15: Captura el estado “conocido bueno” del sistema para comparaciones posteriores
cr0x@server:~$ sudo zpool status > /root/pre-reboot-zpool-status.txt
cr0x@server:~$ sudo zfs list -o name,used,avail,refer,mountpoint > /root/pre-reboot-zfs-list.txt
Qué significa: Ahora tienes instantáneas antes/después de la realidad.
Decisión: Siempre captura esto en sistemas que vas a solucionar más tarde. Convierte el vago “estaba bien ayer” en evidencia.
Tarea 16: Valida que tu dataset root y propiedades del pool de arranque son sensatas
cr0x@server:~$ sudo zfs get -o name,property,value -H mountpoint,canmount,readonly -r rpool/ROOT | head -n 10
rpool/ROOT mountpoint / local
rpool/ROOT canmount off local
rpool/ROOT/ubuntu mountpoint / local
rpool/ROOT/ubuntu canmount noauto local
rpool/ROOT/ubuntu readonly off default
Qué significa: Estás usando un patrón común root en ZFS: un dataset padre con canmount=off y un dataset hijo root.
Decisión: Si los mountpoints o flags canmount son inconsistentes, arréglalos antes de reiniciar. Las actualizaciones del kernel no rompen esto, pero exponen problemas de orden de arranque que ya estaban latentes.
Tarea 17: Confirma la estabilidad del hostid (evita confusión de import en storage compartido o clones)
cr0x@server:~$ hostid
7f000001
cr0x@server:~$ sudo zgenhostid -i
/etc/hostid: 7f000001
Qué significa: hostid existe y es estable.
Decisión: Si clonas VMs que puedan compartir pools (o ver los mismos discos), asegura hostid único. Las actualizaciones del kernel suelen ser cuando plantillas clonadas se convierten en “servidores reales”, y ZFS lo recuerda.
Tarea 18: Haz un snapshot dirigido antes de tocar kernels (para configs y rollbacks rápidos)
cr0x@server:~$ sudo zfs snapshot -r rpool/ROOT/ubuntu@pre-kernel-upgrade
cr0x@server:~$ sudo zfs list -t snapshot | grep pre-kernel-upgrade | head -n 3
rpool/ROOT/ubuntu@pre-kernel-upgrade 0B -
Qué significa: Creaste un snapshot del dataset root. En sistemas con mecanismos de boot environments adecuados, esto puede ser un rollback rápido.
Decisión: Si no puedes snapshotear root (layout raro, políticas), al menos copia /etc y la configuración de arranque. “Tenemos backups” no es suficientemente específico durante un outage.
Tarea 19: Comprueba el espacio libre (sí, importa para upgrades y comportamiento de ZFS)
cr0x@server:~$ sudo zfs list -o name,used,avail,usedbysnapshots,mountpoint tank
NAME USED AVAIL USEDBYSNAPSHOTS MOUNTPOINT
tank 18.2T 1.14T 3.55T /tank
Qué significa: Tienes margen. A ZFS no le gusta vivir cerca del 100% lleno; las asignaciones de metadatos y el rendimiento se vuelven feos.
Decisión: Si el pool está ajustado, haz limpieza primero. Las actualizaciones del kernel no son el mejor momento para descubrir que tu pool está sin espacio y no puede comprometer transacciones con fluidez.
Tarea 20: Haz un dry-run de acceso remoto y fallback por consola
cr0x@server:~$ sudo systemctl is-active ssh
active
cr0x@server:~$ sudo systemctl is-enabled serial-getty@ttyS0.service
enabled
Qué significa: SSH está activo; la consola serial está configurada (si la tienes). Esto es una facilidad de recuperación, no un lujo.
Decisión: Si no tienes acceso de consola fuera de banda, sé extra conservador: conserva kernels antiguos, practica rollback y programa ventanas de reinicio cuando humanos puedan acceder a la máquina.
Tres mini-historias corporativas (todas verdaderas en espíritu)
Mini-historia 1: El incidente causado por una suposición equivocada
Manejaban una pequeña flota de nodos de analytics. Nada sofisticado: varios servidores Linux, cada uno con un par de arranque en mirror y un gran pool ZFS para datos. El equipo trataba las actualizaciones de kernel como higiene rutinaria—porque durante años así fue.
Una semana, la distro lanzó una nueva línea de kernels y la pipeline de CI empezó a desplegarla. La actualización parecía limpia. Paquetes instalados, DKMS imprimió mensajes tranquilizadores y la ventana de mantenimiento fue corta. Reiniciaron, un nodo a la vez.
El primer nodo volvió… en initramfs. Podía ver discos, pero no podía importar el pool. El pánico siguió la ruta clásica: alguien dijo “ZFS está roto,” otro dijo “es el HBA,” y un tercero empezó a buscar runbooks antiguos que asumían ext4.
El problema real fue más simple y más vergonzoso: el módulo ZFS se había compilado para el nuevo kernel, pero Secure Boot lo rechazó. Nadie había probado la carga del módulo en un host con Secure Boot después de la rotación de claves. La “suposición equivocada” no fue técnica; fue procedimental: asumieron que el entorno no había cambiado porque los servidores no habían cambiado.
La recuperación tomó más tiempo del necesario porque tuvieron que arrancar con un kernel anterior, inscribir la clave correcta y luego rehacer la actualización correctamente. La lección que quedó: añade una comprobación modprobe zfs como puerta antes del reinicio. No puedes discutir con un kernel que rechaza código sin firmar.
Mini-historia 2: La optimización que se volvió en contra
Otra organización tenía una cultura de rendimiento. No la buena. La que alguien publica capturas de iostat en Slack como si fueran selfies de entrenamiento. Querían tiempos de reboot más rápidos, imports más rápidos, todo más rápido.
Alguien notó que importar pools escaneando dispositivos era “lento”, así que impusieron imports por cachefile en todas partes y deshabilitaron cualquier cosa que pareciera trabajo extra. También recortaron initramfs para reducir su tamaño, porque un initramfs más pequeño debe ser más rápido. Así funciona la lógica en las salas de conferencias.
Meses después, actualizaron kernels en un nodo de almacenamiento. La actualización en sí fue bien. Pero el reinicio cambió el orden de enumeración de dispositivos—una actualización de firmware del HBA también se había aplicado antes. El cachefile seguía referenciando nombres /dev antiguos. El arranque temprano intentó importar usando un mapeo obsoleto y, como habían recortado scripts, no existía el comportamiento de fallback de escaneo.
El servidor no importó pools automáticamente. Un operador importó manualmente con -d /dev/disk/by-id, todo subió y todos coincidieron en que fue “raro.” La rareza se repitió en el siguiente nodo. La “optimización” había eliminado resiliencia.
Lo solucionaron tratando las rutas de importación como deriva de configuración: o confías en rutas by-id estables y mantienes fallback de escaneo, o mantienes el cachefile intencionalmente y lo regeneras cuando cambie el hardware. “Boot más rápido” no es un KPI que merezca un pager.
Mini-historia 3: La práctica aburrida pero correcta que salvó el día
Gran plataforma de datos corporativa. Varios entornos. Muchos stakeholders. El equipo de almacenamiento no era querido, pero sí respetado—la diferencia suele ser papeleo.
Tenían una checklist para actualizaciones de kernel con ZFS. No era sofisticada. Era rígida. Incluía “verificar DKMS para el kernel objetivo”, “confirmar que initramfs contiene zfs.ko” y “confirmar que GRUB tiene entrada de kernel anterior.” Nadie la saltaba por estar “apurado”.
Una noche, llegó una actualización de kernel que rompió las compilaciones DKMS de ZFS debido a un desajuste de toolchain en esa imagen. Su pipeline lo detectó porque el preflight incluía dkms autoinstall -k como paso de validación. La compilación falló ruidosamente mientras el sistema aún estaba arriba y el nodo nunca reinició en estado roto.
La solución fue mundana: instalar los headers y bits del toolchain correctos, luego recompilar. La parte heroica fue que nadie tuvo que ser heroico. El clúster se mantuvo sano, la ventana de mantenimiento siguió aburrida y el informe de la mañana fue solo “completado con éxito.”
El arma secreta de ese equipo no fue la pericia. Fue insistir en las comprobaciones aburridas, siempre, especialmente cuando todo parecía fácil.
Listas de verificación / plan paso a paso
Usa esto como runbook. No lo “adaptes en vivo.” Adáptalo una vez, en un día tranquilo, y luego síguelo.
Plan paso a paso: la secuencia segura de reinicio
- Elige un kernel de rollback. Confirma que un kernel anterior esté instalado y seleccionable en GRUB. Si no puedes señalarlo, no lo tienes.
- Verifica la salud del pool.
zpool status -xdebe estar limpio o explicado. Cualquier resilver activo, dispositivo faltante o contadores de error en aumento debe retrasar el reinicio. - Revisa el scrub reciente. Si el sistema es crítico y el último scrub es antiguo, ejecuta uno antes del cambio.
- Instala kernel + headers. No los separes. Kernel sin headers es ruleta DKMS.
- Confirma compilaciones DKMS para el kernel objetivo. Usa
dkms statusy luego fuerza condkms autoinstall -k. - Prueba la carga del módulo en el sistema actual (si es posible). No puedes cargar un módulo compilado para otro kernel, pero puedes detectar problemas de Secure Boot/firmas probando tu flujo de firmado y el comportamiento del módulo actual.
- Regenera initramfs para el kernel objetivo. Luego inspecciónalo con
lsinitramfspara confirmar que el contenido ZFS existe. - Haz snapshot de datasets root. Especialmente si tienes un mecanismo de boot environments. Los snapshots son baratos; los outages no.
- Captura salidas del pre-estado. Guarda
zpool status,zfs listyjournalctl -bde arranques previos si persigues problemas intermitentes. - Reinicia un nodo, observa y luego procede. Si tienes varias máquinas, haz un canario. Si no, tu canario eres tú actuando con cuidado.
Lista mínima “tengo cinco minutos” (usar solo cuando el blast radius es pequeño)
zpool status -xestá limpiodkms status | grep zfsmuestra el kernel objetivolsinitramfs /boot/initrd.img-<target> | grep zfs.koencuentra el módulo- GRUB tiene una entrada de kernel anterior
- Tienes acceso a consola
Broma #2 (corta, relevante): Si tu plan de rollback es “SSH y lo arreglamos,” tu plan de rollback también es “creemos en magia.”
Errores comunes: síntoma → causa raíz → solución
1) El arranque cae a initramfs, el pool root no se importa
Síntoma: Llegas a una shell de initramfs. Mensajes mencionan filesystem root faltante, falla de import ZFS o “cannot mount rpool.”
Causa raíz: initramfs falta módulos/scripts ZFS para el kernel nuevo, o el módulo ZFS falló al cargar (Secure Boot, incompatibilidad ABI).
Solución: Arranca un kernel antiguo desde GRUB. Recompila DKMS para el kernel objetivo, ejecuta update-initramfs -u -k <target>, verifica con lsinitramfs y luego reinicia de nuevo.
2) El módulo ZFS existe pero no se carga: “Unknown symbol”
Síntoma: modprobe zfs falla; dmesg muestra símbolos desconocidos o mismatch de module_layout.
Causa raíz: Módulo compilado contra otro kernel, módulos obsoletos no reemplazados, o una actualización parcial dejó archivos inconsistentes bajo /lib/modules.
Solución: Recompila ZFS para el kernel exacto: dkms autoinstall -k $(uname -r) (o instala el kmod correcto). Ejecuta depmod -a. Si el empaquetado está roto, reinstala paquetes ZFS limpiamente.
3) Falla la carga del módulo: “Key was rejected by service”
Síntoma: El módulo ZFS no carga en sistemas con Secure Boot.
Causa raíz: Módulo no firmado o clave de firmado no confiable.
Solución: Inscribe una Machine Owner Key (MOK) y asegura que DKMS firme el módulo, o desactiva Secure Boot (si la política lo permite). Valida de antemano probando la carga del módulo tras la recompilación.
4) El pool se importa manualmente pero no auto-importa en el arranque
Síntoma: Tras reiniciar, los servicios están arriba pero los datasets faltan hasta que alguien ejecuta zpool import.
Causa raíz: Servicios zfs-import deshabilitados, cachefile faltante/obsoleto, o método de import no coincide con el entorno (p. ej., nombres de dispositivo cambiaron).
Solución: Habilita servicios de import, regenera /etc/zfs/zpool.cache intencionalmente exportando/importando, y prefiere rutas estables como /dev/disk/by-id para imports en entornos inusuales.
5) El pool no se importa en el entorno de rescue, pero sí en el host
Síntoma: La ISO de rescue no puede importar; el host sí.
Causa raíz: Feature flags del pool en uso son más nuevos que lo que soporta el entorno de rescue.
Solución: Mantén los entornos de rescue actualizados para que coincidan con tus feature flags. Evita habilitar nuevas features a menos que hayas verificado que tus herramientas de recuperación las manejan.
6) El reinicio tiene éxito, pero el rendimiento se desploma y la latencia sube
Síntoma: Tras la actualización del kernel, la latencia I/O aumenta; el comportamiento del ARC cambia; el uso de CPU sube.
Causa raíz: El nuevo kernel/módulo ZFS interactúa de forma distinta con límites de memoria, restricciones de cgroups o tunables. A veces el cambio es real; otras veces tu monitor moved etiquetas.
Solución: Compara /proc/spl/kstat/zfs/arcstats antes/después, revisa límites de memoria y revertir experimentos de tunables. No “optimices” durante el incidente; estabiliza primero.
Preguntas frecuentes
1) ¿Realmente necesito recompilar initramfs si DKMS dice que ZFS está instalado?
En sistemas root-on-ZFS o cualquier sistema que importe pools durante el arranque temprano: sí. DKMS compilando un módulo no garantiza que initramfs lo contenga. Verifica con lsinitramfs.
2) ¿Cuál es el mejor indicador de que un reinicio tendrá éxito?
Para root en ZFS: que el initramfs objetivo incluya módulos y scripts ZFS, y que puedas seleccionar un kernel previo en GRUB. Para pools no root: DKMS compiló para el kernel objetivo y los pools están saludables.
3) ¿Debo habilitar nuevos feature flags de pool durante mantenimiento rutinario?
No como un “por qué no”. Los feature flags son mayormente unidireccionales. Habilítalos cuando tengas una razón y después de confirmar que tus entornos de recuperación pueden importar el pool.
4) ¿Es más seguro usar kmods preconstruidos de la distro o DKMS?
Los kmods preconstruidos pueden ser más previsibles si tu distro los mantiene bien. DKMS es flexible pero añade un paso de compilación que puede fallar en el peor momento. Elige según la fiabilidad de tu entorno, no por ideología.
5) ¿Cómo sé si mi pool probablemente fallará al importar después del reinicio?
Si zpool status muestra dispositivos faltantes, resilver en curso, errores de checksum en aumento o recientes cortes de energía, retrasa el reinicio y estabiliza primero.
6) ¿Y si solo uso ZFS para un pool de datos, no para root?
Tu sistema arrancará aunque ZFS esté roto, lo cual es agradable. Pero tus aplicaciones no verán sus datos. La checklist sigue aplicando: verifica la compilación/carga del módulo y los servicios de auto-import.
7) ¿Por qué importan los cambios en nombres de dispositivos si ZFS usa GUIDs?
ZFS rastrea dispositivos por GUID, pero el comportamiento de import y las entradas del cachefile pueden depender de rutas. En arranque temprano o en entornos rescue limitados, rutas estables reducen sorpresas.
8) ¿Puedo simplemente mantener el kernel antiguo para siempre y evitar el problema?
Puedes, hasta que no puedas: parches de seguridad, soporte vendor y habilitación de hardware eventualmente te obligarán. La movida sostenible es volver las actualizaciones aburridas, no evitarlas.
9) ¿Cuál es el rollback más rápido si el kernel nuevo no puede importar pools?
Reinicia y selecciona el kernel previo desde GRUB. Por eso lo mantienes instalado y probado. Si no puedes alcanzar GRUB, necesitabas acceso por consola ayer.
10) ¿Debería exportar pools antes del reinicio?
Usualmente no para discos locales en un solo host; puede aumentar el riesgo si servicios esperan montajes durante el shutdown. Pero en storage compartido o setups multipath complejos, un export controlado puede reducir ambigüedad de “pool en uso”. Hazlo por decisión deliberada, no por superstición.
Conclusión: pasos prácticos siguientes
Una actualización del kernel con ZFS sale mal cuando la tratas como un parche de SO en lugar de un cambio en la pila de almacenamiento. La estrategia de supervivencia es consistente:
- Demuestra que el módulo ZFS existe para el kernel objetivo (estado DKMS más build forzado).
- Demuestra que initramfs contiene lo que el arranque necesita (inspecciona, no asumas).
- Demuestra que tus pools están lo bastante sanos para sobrevivir estrés (status, recencia de scrub, contadores de error).
- Demuestra que puedes revertir sin heroicidades (entradas GRUB, consola, snapshots).
La próxima vez que programes una ventana de reinicio, realiza las tareas de preflight en orden, guarda las salidas y trata cualquier bandera roja como un stop. La meta no es coraje. Es confianza con respaldo documental.