En corto

Disco bueno ada0, disco nuevo ada3, el muerto era ada1:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
zpool status zroot                                  # ada1p4 FAULTED / UNAVAIL
gpart backup ada0 | gpart restore -F ada3           # clona la tabla de particiones
gpart show ada3                                     # p1 efi, p2 freebsd-boot, p3 freebsd-swap, p4 freebsd-zfs

# Bootcode BIOS: el índice es el de la partición freebsd-boot
gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 2 ada3

# UEFI: rellena la ESP
newfs_msdos -F 32 -c 1 /dev/ada3p1
mount -t msdosfs /dev/ada3p1 /mnt
mkdir -p /mnt/EFI/BOOT /mnt/EFI/FREEBSD
cp /boot/loader.efi /mnt/EFI/BOOT/BOOTX64.EFI
cp /boot/loader.efi /mnt/EFI/FREEBSD/LOADER.EFI
umount /mnt

# El disco nuevo entra al mirror en el lugar del muerto
zpool replace zroot ada1p4 ada3p4
zpool status zroot                                  # resilver en curso

Cuando zpool status diga ONLINE en los dos, prueba a arrancar solo con el disco nuevo.

Antes de empezar

  • Identifica el disco. zpool status nombra el miembro muerto (ada1p4, o un GUID largo si ya no está). camcontrol devlist lista los discos con modelo y serie para saber cuál bahía tocar.
  • Si el disco malo sigue conectado, sácalo del pool antes de tirar del cable: zpool offline zroot ada1p4.
  • Layout. Una instalación por defecto de FreeBSD 13/14 con zroot crea, por disco: p1 efi, p2 freebsd-boot, p3 freebsd-swap, p4 freebsd-zfs. Instalaciones antiguas o a mano varían: mira gpart show ada0 y ajusta los índices. El -i del bootcode es el de freebsd-boot.
  • El disco nuevo tiene que ser igual o mayor. gpart restore copia tamaños exactos; si es mayor, el resto queda libre y lo puedes usar después.

Por qué particiones y no el disco entero

En un pool de arranque cada disco lleva las particiones de boot además de la de ZFS. Si haces zpool replace zroot ada1p4 ada3 con el disco crudo, el mirror funciona pero ese disco no puede arrancar: el día que ada0 muera, tendrás los datos y ningún cargador. Por eso el orden es: particionar igual, bootcode, y solo entonces zpool replace con la partición.

Paso a paso

1. Clonar la tabla de particiones.

1
2
gpart backup ada0 | gpart restore -F ada3
gpart show ada3

-F destruye lo que hubiera en ada3. Si el pool usa etiquetas GPT (gpt/zfs0 en zpool status) en vez de nombres adaXpY, ponle la suya al nuevo: gpart modify -i 4 -l zfs1 ada3, y usa gpt/zfs1 en el zpool replace.

2. Bootcode. Instala los dos: así arranca tanto si la placa está en modo BIOS/CSM como en UEFI.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# BIOS: MBR protector + gptzfsboot en la partición freebsd-boot (p2 en el layout por defecto)
gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 2 ada3

# UEFI: la ESP (p1) es un FAT32 con loader.efi en las rutas estándar
newfs_msdos -F 32 -c 1 /dev/ada3p1
mount -t msdosfs /dev/ada3p1 /mnt
mkdir -p /mnt/EFI/BOOT /mnt/EFI/FREEBSD
cp /boot/loader.efi /mnt/EFI/BOOT/BOOTX64.EFI
cp /boot/loader.efi /mnt/EFI/FREEBSD/LOADER.EFI
umount /mnt

Las guías viejas dicen gpart bootcode -p /boot/boot1.efifat -i 1; boot1.efi está obsoleto en FreeBSD actual y el camino documentado en loader.efi(8) es copiar loader.efi a la ESP. Si quieres una entrada propia en el firmware: efibootmgr -c -l /mnt/EFI/FREEBSD/LOADER.EFI -L FreeBSD-ada3 -a.

3. Reemplazar en el pool.

1
zpool replace zroot ada1p4 ada3p4

Si el miembro muerto ya no aparece y el mirror quedó con un solo disco, en vez de replace se añade al superviviente: zpool attach zroot ada0p4 ada3p4.

4. Resilver.

1
zpool status zroot           # scan: resilver in progress ... % done

Horas, según lo lleno que esté el pool. Opcional, para que el resilver no ceda tanto el turno a la carga normal:

1
sysctl vfs.zfs.resilver_min_time_ms=5000

5. Swap. Si /etc/fstab tenía /dev/ada1p3 como swap, cámbialo a /dev/ada3p3 (o mejor, a etiquetas gpt/swapN que no cambien con el nombre del disco) y swapon -a.

6. Comprobar el arranque. Con el resilver terminado, apaga, desconecta ada0 (o cambia el orden de arranque) y arranca desde el nuevo. Si entra, vuelve a conectar y zpool status debe seguir ONLINE sin quejas. Una zpool scrub zroot de cierre no está de más.

Trampas

  • gpart restore -F no pregunta. Revisa dos veces cuál es el disco nuevo; camcontrol devlist y diskinfo -v ada3 (serie) antes de escribir.
  • Bootcode de un solo tipo deja el disco arrancable solo en un modo de firmware. Pon los dos.
  • Sector físico distinto (512 vs 4K) puede hacer que zpool replace se queje del ashift; en un mirror moderno con ashift=12 un disco 4Kn entra sin problema, uno con ashift=9 no.
  • Disco más grande: tras el resilver, gpart resize -i 4 ada3 y zpool online -e zroot ada3p4; cuando los dos discos del mirror sean grandes, el pool crece.
  • Los nombres adaX cambian al quitar discos; las etiquetas GPT y los GUID no. Para la operación usa lo que muestre zpool status en ese momento.

Ver también