ZFS zpool import -d: Encontrar pools cuando cambian las rutas de dispositivos

¿Te fue útil?

ZFS es implacable con la integridad de los datos y curiosamente indulgente con casi todo lo demás. Puedes desconectar un controlador, cambiar un backplane, reordenar el cableado, y ZFS normalmente mantendrá tus datos a salvo. Pero puede “olvidar” dónde vive tu pool, porque la idea del sistema operativo sobre los nombres de disco es… interpretativa. El /dev/sdb de hoy puede ser el /dev/sde de mañana, y el pool que antes se importaba automáticamente ahora te mira como si fuera la primera vez que se encuentran.

Aquí es donde zpool import -d demuestra su valor. No es magia; simplemente le dice a ZFS dónde buscar nodos de dispositivo (o archivos) que puedan contener miembros del pool. La clave es saber qué directorio darle, qué hace con ese directorio y cómo interpretar los resultados bajo presión—por ejemplo cuando un VP pregunta por qué el “lago de datos” es actualmente un “espejismo de datos”.

Qué hace realmente zpool import -d

zpool import es la herramienta de ZFS para “encontrar pools que existen pero que no están importados actualmente”. Cuando la ejecutas sin argumentos, busca en un conjunto predeterminado de ubicaciones dispositivos que puedan contener etiquetas ZFS (los metadatos al inicio/fin de cada vdev).

zpool import -d <dir> cambia el ámbito de búsqueda. Le estás diciendo a ZFS: “Busca en este directorio nodos de bloque (o archivos) que puedan contener etiquetas ZFS.” Escaneará las entradas bajo ese directorio, abrirá dispositivos, leerá etiquetas e intentará ensamblar pools candidatos.

Comportamientos clave que importan en producción

  • -d indica dónde buscar, no qué importar. Afecta al descubrimiento. La importación sigue las reglas normales (comprobaciones de hostid/pool activo, comportamiento de puntos de montaje, etc.).
  • Puedes especificar varias opciones -d. Esto es oro cuando tienes una mezcla de /dev/disk/by-id, dispositivos multipath o directorios de preparación.
  • -d puede apuntar a un directorio de archivos. Sí: importar pools desde imágenes es algo real (para forense o restauraciones de laboratorio).
  • El descubrimiento puede ralentizarse por un “directorio demasiado grande”. Apuntarlo a /dev en un sistema con muchos nodos de dispositivo, mapas multipath obsoletos o montajes de contenedores extraños puede convertir un “escaneo rápido” en un “¿por qué está colgado esto?”.

Broma #1: Si alguna vez confiaste en los nombres /dev/sdX en producción, o eres muy valiente o nunca has reiniciado.

Por qué cambian las rutas de dispositivos (y por qué le importa a ZFS)

Los nombres de dispositivos de bloque en Linux como /dev/sda se asignan según el orden de descubrimiento. Ese orden cambia porque el mundo cambia: tiempos de firmware distintos, reinicios de HBA, actualizaciones del kernel, un disco que hoy gira más lento, una reenumeración del bus PCIe o multipath eligiendo una ruta diferente primero.

ZFS almacena la identidad del vdev en etiquetas usando identificadores estables cuando están disponibles, pero aún necesita que el SO presente un nodo de dispositivo que pueda abrir y leer. Si tu pool se creó en /dev/sdb y luego configuraste cachefile o servicios de systemd que esperan esas rutas, puedes acabar con un arranque que no se importa automáticamente o una importación que usa una ruta inesperada.

Familias de rutas comunes que encontrarás

  • /dev/sdX: corto, cómodo e inestable entre reinicios y cambios de topología.
  • /dev/disk/by-id/: estable, basado en WWN/serial; preferido en servidores.
  • /dev/disk/by-path/: relativamente estable, describe la ruta del bus; puede cambiar si mueves cables/HBA.
  • /dev/mapper/mpath*: dispositivos multipath; estables pero requieren una configuración de multipath correcta (y disciplina).
  • /dev/zvol/: volúmenes ZFS presentados como dispositivos de bloque; no relevantes para la importación pero a menudo confundidos en chats de incidentes.

Hechos interesantes y contexto histórico

Algo de contexto hace que el comportamiento extraño de hoy parezca menos aleatorio—y te ayuda a explicarlo a quienes creen que el almacenamiento es “solo discos”.

  1. ZFS almacena varias etiquetas por dispositivo. Las etiquetas se escriben tanto al inicio como al final de cada miembro de vdev, lo que aumenta la resiliencia frente a sobrescrituras parciales y permite el descubrimiento incluso cuando un extremo está dañado.
  2. El diseño temprano de ZFS priorizaba la autodescripción. Los pools se describen a sí mismos: topología, GUIDs de vdev y config están embebidos en disco, no en una “base de datos” separada del gestor de volúmenes.
  3. La comprobación de “hostid” existe para impedir importar un pool activo en otro lugar. Es una característica de seguridad contra split-brain y desastres por doble montaje.
  4. /dev/sdX no está diseñado para ser estable. Linux lo trata como un detalle de implementación, no como un contrato de interfaz. Por eso existen los nombres por udev como by-id/by-path.
  5. ZFS precede muchas de las expectativas de arranque actuales en Linux. Muchos problemas de “ZFS no se importó en el arranque” son realmente ordenamiento del init, temporización de udev o manejo de cachefile—las pilas de arranque modernas son rápidas y el almacenamiento a veces no lo es.
  6. Multipath puede hacer que la importación parezca “embrujada”. Si existen tanto rutas crudas como mapas multipath, ZFS puede ver duplicados. Tu pool puede ser “importable” dos veces, y ninguna es la que realmente quieres.
  7. Importar en solo lectura es una función intencional. Permite forense seguro y reduce el riesgo cuando no estás seguro de si el pool se exportó limpiamente.
  8. ZFS puede importar pools desde archivos normales. No es un truco de fiesta; es como muchos laboratorios prueban actualizaciones y cómo algunos equipos de incidentes hacen comprobaciones rápidas fuera de línea.

Guion rápido de diagnóstico

Cuando un pool “desaparece” tras un cambio de rutas, tu objetivo es responder tres preguntas rápido: (1) ¿son visibles los discos?, (2) ¿se pueden leer las etiquetas ZFS?, y (3) ¿hay algo bloqueando la importación (hostid, uso activo, multipath, vdevs faltantes)?

Primero: confirma que el SO ve el hardware que crees que ve

cr0x@server:~$ lsblk -o NAME,TYPE,SIZE,MODEL,SERIAL,WWN,FSTYPE,MOUNTPOINTS
NAME   TYPE  SIZE MODEL            SERIAL        WWN                FSTYPE MOUNTPOINTS
sda    disk  1.8T HGST_HUS724...    K7J1...       0x5000cca25...             
sdb    disk  1.8T HGST_HUS724...    K7J2...       0x5000cca25...             
nvme0n1 disk 3.6T SAMSUNG_MZ...     S4EV...       0x0025385...               

Interpretación: si los WWN/serial esperados no están presentes, todavía no es un problema de ZFS. Es cableado, HBA, expander, multipath o un disco muerto. Si los discos están presentes pero los nombres cambiaron, continúa.

Segundo: verifica qué piensa ZFS que es importable

cr0x@server:~$ sudo zpool import
   pool: tank
     id: 12345678901234567890
  state: ONLINE
 action: The pool can be imported using its name or numeric identifier.
 config:

        tank                          ONLINE
          raidz1-0                    ONLINE
            /dev/sdb                  ONLINE
            /dev/sdc                  ONLINE
            /dev/sdd                  ONLINE

Interpretación: si esto muestra rutas /dev/sdX en las que ya no confías, aún puedes importar—pero deberías arreglar el nombrado persistente inmediatamente después. Si no aparece nada, probablemente necesites -d para señalar a ZFS el espacio de nombres correcto.

Tercero: busca en el espacio de nombres estable y busca duplicados

cr0x@server:~$ sudo zpool import -d /dev/disk/by-id
   pool: tank
     id: 12345678901234567890
  state: ONLINE
 action: The pool can be imported using its name or numeric identifier.
 config:

        tank                                            ONLINE
          raidz1-0                                      ONLINE
            wwn-0x5000cca25abcd001                      ONLINE
            wwn-0x5000cca25abcd002                      ONLINE
            wwn-0x5000cca25abcd003                      ONLINE

Interpretación: esto es lo que quieres ver. Si también aparece vía /dev/sdX o vía /dev/mapper, detente y decide qué capa es la autorizada. Importar a través de la capa “equivocada” es como ganar un fin de semana libre por las malas razones.

Cuarto: si la importación está bloqueada, identifica por qué antes de forzar

cr0x@server:~$ sudo zpool import tank
cannot import 'tank': pool may be in use from other system
use '-f' to import anyway

Interpretación: no añadas -f reflexivamente. Confirma que el pool no esté realmente importado en otro sitio (o que no se exportó limpiamente) y confirma que no estás viendo los mismos LUNs desde dos rutas (los errores de zonificación SAN ocurren).

Tareas prácticas: comandos + interpretación

A continuación están las tareas que realmente ejecuto en el campo. Cada una tiene una razón, un comando y cómo leer el resultado. Úsalas como bloques de construcción.

Task 1: Mostrar pools importables y las rutas de dispositivo que ZFS ve actualmente

cr0x@server:~$ sudo zpool import
   pool: backup
     id: 8811223344556677889
  state: DEGRADED
status: One or more devices could not be opened.
action: The pool can be imported despite missing devices.
   see: http://zfsonlinux.org/msg/ZFS-8000-2Q
 config:

        backup                         DEGRADED
          mirror-0                     DEGRADED
            /dev/sda                   ONLINE
            15414153927465090721       UNAVAIL

Interpretación: ZFS te está diciendo que falta un dispositivo por GUID. Eso no es “renombrado de dispositivo”; es “dispositivo no presente” (o presente bajo un espacio de nombres distinto que no escaneaste).

Task 2: Buscar en un directorio específico para dispositivos (conceptos básicos de -d)

cr0x@server:~$ sudo zpool import -d /dev/disk/by-id
   pool: backup
     id: 8811223344556677889
  state: ONLINE
action: The pool can be imported using its name or numeric identifier.
 config:

        backup                                           ONLINE
          mirror-0                                       ONLINE
            wwn-0x5000c500a1b2c3d4                        ONLINE
            wwn-0x5000c500a1b2c3e5                        ONLINE

Interpretación: el disco “faltante” en realidad estaba presente; simplemente no estabas buscando en el lugar correcto.

Task 3: Usar múltiples -d para cubrir entornos mixtos

cr0x@server:~$ sudo zpool import -d /dev/disk/by-id -d /dev/mapper
   pool: sanpool
     id: 4000111122223333444
  state: ONLINE
action: The pool can be imported using its name or numeric identifier.
 config:

        sanpool                                          ONLINE
          mirror-0                                       ONLINE
            mpatha                                       ONLINE
            mpathb                                       ONLINE

Interpretación: si tu almacenamiento está multipath, prefiere importar vía /dev/mapper/mpath* o por-id para el dispositivo multipath, no las rutas crudas /dev/sdX. La consistencia importa más que el gusto.

Task 4: Detectar presentaciones duplicadas de dispositivos (rutas crudas vs multipath)

cr0x@server:~$ ls -l /dev/disk/by-id | grep -E 'wwn|dm-uuid|mpath' | head
lrwxrwxrwx 1 root root  9 Dec 25 09:10 dm-uuid-mpath-3600508b400105e210000900000490000 -> ../../dm-2
lrwxrwxrwx 1 root root  9 Dec 25 09:10 mpath-3600508b400105e210000900000490000 -> ../../dm-2
lrwxrwxrwx 1 root root  9 Dec 25 09:10 wwn-0x600508b400105e210000900000490000 -> ../../sdb

Interpretación: si el mismo LUN aparece como dm-* y sd*, debes decidir cuál debe usar ZFS. Importar con los dispositivos crudos sd* mientras multipath está activo es invitar a errores intermitentes de E/S y flaps de ruta en tu pool.

Task 5: Mirar las etiquetas ZFS directamente (comprobación de cordura)

cr0x@server:~$ sudo zdb -l /dev/disk/by-id/wwn-0x5000cca25abcd001 | head -n 25
------------------------------------
LABEL 0
------------------------------------
    version: 5000
    name: 'tank'
    state: 0
    txg: 1234567
    pool_guid: 12345678901234567890
    vdev_guid: 11112222333344445555
    top_guid: 66667777888899990000
    guid: 11112222333344445555

Interpretación: si zdb -l puede leer una etiqueta, el descubrimiento debería funcionar. Si no puede, puede que tengas un problema de permisos en el dispositivo, un disco muriendo, o que estés apuntando a lo incorrecto (partición vs disco entero, mapper vs crudo).

Task 6: Importar por ID numérico del pool (útil cuando los nombres colisionan o confunden)

cr0x@server:~$ sudo zpool import
   pool: tank
     id: 12345678901234567890
  state: ONLINE
action: The pool can be imported using its name or numeric identifier.

cr0x@server:~$ sudo zpool import -d /dev/disk/by-id 12345678901234567890

Interpretación: importar por ID evita errores cuando alguien renombra pools de forma inconsistente entre entornos (sí, eso pasa).

Task 7: Importar en solo lectura para inspeccionar de forma segura

cr0x@server:~$ sudo zpool import -o readonly=on -d /dev/disk/by-id tank
cr0x@server:~$ zpool status tank
  pool: tank
 state: ONLINE
config:

        NAME                                            STATE     READ WRITE CKSUM
        tank                                            ONLINE       0     0     0
          raidz1-0                                      ONLINE       0     0     0
            wwn-0x5000cca25abcd001                      ONLINE       0     0     0
            wwn-0x5000cca25abcd002                      ONLINE       0     0     0
            wwn-0x5000cca25abcd003                      ONLINE       0     0     0

Interpretación: la importación en solo lectura es una forma de bajo riesgo para confirmar que encontraste el pool correcto y que está sano antes de permitir que los servicios lo usen.

Task 8: Importar sin montar datasets (controlar el radio de impacto)

cr0x@server:~$ sudo zpool import -N -d /dev/disk/by-id tank
cr0x@server:~$ zfs list -o name,mountpoint,canmount -r tank | head
NAME            MOUNTPOINT  CANMOUNT
tank            /tank       on
tank/home       /home       on
tank/pg         /var/lib/pg on

Interpretación: -N importa el pool pero no monta los datasets. Esto es genial cuando quieres ajustar propiedades, comprobar claves de cifrado o evitar arrancar una base de datos que inmediatamente fallará por dependencias de red faltantes.

Task 9: Mostrar las rutas de vdev que ZFS usará después de importar (y corregirlas)

cr0x@server:~$ zpool status -P tank
  pool: tank
 state: ONLINE
config:

        NAME                       STATE     READ WRITE CKSUM
        tank                       ONLINE       0     0     0
          raidz1-0                 ONLINE       0     0     0
            /dev/sdb               ONLINE       0     0     0
            /dev/sdc               ONLINE       0     0     0
            /dev/sdd               ONLINE       0     0     0

Interpretación: -P muestra rutas completas. Si ves /dev/sdX, decide si puedes tolerarlo. En la mayoría de entornos, no puedes.

Para migrar a nombres estables por-id, típicamente exportas e importas usando las rutas deseadas:

cr0x@server:~$ sudo zpool export tank
cr0x@server:~$ sudo zpool import -d /dev/disk/by-id tank
cr0x@server:~$ zpool status -P tank | sed -n '1,25p'
  pool: tank
 state: ONLINE
config:

        NAME                                      STATE     READ WRITE CKSUM
        tank                                      ONLINE       0     0     0
          raidz1-0                                ONLINE       0     0     0
            /dev/disk/by-id/wwn-0x5000cca25abcd001 ONLINE       0     0     0
            /dev/disk/by-id/wwn-0x5000cca25abcd002 ONLINE       0     0     0
            /dev/disk/by-id/wwn-0x5000cca25abcd003 ONLINE       0     0     0

Interpretación: esta es la forma más simple de estabilizar rutas: cambia el descubrimiento de importación y deja que ZFS registre las rutas elegidas.

Task 10: Manejar “pool may be in use” de forma segura (hostid / importación forzada)

cr0x@server:~$ sudo zpool import -d /dev/disk/by-id tank
cannot import 'tank': pool may be in use from other system
use '-f' to import anyway

Interpretación: común después de mover discos a un host nuevo, restaurar una VM desde snapshot, o tras un apagado no limpio donde el sistema antiguo nunca exportó el pool.

Si estás seguro de que el pool no está activo en otra parte, fuerza la importación:

cr0x@server:~$ sudo zpool import -f -d /dev/disk/by-id tank

Interpretación: la bandera -f omite la comprobación de host. Úsala como una motosierra: eficaz, pero solo cuando la usas correctamente.

Task 11: Recuperar de un cachefile faltante / suposiciones erróneas sobre cachefile

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
ls: cannot access '/etc/zfs/zpool.cache': No such file or directory

Interpretación: algunas distribuciones dependen de un cachefile para la auto-importación en el arranque. Si el archivo falta o está obsoleto, el pool puede no importarse automáticamente aunque la importación manual funcione bien.

Después de importar el pool, regenera el cachefile:

cr0x@server:~$ sudo zpool set cachefile=/etc/zfs/zpool.cache tank
cr0x@server:~$ sudo zpool export tank
cr0x@server:~$ sudo zpool import -d /dev/disk/by-id tank

Interpretación: exportar e importar hace que el cachefile se actualice de forma coherente en muchos sistemas. (La integración exacta con el arranque varía, pero el patrón se mantiene.)

Task 12: Importar cuando intervienen particiones (confusión disco entero vs part)

cr0x@server:~$ lsblk -o NAME,SIZE,TYPE,FSTYPE /dev/sdb
NAME   SIZE TYPE FSTYPE
sdb    1.8T disk
sdb1  1.8T part zfs_member

cr0x@server:~$ sudo zpool import -d /dev/disk/by-id tank

Interpretación: si tu pool se construyó sobre particiones, asegúrate de escanear un directorio que incluya los symlinks de partición (by-id normalmente los incluye). Si apuntas -d a un directorio que solo contiene nodos de disco entero pero las etiquetas están en ...-part1, el descubrimiento puede fallar.

Task 13: Importar un pool desde archivos de imagen (movida de laboratorio/forense)

cr0x@server:~$ sudo mkdir -p /srv/zfs-images
cr0x@server:~$ sudo losetup -fP /srv/zfs-images/disk0.img
cr0x@server:~$ sudo losetup -fP /srv/zfs-images/disk1.img
cr0x@server:~$ losetup -a | grep zfs-images
/dev/loop0: [2065]:12345 (/srv/zfs-images/disk0.img)
/dev/loop1: [2065]:12346 (/srv/zfs-images/disk1.img)

cr0x@server:~$ sudo zpool import -d /dev/ tanklab
cannot import 'tanklab': no such pool available

cr0x@server:~$ sudo zpool import -d /dev/loop tanklab

Interpretación: los dispositivos loop siguen siendo dispositivos. Escanea donde viven. Esto muestra por qué -d es conceptualmente “dónde buscar”, no “qué tipo de disco”.

Task 14: Cuando la importación es lenta o parece colgada, reduce el escaneo

cr0x@server:~$ time sudo zpool import -d /dev
^C

cr0x@server:~$ time sudo zpool import -d /dev/disk/by-id
real    0m1.214s
user    0m0.084s
sys     0m0.190s

Interpretación: escanear /dev es la jugada de “estoy en pánico”. Puede funcionar, pero tiene un coste. Los espacios de nombres estables son más rápidos y menos propensos a errores.

Tres micro relatos del mundo corporativo

Micro relato 1: El incidente causado por una suposición equivocada

El incidente no empezó con ZFS. Empezó con una actualización de hardware bienintencionada: nuevos HBA con firmware más reciente, instalados durante una ventana de mantenimiento que era “definitivamente tiempo suficiente”. El sistema volvió, el SO arrancó y el dashboard de monitorización se puso en rojo porque el pool primario nunca se importó.

El ingeniero on-call inició sesión y vio que los discos estaban presentes. Ya no eran /dev/sd[bcd...]; eran /dev/sd[fgh...]. Eso es normal. La suposición equivocada fue que “normal” también significaba “inofensivo”. La unidad de auto-importación se había construido con expectativas obsoletas: un cachefile que referenciaba rutas antiguas, además de un script personalizado que hacía grep de nodos /dev/sdX como si fueran 2009.

Bajo presión, alguien ejecutó zpool import -f tank sin especificar -d, lo que importó usando el primer conjunto de dispositivos que ZFS encontró. Desafortunadamente, multipath también se había activado en la nueva configuración, y el pool se importó usando rutas crudas /dev/sdX aunque el equipo SAN esperaba /dev/mapper/mpath*. Todo parecía bien hasta que ocurrió un failover de ruta—entonces la latencia de E/S aumentó y empezaron a aparecer errores de checksum, porque el sistema ahora manejaba capas de dispositivo inconsistentes.

La solución fue aburrida: exportar el pool, importarlo usando el namespace previsto (/dev/mapper en ese entorno), regenerar el cachefile y eliminar el script personalizado. La conclusión del postmortem fue más afilada: si tu automatización depende de /dev/sdX, no tienes automatización; tienes un temporizador de cuenta regresiva.

Micro relato 2: La optimización que salió mal

Otro equipo quería arranques más rápidos. Les habían dicho que la importación de ZFS podía añadir segundos, y los segundos son aparentemente inaceptables cuando ejecutas microservicios que tardan minutos en ser útiles. Así que “optimizaron” quitando reglas de disk-by-id de su initramfs y apoyándose en un descubrimiento de dispositivos simplificado, asumiendo que el pool siempre aparecería bajo una ruta predecible.

Funcionó—hasta que no. Una actualización menor del kernel cambió la temporización de la enumeración de dispositivos. Los miembros del pool aparecieron, pero no a tiempo para la etapa de importación. El arranque continuó sin el pool, los servicios se iniciaron apuntando a directorios vacíos y el nodo se registró como “saludable” porque las comprobaciones de salud eran a nivel de aplicación, no de almacenamiento. Se notó el radio de impacto: contenedores escribiendo felizmente en el sistema raíz, llenándolo, mientras el dataset real permanecía desmontado como testigo silencioso.

Cuando el equipo intentó arreglarlo, ejecutaron zpool import -d /dev porque “cubre todo”. En ese host, “todo” incluía cientos de nodos de dispositivo de runtimes de contenedores y un desorden de entradas mapper obsoletas. Los escaneos de importación se volvieron lentos, se acumularon timeouts y el runbook de recuperación se convirtió en una aventura con opciones múltiples.

La solución final fue deshacer la optimización: restaurar el nombrado udev estable en el entorno de arranque temprano, importar usando /dev/disk/by-id y añadir una puerta dura para que los servicios no se inicien a menos que los datasets ZFS estén montados. Los arranques perdieron un par de segundos; los incidentes duraron horas menos. La compensación fue obvia una vez que alguien la vivió.

Micro relato 3: La práctica correcta y aburrida que salvó el día

La recuperación de ZFS más tranquila que he visto ocurrió en una empresa que trataba el almacenamiento como un sistema aeronáutico: poco glamuroso, con listas de verificación y nunca confiando en la “sabiduría tribal”. Tenían una regla: cada pool debe importarse usando rutas by-id, y cada sistema debe tener un procedimiento de exportación verificado antes de cualquier movimiento de hardware.

Durante una migración de centro de datos, se apagó una chapa, se movieron discos y se volvió a encender. Predeciblemente, los nombres de dispositivo cambiaron. También de forma predecible, a nadie le importó. El runbook decía: verificar discos por WWN, ejecutar zpool import -d /dev/disk/by-id, importar con -N, comprobar el estado y luego montar datasets. Lo siguieron al pie de la letra.

Tuvieron un contratiempo: el pool informó “may be in use from other system.” En lugar de forzar de inmediato, comprobaron si el nodo antiguo aún tenía acceso mediante una zona SAN persistente. La tenía. Eliminó la zona, esperaron a que las rutas desaparecieran y luego importaron limpiamente—sin necesidad de forzar.

La mejor parte fue el tono en el canal de incidentes. Sin drama, sin gestas heroicas, sin “prueba esta bandera aleatoria”. Solo una secuencia lenta y correcta. Era aburrida en el sentido que quieres para producción. Broma #2: Su runbook de almacenamiento era tan aburrido que podía curar el insomnio—a menos que disfrutes dormir durante los incidentes.

Errores comunes (con síntomas y soluciones)

Mistake 1: Escanear /dev y esperar lo mejor

Síntoma: zpool import -d /dev es lento, parece atascado o devuelve duplicados confusos.

Solución: escanea solo espacios de nombres estables: /dev/disk/by-id para discos locales, /dev/mapper para multipath. Usa múltiples -d si es necesario.

cr0x@server:~$ sudo zpool import -d /dev/disk/by-id -d /dev/mapper

Mistake 2: Importar vía rutas crudas cuando multipath está habilitado

Síntoma: el pool se importa, pero más tarde muestra errores intermitentes de E/S, flaps de ruta o jitter de rendimiento extraño durante el failover del controlador.

Solución: asegura que ZFS vea solo los dispositivos multipath (lista negra de rutas crudas en la configuración de multipath según corresponda), luego exporta/importa usando /dev/mapper/mpath* (o el by-id correspondiente para dm).

Mistake 3: Usar -f como primera respuesta

Síntoma: aparece pool may be in use from other system; el operador fuerza la importación sin verificar la exclusividad.

Solución: confirma que el host antiguo esté apagado o ya no tenga acceso a los discos/LUNs. Si es un SAN, confirma zonificación/masking. Si es una VM, confirma que no adjuntaste los mismos discos virtuales a dos invitados.

Mistake 4: Confundir “disco faltante” con “directorio equivocado escaneado”

Síntoma: zpool import muestra un vdev como UNAVAIL por GUID, pero lsblk muestra que el disco existe.

Solución: escanea el espacio de nombres que incluye el nodo real que contiene las etiquetas ZFS (partición vs disco entero). Prueba -d /dev/disk/by-id y verifica con zdb -l.

Mistake 5: Importar y montar todo inmediatamente

Síntoma: tras la importación, los servicios se inician demasiado pronto o los datasets se montan en lugares inesperados, causando corrupción de aplicaciones o incidentes de “escribió en el FS raíz”.

Solución: importa con -N, inspecciona, ajusta propiedades necesarias y luego monta deliberadamente.

cr0x@server:~$ sudo zpool import -N -d /dev/disk/by-id tank

Mistake 6: Creer que el cachefile es la verdad absoluta

Síntoma: el pool se importa manualmente pero no en el arranque; o se importa con rutas extrañas tras actualizaciones/movimientos.

Solución: regenera el cachefile después de importar con las rutas de dispositivo deseadas; asegúrate de que el sistema init use la ubicación correcta del cachefile para tu distro.

Listas de verificación / plan paso a paso

Paso a paso: recuperación de “Pool faltante después de reinicio”

  1. Confirma visibilidad del hardware: verifica WWNs/serial esperados.
  2. Escanea el espacio de nombres estable: usa zpool import -d /dev/disk/by-id.
  3. Si hay multipath: asegúrate de importar vía /dev/mapper, no rutas crudas.
  4. Importa de forma segura primero: usa -o readonly=on o -N según la situación.
  5. Comprueba salud: zpool status, confirma que no falten vdevs inesperados.
  6. Arregla persistencia de rutas: exporta y reimporta vía by-id/mapper; regenera cachefile.
  7. Monta datasets intencionalmente: luego inicia servicios.

Checklist: Antes de mover discos a un host nuevo

  1. Exporta el pool limpiamente (zpool export) y confirma que desapareció (zpool list no debería mostrarlo).
  2. Registra la disposición del pool: salida de zpool status -P guardada en tu ticket.
  3. Registra WWNs: lsblk -o NAME,SERIAL,WWN.
  4. En el host destino, confirma que esos WWNs aparecen antes de intentar importar.
  5. Importa con -d apuntando explícitamente a tu namespace elegido.

Checklist: Decidir tu política de “una sola ruta verdadera”

  • SATA/SAS local: prefiere /dev/disk/by-id/wwn-* o by-id basado en serial.
  • SAN con multipath: prefiere /dev/mapper/mpath* o by-id dm-uuid apuntando a dispositivos dm.
  • Evitar: raw /dev/sdX en cualquier cosa que tenga una ventana de cambios más larga que un descanso para café.

Preguntas frecuentes

1) ¿Qué escanea exactamente zpool import -d?

Escanea nodos de dispositivo (o archivos) encontrados bajo el directorio que especifiques, buscando etiquetas ZFS. Piensa en “ruta de búsqueda para posibles miembros de vdev”. No escanea recursivamente todo tu sistema de archivos—solo las entradas en ese espacio de nombres del directorio.

2) ¿Debería usar siempre /dev/disk/by-id?

Para discos locales, sí en la mayoría de entornos de producción. Es estable entre reinicios y cambios en la enumeración del controlador. Para SAN/multipath, /dev/mapper suele ser la capa correcta. Lo importante es elegir una y ser consistente.

3) ¿Por qué a veces zpool import muestra GUIDs en lugar de nombres de dispositivo?

Cuando un vdev no puede abrirse, ZFS recurre al GUID del vdev desde la config en disco. Eso es una pista: ZFS sabe lo que quiere, pero el SO no lo está presentando en la ruta intentada (o no lo presenta en absoluto).

4) ¿Es seguro ejecutar zpool import -f?

Puede ser seguro si estás seguro de que el pool no está activo en otro sitio. Es inseguro si los mismos discos/LUNs son accesibles desde otro host que también pueda importarlos. Confirma la exclusividad primero.

5) ¿Por qué la importación funciona manualmente pero no en el arranque?

Usualmente: temporización del descubrimiento de dispositivos (los discos aparecen después del intento de importación), cachefile faltante/obsoleto o orden del init. La importación manual ocurre más tarde, cuando udev y el almacenamiento ya se estabilizaron.

6) ¿Puedo usar zpool import -d para importar un pool construido sobre particiones?

Sí, siempre que el directorio que escanees incluya los nodos/symlinks de partición (por ejemplo, ...-part1 bajo by-id). Si escaneas un directorio que contiene solo discos enteros mientras el pool vive en particiones, el descubrimiento puede fallar.

7) ¿Cuál es la diferencia entre zpool import -d y arreglar los nombres de dispositivo permanentemente?

-d es una pista de descubrimiento para este intento de importación. La estabilidad permanente viene de importar consistentemente usando rutas estables (by-id/mapper) y asegurando que tu proceso de arranque y cachefile estén alineados con eso.

8) ¿Por qué a veces la importación muestra el mismo pool dos veces?

Porque el mismo almacenamiento subyacente es visible a través de múltiples capas de dispositivo (ruta cruda y multipath, o múltiples namespaces de symlink). Esa es una señal para detenerte y elegir la capa destinada antes de importar.

9) ¿Cómo confirmo que un disco específico forma parte del pool antes de importar?

Usa zdb -l contra el dispositivo candidato para leer su etiqueta y confirmar que el nombre del pool y el GUID coinciden con lo que esperas.

Conclusión

zpool import -d es la forma que tiene ZFS de decir: “Dime dónde están los dispositivos hoy y yo me encargo del resto.” En un mundo donde los nombres de dispositivo se asignan por temporización y capricho, ser explícito sobre las rutas de descubrimiento no es opcional—es cómo mantienes la recuperación predecible.

Cuando cambian las rutas de dispositivos, no te desesperes. Confirma que los discos existen, escanea el namespace correcto, importa de forma segura (-N o solo lectura), y luego haz la corrección duradera estandarizando rutas estables y manteniendo honesto tu flujo de arranque/importación. Si haces eso, los renombrados de dispositivos pasan a ser una nota al pie en lugar de un titular.

← Anterior
Passthrough de GPU en Proxmox: pantalla negra, UEFI/OVMF, problemas de ROM, fallos de reinicio y soluciones comprobadas
Siguiente →
WireGuard túnel dividido: enruta solo lo que necesitas (y mantén el resto local)

Deja un comentario