Esta pagina se ve mejor con JavaScript habilitado

Cambio disco zroot sin reinstalación en FreeBSD

 ·  🎃 kr0m

Mejorar el hardware de nuestros sistemas siempre es motivo de felicidad pero reinstalar el sistema operativo es una tarea laboriosa si queremos dejarlo fino tal y como nos gusta. Afortunadamente ZFS es capaz de ampliar un vdev en modo single a mirror de forma transparene, de este modo podremos en pocos pasos migrar zroot a otro disco sin necesidad de reinstalar.

Primero debemos conectar el disco nuevo, en mi caso se trata de un disco externo conectado mediante una carcasa USB, esto generó entradas en el registro dmesg del sistema:

dmesg

da1 at umass-sim1 bus 1 scbus7 target 0 lun 0
da1: <sobetter EXT 0204> Fixed Direct Access SPC-4 SCSI device
da1: Serial Number 3605E804107440A
da1: 40.000MB/s transfers
da1: 953869MB (1953525168 512 byte sectors)
da1: quirks=0x2<NO_6_BYTE>

Buscamos el disco da1 en la lista de camcontrol:

camcontrol devlist

<WDC WDS120G2G0A-00JH30 UE510000>  at scbus0 target 0 lun 0 (ada0,pass0)
<HL-DT-ST DVD+-RW GS20N A106>      at scbus1 target 0 lun 0 (cd0,pass1)
<WD 10EZEX External 1.75>          at scbus6 target 0 lun 0 (pass2,da0)
<sobetter EXT 0204>                at scbus7 target 0 lun 0 (pass3,da1)

Consultamos el estado actual del sistema:

zpool status

  pool: zroot
 state: ONLINE
  scan: scrub repaired 0B in 00:13:16 with 0 errors on Thu May 19 08:13:16 2022
config:

	NAME        STATE     READ WRITE CKSUM
	zroot       ONLINE       0     0     0
	  ada0p3    ONLINE       0     0     0

errors: No known data errors

Teniendo claro que disco es zroot y que disco es el nuevo, backupeamos el esquema de particiones de un disco a otro:

gpart backup ada0 | gpart restore -F da1

Nos aseguramos de que el backup se ha realizado correctamente:

gpart show ada0

=>       40  234454960  ada0  GPT  (112G)
         40       1024     1  freebsd-boot  (512K)
       1064        984        - free -  (492K)
       2048    4194304     2  freebsd-swap  (2.0G)
    4196352  230256640     3  freebsd-zfs  (110G)
  234452992       2008        - free -  (1.0M)
gpart show da1
=>        40  1953525088  da1  GPT  (932G)
          40        1024    1  freebsd-boot  (512K)
        1064         984       - free -  (492K)
        2048     4194304    2  freebsd-swap  (2.0G)
     4196352   230256640    3  freebsd-zfs  (110G)
   234452992  1719072136       - free -  (820G)

Recreamos la tercera partición para que ocupe el espacio adicional ya que el disco nuevo es de mayor tamaño:

gpart delete -i 3 da1

da1p3 deleted

Creamos una nueva teniendo en cuenta el alineamiento de particiones:

gpart add -i 3 -a 1m -t freebsd-zfs da1

da1p3 added

Consultamos el estado:

gpart show da1

=>        40  1953525088  da1  GPT  (932G)
          40        1024    1  freebsd-boot  (512K)
        1064         984       - free -  (492K)
        2048     4194304    2  freebsd-swap  (2.0G)
     4196352  1949327360    3  freebsd-zfs  (930G)
  1953523712        1416       - free -  (708K)

Añadimos el nuevo disco al vdev-zroot:

zpool attach zroot ada0p3 da1p3

Veremos que se están copiando los datos de un disco al otro:

zpool status

  pool: zroot
 state: ONLINE
status: One or more devices is currently being resilvered.  The pool will
	continue to function, possibly in a degraded state.
action: Wait for the resilver to complete.
  scan: resilver in progress since Thu May 19 11:17:19 2022
	11.5G scanned at 420M/s, 176M issued at 6.28M/s, 86.4G total
	182M resilvered, 0.20% done, no estimated completion time
config:

	NAME        STATE     READ WRITE CKSUM
	zroot       ONLINE       0     0     0
	  mirror-0  ONLINE       0     0     0
	    ada0p3  ONLINE       0     0     0
	    da1p3   ONLINE       0     0     0  (resilvering)

errors: No known data errors

Según el tipo de arranque que estemos utilizando instalaremos el bootstrap code de un modo u otro:

  • EFI: Volcamos la imagen RAW de una partición EFI sobre la partición efi del disco.
  • BIOS: Instalamos el bootstrap code en la MBR del disco(-b /boot/pmbr) y el contenido del loader(-p /boot/gptzfsboot) en la partición freebsd-boot.

Primero identificamos el tipo de instalación y luego instalamos en bootstrapcode:

Identificación:
gpart show da1|grep efi
    40      409600    1  efi  (200M)

Instalación, disco da1, partición 1:
gpart bootcode -p /boot/boot1.efifat -i 1 da1
Identificación:
gpart show da1|grep freebsd-boot
    40      1024      1  freebsd-boot  (512K)

Instalación, disco da1, partición 1:
gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 da1
Identificación:
gpart show da1
    40      409600    1  efi  (200M)  
    409640    1024    2  freebsd-boot  (512K)

Instalación:
disco da1, partición 1 -> EFI
disco da1, partición 2 -> BIOS

gpart bootcode -p /boot/boot1.efifat -i 1 da1
gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 2 da1

En mi caso se trata de un sistema BIOS:

gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 da1

partcode written to da1p1
bootcode written to da1

Cuando el mirror se haya duplicado veremos los dos discos online:

zpool status

  pool: zroot
 state: ONLINE
  scan: resilvered 90.1G in 03:20:15 with 0 errors on Thu May 19 14:37:34 2022
config:

	NAME        STATE     READ WRITE CKSUM
	zroot       ONLINE       0     0     0
	  mirror-0  ONLINE       0     0     0
	    ada0p3  ONLINE       0     0     0
	    da1p3   ONLINE       0     0     0

errors: No known data errors

Apagamos el sistema:

shutdown -p now

Quitamos el disco original y lo sustituimos por el nuevo.

Volvemos a arrancar.


El estado tras el cambio de disco es el siguiente:

zpool status

  pool: zroot
 state: DEGRADED
status: One or more devices could not be used because the label is missing or
	invalid.  Sufficient replicas exist for the pool to continue
	functioning in a degraded state.
action: Replace the device using 'zpool replace'.
   see: https://openzfs.github.io/openzfs-docs/msg/ZFS-8000-4J
  scan: resilvered 90.1G in 03:20:15 with 0 errors on Thu May 19 14:37:34 2022
config:

	NAME        STATE     READ WRITE CKSUM
	zroot       DEGRADED     0     0     0
	  mirror-0  DEGRADED     0     0     0
	    ada0p3  FAULTED      0     0     0  corrupted data
	    ada0p3  ONLINE       0     0     0

errors: No known data errors

Cuando se sustituye ada0 el nuevo disco se remapea a ada0, por lo tanto ada0p3 está FAULTED porque ese era el nombre del disco antes de sacarlo y está ONLINE porque es el antiguo da1p3 remapeado a ada0p3 en este último boot.

Consultamos los discos:

camcontrol devlist

<Samsung SSD 870 EVO 1TB SVT02B6Q>  at scbus0 target 0 lun 0 (ada0,pass0)
<HL-DT-ST DVD+-RW GS20N A106>      at scbus1 target 0 lun 0 (cd0,pass1)
<WD 10EZEX External 1.75>          at scbus6 target 0 lun 0 (pass2,da0)

Eliminamos el disco FAULTED del pool:

zpool detach zroot ada0p3

Quedando del siguiente modo:

zpool status

  pool: zroot
 state: ONLINE
  scan: resilvered 90.1G in 03:20:15 with 0 errors on Thu May 19 14:37:34 2022
config:

	NAME        STATE     READ WRITE CKSUM
	zroot       ONLINE       0     0     0
	  ada0p3    ONLINE       0     0     0

errors: No known data errors

Si consultamos el espacio del pool todavía seguirá con el tamaño anterior:

zpool list

NAME      SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP    HEALTH  ALTROOT
zroot     109G  91.0G  18.0G        -      819G    73%    83%  1.00x    ONLINE  -

Expandimos el pool:

zpool online -e zroot ada0p3

Volvemos a consultar los datos:

zpool list

NAME      SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP    HEALTH  ALTROOT
zroot     929G  91.0G   838G        -         -     8%     9%  1.00x    ONLINE  -

Dejo mi configuración del autoexpand ya que puede resultar útil por si leéis acerca del autoexpand en algún foro:

zpool get autoexpand

NAME     PROPERTY    VALUE   SOURCE
storage  autoexpand  off     default
zroot    autoexpand  off     default

Como nota final destacar que un efecto colateral de esta mogración es que la fragmentación del pool se ha reducido considerablemente.

Si te ha gustado el artículo puedes invitarme a un RedBull aquí