Pocos fallos de almacenamiento son tan groseros como un pool ZFS que antes funcionaba y ahora se niega a importarse. El servidor arranca, los discos giran y ZFS te mira y dice: “no”. El mensaje varía—etiquetas corruptas, vdevs faltantes, GUIDs erróneos—pero el resultado es el mismo: tus aplicaciones están caídas y tu estómago realiza su propio resilver.
Este texto trata sobre cómo recuperar ese pool de la manera correcta: con evidencia, el menor daño adicional posible y un plan que puedas explicarle a tu yo futuro. Trataremos “etiquetas corruptas” como un síntoma, no como un diagnóstico definitivo. Las etiquetas pueden estar realmente corruptas, o pueden parecer “corruptas” porque cambiaron las rutas de dispositivo, el HBA mintió, o importaste el pool equivocado en el host equivocado. ZFS suele decir la verdad. Los humanos son el componente poco fiable.
Qué son las etiquetas ZFS (y qué significa realmente “corrupta”)
ZFS no guarda un único “superbloque” en una ubicación preciosa. Escribe la configuración crítica del pool y la identidad del dispositivo en cuatro etiquetas por vdev: dos al inicio del disco (o partición) y dos al final. En esas etiquetas encontrarás cosas como:
- Pool GUID y nombre
- Vdev GUID y topología
- Punteros de transaction group (TXG) a “dónde está la verdad ahora”
- Uberblocks: un conjunto de puntos de control que permiten a ZFS encontrar el estado consistente más reciente
Cuando ZFS dice que una etiqueta está corrupta, puede significar varias cosas distintas:
- La suma de comprobación de la etiqueta no se verifica (corrupción real).
- El dispositivo no contiene los GUIDs de pool/vdev esperados (disco equivocado, disco obsoleto o cambio de mapeo del dispositivo).
- Sólo algunas etiquetas son legibles (daño parcial, problemas al final del disco, peculiaridades del enclosure).
- La etiqueta está bien, pero el resto del árbol de metadatos apunta a bloques que no se pueden leer (un problema I/O más profundo que emerge como fallo de etiqueta/uberblock).
Una matización adicional que la gente pasa por alto bajo estrés: la importación de ZFS es una operación intensiva en lecturas. La importación puede fallar porque las lecturas están agotándose por tiempo, no porque los metadatos sean lógicamente incorrectos. Una ruta que “más o menos funciona” bajo baja carga puede colapsar cuando ZFS escanea etiquetas, lee uberblocks e intenta abrir cada vdev. Así que cuando veas “etiqueta corrupta”, no alcances inmediatamente herramientas destructivas. Primero, prueba qué tipo de “corrupta” estás tratando.
Hechos interesantes y contexto histórico
- Las etiquetas ZFS son redundantes por diseño: cuatro por vdev. Perder una es común; perder las cuatro suele indicar un evento serio de I/O o sobrescritura.
- Los primeros diseños de ZFS evitaron puntos únicos de fallo: el enfoque multi-etiqueta forma parte de la filosofía de “sin superblock” que definió ZFS desde el inicio.
- La identidad del pool se basa en GUID, no en nombre: el nombre del pool es legible para humanos; el GUID es en quien confía ZFS.
- Las rutas de dispositivo no son identificadores estables: “/dev/sda” siempre ha sido una mala idea para pools de producción. Existen rutas persistentes como by-id porque el mundo es caótico.
- ZFS moderno mantiene múltiples uberblocks: puede retroceder a un estado consistente anterior cuando el TXG más reciente no es legible.
- El comportamiento de importación evolucionó: banderas como
-F(rewind) y funcionalidades como checkpoints existen porque los sistemas reales se bloquean, y los metadatos necesitan mecanismos seguros de fallback. - La realidad de sectores 4K pegó fuerte: errores de ashift (p. ej., 512e vs 4Kn) han causado pools que “funcionan” hasta que reemplazas un disco y de repente nada coincide como suponías.
- HBAs y expanders pueden mentir: reinicios transitorios de enlace y bugs de firmware del enclosure históricamente se han hecho pasar por corrupción.
- ZFS es conservador al importar: prefiere negarse a importar antes que importar un pool de forma que pueda causar daño silencioso.
Modos de fallo en la importación: los que importan
1) Corrupción real de etiquetas (sobrescritura o daño del medio)
Esto ocurre cuando algo sobrescribe el inicio/fin del dispositivo (herramienta de particionado equivocada, un “wipefs” mal dirigido, dd en la dirección errónea, un controlador RAID inicializando metadatos), o cuando el disco no puede leer esas regiones de forma fiable. En el caso de sobrescritura, suele ser súbito y total: ZFS no puede identificar el vdev en absoluto. En el caso del medio, puede ser intermitente: etiquetas legibles en un arranque, no legibles en el siguiente.
2) Mapeo de dispositivo equivocado (el clásico)
Los nombres de dispositivo cambian. El orden de controladores cambia. Multipath está medio configurado. Alguien movió discos entre estantes. El sistema operativo ahora presenta tus discos de forma distinta y ZFS no encuentra lo que espera. Esto parece corrupción porque ZFS ve discos, pero las etiquetas que lee no pertenecen al pool que intentas importar.
3) Vdevs faltantes (un disco ausente en RAIDZ no es “opcional”)
Los mirrors a menudo pueden funcionar con un miembro ausente. Los vdevs RAIDZ son más exigentes: un disco faltante puede impedir la importación, según la redundancia y qué disco falta. Además: si construiste el pool con particiones y ahora un disco aparece como dispositivo completo, ZFS puede no coincidirlo.
4) Fallo en la ruta de I/O que se disfraza de fallo de metadatos
La importación requiere lecturas en toda la topología. Un cable SAS defectuoso, alimentación marginal, problemas de expander o un HBA moribundo pueden convertirse en errores de “etiqueta corrupta” porque las lecturas agotaron tiempo o devuelven basura. Aquí es cuando dejas de creer en soluciones puramente de software y empiezas a mirar el hardware como si te debiera dinero.
5) Desajuste de flags de características / versión (menos común, pero real)
Importar un pool creado en una versión más nueva de OpenZFS en una implementación más antigua puede fallar. Normalmente eso no se presenta como “etiqueta corrupta”, pero en entornos enmarañados los mensajes pueden ser confusos. Mantén esto en la lista, pero no en la cima.
6) Importaste el pool equivocado (sí, pasa)
Laboratorios compartidos, discos reutilizados, entornos de staging. La máquina ve múltiples pools. Importas el equivocado y luego te preguntas por qué tus datasets esperados no están. O exportas el equivocado y tiras producción abajo de una manera que hace que todos de repente estén “disponibles para una llamada rápida”.
Broma #1: La forma más rápida de descubrir que tu inventario de activos está incompleto es intentar importar un pool ZFS durante una incidencia.
Guion de diagnóstico rápido
Esta es la secuencia de “no perderse”. El objetivo es encontrar el cuello de botella rápido: dispositivos equivocados, dispositivos faltantes o I/O fallando.
Primero: confirma lo que ZFS ve sin cambiar nada
- Listar pools importables (
zpool import). - Intentar importar en solo lectura si es visible (
zpool import -o readonly=on). - Captura los errores textualmente. No los resumas de memoria. Tu memoria no es un log.
Segundo: confirma la estabilidad de la identidad de los dispositivos
- Usa rutas persistentes:
/dev/disk/by-id(Linux) o nodos de dispositivo estables en tu SO. - Relaciona seriales con bahías/enclosures (con
lsblk,udevadm,smartctl). - Verifica que cada disco esperado esté presente y que el SO pueda leerlo sin errores.
Tercero: busca errores y timeouts de I/O
- Mira los logs del kernel por resets y timeouts (
dmesg,journalctl). - Ejecuta checks SMART rápidos y lee contadores de error.
- Si las lecturas fallan, detén la “cirugía ZFS” y arregla primero la ruta de hardware.
Cuarto: inspecciona las etiquetas directamente
- Usa
zdb -lcontra dispositivos candidatos para ver pool/vdev GUIDs. - Compara lo que encuentres con lo que la importación espera.
Quinto: solo entonces intenta rewind/recuperaciones
- Prueba la importación en solo lectura primero.
- Usa
-F(rewind) con precaución y entiende el rollback. - Usa flags extremos solo cuando puedas explicar el radio de impacto.
Tareas prácticas: comandos, salidas, decisiones
Estos son los movimientos de campo. Cada tarea incluye un comando, una salida de ejemplo, qué significa y la decisión que tomas a partir de ello. Asume Linux con OpenZFS salvo que se indique lo contrario.
Task 1: Listar pools que ZFS cree que existen
cr0x@server:~$ sudo zpool import
pool: tank
id: 10384722971711646021
state: ONLINE
action: The pool can be imported using its name or numeric identifier.
config:
tank ONLINE
mirror-0 ONLINE
ata-ST8000VN004-2M2101_ZA1A2B3C ONLINE
ata-ST8000VN004-2M2101_ZD4E5F6G ONLINE
pool: prod
id: 1692242210959834013
state: FAULTED
status: One or more devices contains corrupted data.
action: The pool cannot be imported due to damaged devices or data.
see: zpool(8)
config:
prod FAULTED corrupted data
raidz2-0 FAULTED
ata-WDC_WD120EMFZ-11A6JA0_9HGK1AAA UNAVAIL invalid label
ata-WDC_WD120EMFZ-11A6JA0_9HGK2BBB ONLINE
ata-WDC_WD120EMFZ-11A6JA0_9HGK3CCC ONLINE
ata-WDC_WD120EMFZ-11A6JA0_9HGK4DDD ONLINE
ata-WDC_WD120EMFZ-11A6JA0_9HGK5EEE ONLINE
ata-WDC_WD120EMFZ-11A6JA0_9HGK6FFF ONLINE
Qué significa: ZFS puede ver un pool llamado prod pero un dispositivo aparece como UNAVAIL invalid label. Eso es o bien un disco ausente, un dispositivo equivocado, o una etiqueta que no se puede leer.
Decisión: No ejecutar todavía zpool import -f. Primero, verifica que el disco exista y sea legible a nivel de SO, luego inspecciona las etiquetas.
Task 2: Intentar una importación en solo lectura (primer toque seguro)
cr0x@server:~$ sudo zpool import -o readonly=on prod
cannot import 'prod': one or more devices is currently unavailable
Qué significa: Solo lectura no anula los requisitos de vdev faltantes. El pool sigue sin poder ensamblarse.
Decisión: Identificar el dispositivo faltante/no disponible y si realmente falta o solo está mal identificado.
Task 3: Verificar que el SO vea los dispositivos de bloque esperados
cr0x@server:~$ lsblk -o NAME,SIZE,MODEL,SERIAL,WWN,TYPE | sed -n '1,12p'
NAME SIZE MODEL SERIAL WWN TYPE
sda 10.9T WDC WD120EMFZ-11A6 9HGK2BBB 0x50014ee2b1a2b222 disk
sdb 10.9T WDC WD120EMFZ-11A6 9HGK3CCC 0x50014ee2b1a2b333 disk
sdc 10.9T WDC WD120EMFZ-11A6 9HGK4DDD 0x50014ee2b1a2b444 disk
sdd 10.9T WDC WD120EMFZ-11A6 9HGK5EEE 0x50014ee2b1a2b555 disk
sde 10.9T WDC WD120EMFZ-11A6 9HGK6FFF 0x50014ee2b1a2b666 disk
Qué significa: Esperábamos seis discos; solo hay cinco presentes. El dispositivo con “etiqueta inválida” podría estar realmente ausente, no corrupto.
Decisión: Revisa conectividad física, la bahía del enclosure, visibilidad en el HBA y logs. No reescribas etiquetas para un disco que el SO ni siquiera ve.
Task 4: Revisar logs del kernel por resets de enlace y eventos de dispositivo faltante
cr0x@server:~$ sudo journalctl -k -b | egrep -i 'sd[a-z]|sas|ata|reset|timeout|I/O error' | tail -n 20
kernel: ata12: hard resetting link
kernel: ata12: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
kernel: sd 12:0:0:0: [sdf] tag#18 FAILED Result: hostbyte=DID_TIME_OUT driverbyte=DRIVER_OK
kernel: sd 12:0:0:0: [sdf] tag#18 CDB: Read(16) 88 00 00 00 00 00 00 00 00 10 00 00 00 08 00 00
kernel: blk_update_request: I/O error, dev sdf, sector 16 op 0x0:(READ) flags 0x80700 phys_seg 1 prio class 0
kernel: sd 12:0:0:0: [sdf] Synchronizing SCSI cache
kernel: sd 12:0:0:0: [sdf] Stopping disk
Qué significa: Hubo un sdf, pero agotó tiempo en lecturas cerca del inicio del disco (el sector 16 es territorio de etiquetas). Eso es clásico “etiqueta corrupta” causado por fallo de I/O.
Decisión: Tratar esto primero como hardware/ruta. Reasentar, cambiar cable, probar otro puerto HBA, revisar alimentación. Si es un fallo de disco único en RAIDZ2, planifica reemplazar el disco y dejar que ZFS sanee—una vez puedas importar.
Task 5: Enumerar IDs persistentes de dispositivos para evitar la ruleta /dev/sdX
cr0x@server:~$ ls -l /dev/disk/by-id/ | egrep 'WDC_WD120EMFZ|ST8000' | head
lrwxrwxrwx 1 root root 9 Dec 26 10:12 ata-WDC_WD120EMFZ-11A6JA0_9HGK2BBB -> ../../sda
lrwxrwxrwx 1 root root 9 Dec 26 10:12 ata-WDC_WD120EMFZ-11A6JA0_9HGK3CCC -> ../../sdb
lrwxrwxrwx 1 root root 9 Dec 26 10:12 ata-WDC_WD120EMFZ-11A6JA0_9HGK4DDD -> ../../sdc
lrwxrwxrwx 1 root root 9 Dec 26 10:12 ata-WDC_WD120EMFZ-11A6JA0_9HGK5EEE -> ../../sdd
lrwxrwxrwx 1 root root 9 Dec 26 10:12 ata-WDC_WD120EMFZ-11A6JA0_9HGK6FFF -> ../../sde
Qué significa: Estos IDs sobreviven a reinicios y renumeración de dispositivos mejor que los nombres sdX.
Decisión: Al importar o reemplazar dispositivos, usa estos identificadores estables (o equivalentes en tu SO). Si tu pool fue construido con rutas inestables, considera migrar la configuración una vez estés estable de nuevo.
Task 6: Inspeccionar etiquetas en un disco conocido bueno
cr0x@server:~$ sudo zdb -l /dev/disk/by-id/ata-WDC_WD120EMFZ-11A6JA0_9HGK2BBB | sed -n '1,25p'
------------------------------------
LABEL 0
------------------------------------
version: 5000
name: 'prod'
state: 0
txg: 1984567
pool_guid: 1692242210959834013
vdev_guid: 15812007741234567890
hostid: 1029384756
hostname: 'fileserver-a'
top_guid: 7321098765432109876
guid_sum: 12345678901234567890
Qué significa: Este disco claramente pertenece al pool prod (el pool GUID coincide con lo mostrado por la importación). Las etiquetas son legibles.
Decisión: Usa esto como referencia. Ahora inspecciona el disco “malo” (si es visible) para comprobar la legibilidad de etiquetas y si pertenece al mismo pool.
Task 7: Inspeccionar etiquetas en el disco sospechoso (si aparece)
cr0x@server:~$ sudo zdb -l /dev/sdf
failed to unpack label 0
failed to unpack label 1
failed to unpack label 2
failed to unpack label 3
Qué significa: Las cuatro etiquetas no son legibles. Eso no es “un bit volteado”. Usualmente son regiones ilegibles, un problema de traducción del controlador, o el disco está devolviendo datos sin sentido.
Decisión: Si este es un vdev redundante (mirror/RAIDZ con paridad suficiente), planifica reemplazar sdf. Si la redundancia es insuficiente, entras en territorio de recuperación de datos y debes evitar cualquier escritura al dispositivo.
Task 8: Validar si el disco está realmente fallando (SMART)
cr0x@server:~$ sudo smartctl -a /dev/sdf | egrep -i 'Reallocated|Pending|Uncorrect|Offline|CRC|SMART overall|Power_On_Hours'
SMART overall-health self-assessment test result: FAILED!
5 Reallocated_Sector_Ct 0x0033 001 001 010 Pre-fail Always - 3120
197 Current_Pending_Sector 0x0012 001 001 000 Old_age Always - 128
198 Offline_Uncorrectable 0x0010 001 001 000 Old_age Offline - 128
199 UDMA_CRC_Error_Count 0x003e 200 199 000 Old_age Always - 12
Power_On_Hours 0x0032 062 062 000 Old_age Always - 31240
Qué significa: El disco está fallando y el enlace tiene errores CRC también (podría ser cable/backplane). Que las etiquetas sean ilegibles encaja con esto.
Decisión: Reemplaza la unidad. También considera cambiar el cable/puerto, porque los errores CRC suelen ser relacionados con la ruta. Arregla ambos o volverás aquí pronto.
Task 9: Intentar import con escaneo de dispositivos limitado (reducir confusión)
cr0x@server:~$ sudo zpool import -d /dev/disk/by-id prod
cannot import 'prod': one or more devices is currently unavailable
Qué significa: Mismo resultado, pero has reducido la posibilidad de que ZFS coincida con nodos de dispositivo obsoletos o inesperados en otro lugar.
Decisión: Si el dispositivo faltante es real y la redundancia lo permite, considera importar degradado con -m (si está soportado/apropiado), pero solo después de confirmar qué vdev falta y cuál es tu redundancia real.
Task 10: Importar el pool (degradado) cuando la redundancia lo permita
cr0x@server:~$ sudo zpool import -o readonly=on -m prod
cannot import 'prod': I/O error
Destroy and re-create the pool from
a backup source.
Qué significa: Incluso la importación degradada no es posible porque el pool necesita datos que no se pueden leer desde los dispositivos restantes, o la ruta de I/O está enferma más allá de un disco.
Decisión: Para y reevalúa: puede que tengas más de un disco fallando, o que tu HBA/backplane esté dejando caer dispositivos. Vuelve al hardware y verifica que cada disco restante sea estable y legible.
Task 11: Identificar exactamente qué vdev GUID falta usando zdb (cuando el listado de importación es vago)
cr0x@server:~$ sudo zdb -C -e prod | sed -n '1,80p'
MOS Configuration:
pool_guid: 1692242210959834013
pool_name: prod
vdev_children: 1
vdev_tree:
type: 'root'
id: 0
guid: 7321098765432109876
children[0]:
type: 'raidz'
id: 0
guid: 882233445566778899
nparity: 2
children[0]:
type: 'disk'
id: 0
guid: 15812007741234567890
path: '/dev/disk/by-id/ata-WDC_WD120EMFZ-11A6JA0_9HGK2BBB'
children[1]:
type: 'disk'
id: 1
guid: 15812007749876543210
path: '/dev/disk/by-id/ata-WDC_WD120EMFZ-11A6JA0_9HGK3CCC'
children[2]:
type: 'disk'
id: 2
guid: 15812007740000111111
path: '/dev/disk/by-id/ata-WDC_WD120EMFZ-11A6JA0_9HGK1AAA'
Qué significa: ZFS espera un disco con serial 9HGK1AAA que actualmente está ausente/no legible. Ahora tienes un objetivo concreto para trabajo físico.
Decisión: Busca ese disco exacto en el chasis/enclosure. Si está presente pero no detectado, soluciona la ruta. Si se fue o está muerto, reemplázalo—luego importa y resilveriza.
Task 12: Si el pool se importó, verifica el estado antes de hacer cualquier otra cosa
cr0x@server:~$ sudo zpool status -v prod
pool: prod
state: DEGRADED
status: One or more devices could not be opened. Sufficient replicas exist for
the pool to continue functioning in a degraded state.
action: Replace the device using 'zpool replace'.
scan: scrub repaired 0B in 0 days 00:42:17 with 0 errors on Sun Dec 22 03:12:19 2025
config:
NAME STATE READ WRITE CKSUM
prod DEGRADED 0 0 0
raidz2-0 DEGRADED 0 0 0
ata-WDC_WD120EMFZ-11A6JA0_9HGK1AAA UNAVAIL 0 0 0 cannot open
ata-WDC_WD120EMFZ-11A6JA0_9HGK2BBB ONLINE 0 0 0
ata-WDC_WD120EMFZ-11A6JA0_9HGK3CCC ONLINE 0 0 0
ata-WDC_WD120EMFZ-11A6JA0_9HGK4DDD ONLINE 0 0 0
ata-WDC_WD120EMFZ-11A6JA0_9HGK5EEE ONLINE 0 0 0
ata-WDC_WD120EMFZ-11A6JA0_9HGK6FFF ONLINE 0 0 0
errors: No known data errors
Qué significa: El pool está arriba y degradado; te dice exactamente qué hacer a continuación.
Decisión: Reemplaza el dispositivo faltante y resilveriza. No hagas un scrub primero “para estar seguro”. Reemplaza primero y luego haz scrub después del resilver si necesitas confianza adicional.
Task 13: Reemplazar el disco fallado por uno nuevo (misma bahía, nuevo serial)
cr0x@server:~$ sudo zpool replace prod \
/dev/disk/by-id/ata-WDC_WD120EMFZ-11A6JA0_9HGK1AAA \
/dev/disk/by-id/ata-WDC_WD120EMFZ-11A6JA0_NEW9SER1AL
cr0x@server:~$ sudo zpool status prod
pool: prod
state: DEGRADED
scan: resilver in progress since Fri Dec 26 10:44:01 2025
1.23T scanned at 1.12G/s, 220G issued at 201M/s, 10.9T total
220G resilvered, 1.94% done, 0 days 15:10:22 to go
config:
NAME STATE READ WRITE CKSUM
prod DEGRADED 0 0 0
raidz2-0 DEGRADED 0 0 0
replacing-0 DEGRADED 0 0 0
ata-WDC_WD120EMFZ-11A6JA0_9HGK1AAA UNAVAIL 0 0 0 cannot open
ata-WDC_WD120EMFZ-11A6JA0_NEW9SER1AL ONLINE 0 0 0 (resilvering)
ata-WDC_WD120EMFZ-11A6JA0_9HGK2BBB ONLINE 0 0 0
ata-WDC_WD120EMFZ-11A6JA0_9HGK3CCC ONLINE 0 0 0
ata-WDC_WD120EMFZ-11A6JA0_9HGK4DDD ONLINE 0 0 0
ata-WDC_WD120EMFZ-11A6JA0_9HGK5EEE ONLINE 0 0 0
ata-WDC_WD120EMFZ-11A6JA0_9HGK6FFF ONLINE 0 0 0
errors: No known data errors
Qué significa: El resilver está progresando. Si se atasca, probablemente tengas más problemas de ruta o otro disco marginal bajo carga.
Decisión: Supervisa el resilver y los logs del sistema. Si ves timeouts, detén las heroicidades y arregla la estabilidad del hardware.
Task 14: Si la importación se queja de “pool activo” o propiedad de host, verifica y decide
cr0x@server:~$ sudo zpool import prod
cannot import 'prod': pool may be in use from other system
use '-f' to import anyway
Qué significa: ZFS piensa que el pool fue importado por otro sistema (o no se exportó limpiamente). Esto puede ser legítimo (almacenamiento compartido) o estar obsoleto (crash).
Decisión: Antes de usar -f, confirma que el otro host no esté usando realmente el pool. Si importas doblemente el mismo pool sin soporte de clustering, crearás corrupción en tiempo récord.
Task 15: Usar rewind (-F) solo después de medir el rollback
cr0x@server:~$ sudo zpool import -F -n prod
Would be able to return pool to state as of TXG 1984501
Would discard approximately 12 seconds of transactions
Qué significa: -n es tu cinturón de seguridad. Muestra lo que se perdería si haces rewind. Aquí es trivial (segundos), lo que suele significar un crash en medio de un TXG o un uberblock más reciente ilegible.
Decisión: Si la ventana de rollback es aceptable, procede con zpool import -F prod. Si son horas/días, detente y reevalúa; puede que estés importando dispositivos equivocados o enfrentando una corrupción más amplia.
Task 16: Después de importar, verifica el comportamiento de montaje y evita escrituras sorpresivas
cr0x@server:~$ sudo zfs get -o name,property,value,mountpoint,mounted -r mountpoint,mounted prod | head -n 12
NAME PROPERTY VALUE MOUNTPOINT MOUNTED
prod mountpoint /prod /prod yes
prod/home mountpoint /home /home yes
prod/backups mountpoint /backups /backups no
prod/backups mounted no - -
Qué significa: No todo se monta automáticamente, y eso puede ser intencional. En modo recuperación, también puede ser señal de que importaste en solo lectura o con settings de mountpoint alternativos.
Decisión: Confirma propiedades antes de volver a activar servicios. No permitas que una aplicación escriba en el mountpoint equivocado porque entraste en pánico y ayer usaste un altroot temporal.
Broma #2: “Funcionó en staging” reconforta hasta que recuerdas que staging es donde los datos van a morir en silencio.
Tres mini-historias corporativas desde el terreno
Mini-historia 1: El incidente causado por una suposición errónea
La empresa tenía un clúster de almacenamiento para artefactos internos—caches de build, capas de contenedores, salidas de CI. Nada glamuroso, pero todo dependía de ello. Una mañana, tras mantenimiento rutinario, el nodo primario reinició y el pool no se importó. La alerta decía “invalid label” en dos discos. El ingeniero on-call supuso que los discos estaban muertos porque el panel de hardware mostraba un par de luces ámbar. Historia fácil: reemplazar discos, resilverizar, seguir.
Cambiaron el primer disco. El pool siguió sin importarse. Cambiaron el segundo. Ahora el pool no solo no se importaba; además no podía ensamblar suficiente metadato para intentar un rewind. La gráfica de “confianza” pareció una pista de esquí.
La suposición equivocada: las luces ámbar no eran fallo de disco; eran problemas de negociación de enlace en un backplane particular. Los discos estaban bien. El backplane presentaba intermitentemente las direcciones SAS equivocadas, y el SO renombraba dispositivos entre arranques. ZFS veía “discos distintos” con “etiquetas equivocadas”, lo que parecía corrupción pero en realidad era churn de identidad.
Cuando finalmente se sentaron y compararon las salidas de zdb -l contra números de serie, se dieron cuenta de que los discos “malos” habían sido reemplazados por discos buenos que nunca habían estado en el pool. ZFS no se estaba portando cabezón; estaba correcto. El camino de recuperación fue feo pero educativo: reintroducir los discos originales (ahora en una ruta HBA estable), importar en solo lectura y reemplazar uno por uno correctamente.
Después cambiaron dos cosas. Primero, una regla: no reemplazar discos hasta probar la identidad del dispositivo y la estabilidad de la ruta de lectura. Segundo, dejaron de confiar en nombres sdX en cualquier runbook. “/dev/sdb” es una vibra, no un identificador.
Mini-historia 2: La optimización que salió mal
Otra organización decidió que el tiempo de importación era demasiado lento tras incidencias. Tenían un pool grande con muchos vdevs y muchos dispositivos detrás de expanders. Alguien leyó sobre acelerar el descubrimiento limitando rutas de escaneo y cacheando mapeos de vdev agresivamente. Afinaron scripts de arranque para importar usando un conjunto estrecho de nodos de dispositivo y recortaron reglas udev para “reducir ruido”. Hizo las importaciones más rápidas—hasta que no.
Meses después, un evento de energía menor hizo que un subconjunto de discos arrancara más lento de lo habitual. El script de import corrió temprano, solo escaneó las rutas “rápidas” y concluyó que el pool tenía vdevs faltantes. Luego intentó una importación forzada con flags de recuperación porque “eso es lo que el script hace cuando falla la importación”. El pool se importó en estado degradado con un rewind. Los servicios volvieron. Todos felicitaron la automatización.
El coste apareció después como errores raros en aplicaciones: datos recientes faltando en algunos datasets, archivos que volvieron a versiones antiguas. El rewind descartó una pequeña pero significativa ventana de transacciones. No fue una gran pérdida, pero sí de las que hacen que los auditores te miren como si admitirías disfrutar del downtime sorpresa.
La optimización salió mal porque cambió la corrección por velocidad sin salvaguardas. La importación no es el momento de ser ingenioso. ZFS está ensamblando un estado consistente; tus scripts no deberían “ayudar” saltándose discos que simplemente tardan en aparecer.
Lo arreglaron volviendo la lógica de arranque a algo aburrido: esperar a que udev se estabilice, escanear rutas by-id estables y negarse a usar flags de rewind automáticamente. Los flags de recuperación pasaron a ser una decisión humana con alguien leyendo primero la estimación de rollback.
Mini-historia 3: La práctica aburrida pero correcta que salvó el día
Una empresa del ámbito financiero administraba un pool ZFS que respaldaba un conjunto de archivos de cumplimiento. La carga era de “escribir-una-vez, leer-a-veces”, con scrubs periódicos de verificación. Era el tipo de sistema que la gente olvida que existe hasta que realmente lo necesita—justo cuando no quieres sorpresas.
Tenían una regla poco sexy: cada reemplazo de disco requería registrar el serial del disco, la ubicación en la bahía y el mapeo GUID vdev en un ticket. Sin excepciones. También tenían un ejercicio trimestral: simular una importación en un host de staging con pools exportados (solo lectura) para verificar que su procedimiento de recuperación aún coincidiera con la realidad.
Un día un controlador falló y fue reemplazado bajo garantía. Tras el reemplazo, el orden de enumeración de dispositivos cambió y un par de discos aparecieron con nombres OS distintos. La importación del pool falló inicialmente con “cannot open” y “invalid label” en lo que parecían dispositivos aleatorios.
El ingeniero on-call no adivinó. Sacó el último mapeo del sistema de tickets, lo comparó con las salidas de zdb -l en el host actual y reconstruyó la lista correcta de dispositivos usando rutas by-id. El pool se importó limpio, sin rewind necesario, sin discos solicitados en pánico.
No fue heroico. Fue correcto. Las prácticas aburridas no obtienen aplausos, pero te permiten dormir.
Errores comunes (síntoma → causa raíz → solución)
1) Síntoma: “invalid label” en un disco tras un reboot
Causa raíz: El disco está presente pero ilegible al inicio/fin (errores I/O), o el SO mapeó un disco diferente a la ruta esperada.
Solución: Revisa logs por timeouts de I/O, confirma seriales vía lsblk/udevadm, inspecciona etiquetas con zdb -l. Reemplaza sólo después de haber demostrado que es el disco correcto y que realmente falla.
2) Síntoma: Import muestra “pool may be in use from other system”
Causa raíz: Pool no exportado limpiamente, o realmente está importado en otro host (JBOD compartido, discos reutilizados, riesgo de split-brain).
Solución: Confirma que el otro host está abajo o ha exportado el pool. Solo entonces usa zpool import -f. Si el pool podría estar activo en otro sitio, detente. La importación doble es dolor autoinfligido.
3) Síntoma: Import sólo tiene éxito con rewind -F
Causa raíz: El uberblock/TXG más reciente es ilegible (a menudo por un disco fallando o reset del controlador durante una escritura), o faltaron dispositivos recientes durante el intento de importación.
Solución: Ejecuta zpool import -F -n primero y lee la ventana de rollback. Si es pequeña, procede. Si es grande, sospecha dispositivos equivocados o corrupción más amplia. Verifica la estabilidad del hardware antes de repetir importaciones.
4) Síntoma: Pool se importa pero los datasets se montan incorrectamente o no se montan
Causa raíz: Importado con altroot, readonly, o un cachefile cambiado; o las propiedades de mountpoint fueron modificadas en el caos.
Solución: Inspecciona zfs get mountpoint,mounted, confirma zpool get cachefile, y evita “arreglos temporales” que persistan. Haz el comportamiento de montaje explícito antes de reiniciar servicios.
5) Síntoma: Import se cuelga durante mucho tiempo
Causa raíz: Un disco está agotando tiempo en lecturas; ZFS espera I/O lento durante el descubrimiento de etiquetas/metadatos.
Solución: Revisa logs del kernel, ejecuta SMART y busca un dispositivo que ralentiza el sistema. Arregla la ruta o elimina el dispositivo fallado si la redundancia lo permite.
6) Síntoma: “corrupted data” inmediatamente después de que alguien “limpió particiones”
Causa raíz: Una herramienta sobrescribió áreas de etiqueta (inicio/fin) o cambió offsets de particionado.
Solución: Para de escribir en los discos. Identifica qué discos aún tienen etiquetas íntegras vía zdb -l. Si suficientes etiquetas sobreviven y la redundancia lo permite, importa y reemplaza. Si no, restauras desde backup o haces recuperación especializada.
7) Síntoma: Tras swap de HBA, la mitad de los discos muestra tamaños diferentes o mismatch 512/4K
Causa raíz: El controlador presenta distinto tamaño lógico de sector o traducción (512e vs 4Kn), confundiendo asunciones sobre ashift y alineamiento.
Solución: Confirma con lsblk -t y tamaños lógicos/físicos de sector. Mantén HBAs/firmware consistentes donde sea posible. No reconstruyas la topología a ciegas; valida primero y reemplaza con cuidado.
Listas de verificación / plan paso a paso
Checklist A: Antes de tocar nada (colección de evidencia)
- Captura la salida de
zpool importy guárdala en un lugar seguro. - Captura
lsblk -o NAME,SIZE,MODEL,SERIAL,WWN. - Captura fragmentos de logs del kernel sobre descubrimiento de discos y errores.
- Si el pool es visible, intenta
zpool import -o readonly=on(y registra el resultado).
Checklist B: Decide si esto es hardware/ruta o metadatos
- Si los logs muestran timeouts/resets/errores I/O: trata primero como hardware/ruta.
- Si los discos son estables y legibles pero ZFS afirma etiquetas inválidas: sospecha mapeo de dispositivo equivocado o etiquetas sobrescritas.
- Usa
zdb -len múltiples discos para confirmar consistencia de pool GUID.
Checklist C: Flujo seguro de importación
- Prefiere importar por rutas estables (
-d /dev/disk/by-id). - Intentar importación en solo lectura.
- Si “pool en uso”, confirma el estado del otro host antes de
-f. - Si es necesario, evalúa rewind con
-F -n, luego decide. - Una vez importado, revisa
zpool statusy montajes de datasets antes de iniciar aplicaciones.
Checklist D: Recuperación tras import (dejarlo sano)
- Reemplaza dispositivos fallidos/no disponibles usando identificadores estables.
- Monitorea resilver y logs; si aparecen errores, detente y arregla la ruta de I/O.
- Tras completar el resilver, ejecuta un scrub en una ventana controlada.
- Documenta lo ocurrido: qué disco, qué bahía, qué GUID, qué mostraron los logs.
Una frase para recordar
Idea parafraseada (atribuida a W. Edwards Deming): Sin datos, eres solo otra persona con una opinión.
Por eso recoges salidas primero y luego actúas. Recuperar ZFS no es un deporte basado en corazonadas.
Preguntas frecuentes
1) ¿Qué es exactamente una “etiqueta ZFS”?
Una pequeña región de metadatos almacenada de forma redundante (cuatro copias por vdev) al inicio y al final de cada dispositivo. Describe la identidad del pool, la topología y los punteros necesarios para encontrar el estado activo.
2) ¿“Etiqueta corrupta” siempre significa que el disco está malo?
No. Puede significar que el disco falta, la ruta del dispositivo cambió, el HBA devuelve basura o las áreas de etiqueta fueron sobrescritas. Demuestra la salud e identidad del disco antes de reemplazar.
3) ¿Puedo reparar etiquetas manualmente?
En operaciones normales, no “reparas etiquetas” escribiendo bytes mágicos. El patrón correcto es: importar si es posible, luego zpool replace del dispositivo fallido/faltante y dejar que ZFS reconstruya la redundancia. Reescribir etiquetas manualmente es para especialistas y suele venir después de “ya perdimos”.
4) ¿Es peligroso zpool import -f?
Puede serlo. Si el pool está genuinamente activo en otro host, forzar la importación arriesga escrituras simultáneas y corrupción real. Si el otro host está muerto y el pool no se exportó, -f a menudo es la opción correcta—tras la verificación.
5) ¿Qué hace realmente zpool import -F?
Retrocede el pool a un transaction group (TXG) anterior que parezca consistente y legible. Perderás las transacciones más recientes desde ese punto. Ejecuta siempre con -n primero para ver la estimación del rollback.
6) Mi pool se importa, pero está degradado. ¿Debo hacer scrub inmediatamente?
No. Reemplaza primero los dispositivos faltantes/fallidos. Hacer scrub en un pool degradado aumenta la carga de lectura y puede empujar discos marginales al fallo. Resilveriza para restaurar redundancia y luego haz scrub para mayor confianza.
7) ¿Por qué a veces las importaciones se cuelgan?
Porque ZFS está esperando I/O. Un solo disco que agota tiempo en lecturas puede bloquear el descubrimiento. Revisa logs del kernel y SMART; no sigas intentando importar mientras el hardware está fallando.
8) ¿Cómo evito esto la próxima vez?
Usa identificadores de dispositivo persistentes, documenta el mapeo disco→bahía, haz scrubs programados, monitorea resets/errores CRC y prueba tu procedimiento de recuperación cuando no estés en pánico.
9) Si las etiquetas de un disco no son legibles, ¿ZFS puede aun así importar?
Depende de la topología y la redundancia. Los mirrors son tolerantes. RAIDZ depende de paridad y de qué falta. Si ZFS no puede ensamblar el árbol de vdevs o cumplir requisitos de redundancia, se negará a importar.
10) ¿Debería usar alguna vez zpool import -D (pools destruidos) en casos de corrupción de etiquetas?
Sólo cuando tengas evidencia sólida de que el pool fue accidentalmente destruido/limpiado y estás haciendo recuperación intencional. No es una herramienta de primera línea para “invalid label” y puede complicar la situación si se usa a la ligera.
Conclusión: qué hacer la próxima vez
Cuando ZFS dice “etiquetas corruptas”, no te invita a empezar intentos aleatorios de reparación. Te está pidiendo que hagas lo que mejor saben hacer los operadores: reducir la incertidumbre. Comprueba lo que ZFS ve, verifica la identidad del dispositivo, busca fallos en la ruta de I/O e inspecciona etiquetas con zdb antes de cambiar nada.
Pasos prácticos siguientes:
- Estandariza el uso de nombres persistentes de dispositivo para pools (by-id/WWN o el equivalente de tu plataforma).
- Añade un paso en el runbook que recopile
zpool import,lsblky logs del kernel antes de cualquier reemplazo. - Monitorea resets/errores CRC y trátalos como precursores, no como trivialidades.
- Requiere aprobación humana para imports con rewind (
-F) y siempre ejecuta-nprimero. - Mantén un mapeo simple serial de disco → bahía → GUID vdev. Es aburrido, por eso funciona.