Esta pagina se ve mejor con JavaScript habilitado

FreeBSD update 13.0

 ·  🎃 kr0m

En este artículo explicaremos como migrar un sistema FreeBSD 12.2 a 13.0, las principales características a destacar de la versión 13 son la incorporación de OpenZFS y TLS en el propio kernel, para mas detalles podemos ver las notas de lanzamiento en este enlace: https://www.freebsd.org/releases/13.0R/relnotes/

La migración se llevará a cabo de distinto modo según se trate de un sistema físico o una jail virtualizada, además hay variaciones dependiendo del sistema de boot que se emplee. Por otro lado también explicaremos algunos aspectos a tener en cuenta si utilizamos FUSE, ZFS o Poudriere.


Sistema operativo

Actualizamos el kernel y las core tools a la última versión dentro de la 12.2:

freebsd-update fetch
freebsd-update install

Hacemos lo mismo con los paquetes binarios:

pkg upgrade
pkg autoremove

Comprobamos la versión actual

freebsd-version

12.2-RELEASE-p6

Creamos un BE(boot environment) nuevo:

bectl create 13
bectl list

BE      Active Mountpoint Space Created
13      -      -          8K    2021-05-15 18:03
default NR     /          41.7G 2020-11-27 23:58

Montamos el BE:

bectl mount 13 /var/tmp/BE-13

Successfully mounted 13 at /var/tmp/BE-13

Chrooteamos a este directorio:

chroot /var/tmp/BE-13
mount -t devfs devfs /dev
rm -rf /var/db/freebsd-update
mkdir /var/db/freebsd-update

Upgradeamos a 13.0:

freebsd-update upgrade -r 13.0

Instalamos kernel y módulos:

freebsd-update install

Instalamos userspace/binaries/libraries

freebsd-update install

El asistente nos informa de que debemos reinstalar todos los paquetes instalados:

Completing this upgrade requires removing old shared object files.
Please rebuild all installed 3rd party software (e.g., programs
installed from the ports tree) and then run "/usr/sbin/freebsd-update install"
again to finish installing updates.

Reinstalamos según utilicemos paquetes binarios o ports:

pkg upgrade
portmaster -af

Detectará el cambio de ABI y reinstalará todos los paquetes instalados.

Eliminamos librerias y ficheros antiguos:

freebsd-update install

Salimos del chroot:

exit

Desmontamos el BE:

umount /var/tmp/BE-13/dev

Activamos el BE para que sea cargado en el próximo arranque:

bectl activate 13


Otro aspecto importante del SO es el loader, para pasar a la versión 13.0 también debemos actualizarlo.

Loader update: EFI

Localizamos la partición EFI:

gpart show -p nvd0 | grep efi

          40      409600  nvd0p1  efi  (200M)

Montamos la partición y mostramos su contenido:

mount_msdosfs /dev/nvd0p1 /mnt
find /mnt

/mnt
/mnt/efi
/mnt/efi/boot
/mnt/efi/boot/BOOTx64.efi
/mnt/efi/boot/startup.nsh
/mnt/System Volume Information

Actualizamos el loader:

cp /var/tmp/BE-13/boot/loader.efi /mnt/efi/boot/bootx64.efi

Desmontamos la partición EFI:

umount /mnt

En el siguiente enlace podemos ver el cambio en el modo de gestionar la partición EFI:
https://www.freebsd.org/releases/13.0R/relnotes/#boot

Prior releases had a complete ms-dos formatted filesystem packaged into boot1.efifat. Older versions of FreeBSD installed this filesystem image into a raw partition. However, uses of the ESP have proliferated, making this inflexible approach no longer desirable.
Users have varied needs for the size of this partition, and multiple booting setups require more detailed access.
To update old ESP partitions, users should stop using the gpart(8) utility. Instead, ESP partitions should be mounted as MS-DOS filesystems as /boot/efi, and /boot/loader.efi should be copied to /boot/efi/efi/boot/bootx64.efi if the default setup is use.
If the efibootmgr(8) utility is used to customize the boot environment, this file should be copied to the location set with the -l flag.

Antes se volcaba directamente una imagen de la partición EFI a una partición:

gpart bootcode -p /boot/boot1.efifat -i 1 vtbd1

Ahora ya no, ahora se monta la partición EFI y se copia el fichero:

loader.efi

Loader update: BIOS

Si arrancamos mediante BIOS debemos localizar la partición de boot:

gpart show -p ada0 | grep freebsd-boot

         40       1024  ada0p1  freebsd-boot  (512K)

Volcamos el contenido del fichero /boot/pmbr a la MBR(primeros 512bytes) del disco y el contenido del fichero /boot/gptzfsboot sobre la partición de boot:

gpart bootcode -b /var/tmp/BE-13/boot/pmbr -p /var/tmp/BE-13/boot/gptzfsboot -i 1 ada0

partcode written to ada0p1
bootcode written to ada0

Reiniciamos:

shutdown -r now

Si algo sale mal siempre podemos arrancar el otro BE.

Si por otro lado nos quedamos sin bootloader, podemos restaurarlo arrancando una ISO de FreeBSD13 y copiando loader.efi a la partición EFI o reescribiendo la MBR y la partición boot en caso de utilizar modo BIOS.

En modo EFI veremos el nuevo loader:

En BIOS continuaremos con el antiguo:

Comprobamos la versión:

freebsd-version

13.0-RELEASE

Cuando estemos seguros de que la nueva versión funciona sin problemas podemos a renombrar el BE:

bectl destroy default
bectl rename 13 default


ZFS update

Cuando se actualiza el código ZFS debemos updatear los pools del sistema para habilitar las nuevas funcionalidades:

zpool status

  pool: zroot
 state: ONLINE
status: Some supported features are not enabled on the pool. The pool can
	still be used, but some features are unavailable.
action: Enable all features using 'zpool upgrade'. Once this is done,
	the pool may no longer be accessible by software that does not support
	the features. See zpool-features(5) for details.
config:

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

errors: No known data errors

Actualizamos el pool:

zpool upgrade zroot

zpool status
  pool: zroot
 state: ONLINE
config:

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

errors: No known data errors

FUSE update

El nombre del módulo del kernel de FUSE ha sido renombrado así que actualizamos la lista de módulos:

vi /etc/rc.conf
kld_list="nvidia-modeset fusefs vmm if_tap if_bridge nmdm linux linux64 linprocfs linsysfs fdescfs"

IOCAGE update

Primero actualizamos el padre a 13.0 siguiendo los pasos anteriores de este mismo artículo.

El siguiente paso es actualizar tanto el SO como los paquetes a su última versión en cada una de las jails.

JAILNAME=….
iocage update $JAILNAME
iocage console $JAILNAME
pkg upgrade
pkg autoremove

Ahora ya podemos actualizarlas a 13.0, Bajamos la RELEASE desde Iocage:

iocage fetch

[0] 11.2-RELEASE
[1] 11.3-RELEASE
[2] 11.4-RELEASE
[3] 12.0-RELEASE
[4] 12.1-RELEASE
[5] 12.2-RELEASE
[6] 13.0-RELEASE

Type the number of the desired RELEASE
Press [Enter] to fetch the default selection: (13.0)
Type EXIT to quit:  
Fetching: 13.0-RELEASE

Actualizamos cada una de las jails:

JAILNAME=….

iocage upgrade $JAILNAME -r 13.0-RELEASE
iocage update $JAILNAME
iocage console $JAILNAME

Si vemos el siguiente mensaje de error, debemos cambiar la shell a la por defecto antes de acceder a la jail:

ld-elf.so.1: Shared object “libncursesw.so.8” not found, required by “bash”

iocage exec $JAILNAME “chsh -s /bin/sh”

Dentro de la jail
Según utilicemos paquetes binarios o ports ejecutaremos:

pkg-static upgrade -f
portmaster -af

Cuando termine, salimos de la jail

exit

Revertimos el cambio de shell:

iocage exec $JAILNAME “chsh -s /usr/local/bin/bash”

Terminamos la actualización:

iocage update $JAILNAME

NOTA: Las actualizaciones mediante Iocage realizan de forma automática un snapshot en cada actualización de este modo si algo saliese mal se podría revertir sin problemas.

Pero debemos tener en cuenta que los snapshots ocupan espacio en disco:

zpool list

NAME      SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP    HEALTH  ALTROOT
storage   928G   822G   106G        -         -    34%    88%  1.00x    ONLINE  -
zroot     109G   104G  5.38G        -         -    87%    95%  1.00x    ONLINE  -
iocage df
+----------------+-------+------+------+-------+-------+
|      NAME      |  CRT  | RES  | QTA  |  USE  |  AVA  |
+================+=======+======+======+=======+=======+
| Andromeda      | 1.56x | none | none | 3.48G | 13.5G |
+----------------+-------+------+------+-------+-------+
| DrWho          | 1.74x | none | none | 7.33G | 13.5G |
+----------------+-------+------+------+-------+-------+
| HAProxy        | 1.59x | none | none | 4.71G | 13.5G |
+----------------+-------+------+------+-------+-------+
| Infinity       | 1.56x | none | none | 4.09G | 13.5G |
+----------------+-------+------+------+-------+-------+
| Lomax          | 1.42x | none | none | 5.82G | 13.5G |
+----------------+-------+------+------+-------+-------+
| Mistery        | 1.50x | none | none | 12.4G | 13.5G |
+----------------+-------+------+------+-------+-------+
| Potras         | 1.61x | none | none | 6.33G | 13.5G |
+----------------+-------+------+------+-------+-------+
| basic_template | 1.64x | none | none | 4.46G | 13.5G |
+----------------+-------+------+------+-------+-------+
| redis00        | 1.55x | none | none | 3.37G | 13.5G |
+----------------+-------+------+------+-------+-------+
| redis01        | 1.58x | none | none | 3.39G | 13.5G |
+----------------+-------+------+------+-------+-------+
| redis02        | 1.58x | none | none | 3.39G | 13.5G |
+----------------+-------+------+------+-------+-------+
| rxWod          | 1.75x | none | none | 10.1G | 13.5G |
+----------------+-------+------+------+-------+-------+

Cuando tengamos claro que la jail funciona sin problemas podremos limpiar los snapshots:

JAIL=….

for SNAPTOREMOVE in $(iocage snaplist $JAIL|grep -v root|grep -v ‘+'|grep -v ‘NAME’|awk ‘{print$2}'); do
iocage snapremove -n $SNAPTOREMOVE $JAIL
done


Iocage - Template

Para actualizar templates primero debemos convertilos a jail, actualizarlos y volvemos a convertirlos a template:

iocage list -t

+-----+----------------+-------+--------------+--------------+
| JID |      NAME      | STATE |   RELEASE    |     IP4      |
+=====+================+=======+==============+==============+
| -   | basic_template | down  | 12.2-RELEASE | 192.168.69.9 |
+-----+----------------+-------+--------------+--------------+
iocage set template=no $JAIL
iocage start $JAIL

Actualizar como si de una jail regular se tratase

iocage stop $JAIL

Borramos los snapshots del template:

JAIL=….

for SNAPTOREMOVE in $(iocage snaplist $JAIL|grep -v root|grep -v ‘+'|grep -v ‘NAME’|awk ‘{print$2}'); do
iocage snapremove -n $SNAPTOREMOVE $JAIL
done

Volvemos a convertirla a template:

iocage set template=yes $JAIL

iocage list -t

+-----+----------------+-------+--------------+--------------+
| JID |      NAME      | STATE |   RELEASE    |     IP4      |
+=====+================+=======+==============+==============+
| -   | basic_template | down  | 13.0-RELEASE | 192.168.69.9 |
+-----+----------------+-------+--------------+--------------+

Poudriere

Nos bajamos la nueva versíon de RELEASE:

poudriere jail -c -j freebsd_13-0x64 -v 13.0-RELEASE

poudriere jail -l
JAILNAME        VERSION         ARCH  METHOD TIMESTAMP           PATH
freebsd_12-2x64 12.2-RELEASE-p6 amd64 ftp    2021-05-10 23:36:10 /usr/local/poudriere/jails/freebsd_12-2x64
freebsd_13-0x64 13.0-RELEASE    amd64 ftp    2021-05-17 15:19:03 /usr/local/poudriere/jails/freebsd_13-0x64

Migramos las opciones genéricas de compilación:

cp /usr/local/etc/poudriere.d/freebsd_12-2x64-make.conf /usr/local/etc/poudriere.d/freebsd_13-0x64-make.conf

Las opciones por paquete:

cp -r /usr/local/etc/poudriere.d/freebsd_12-2x64-HEAD-options /usr/local/etc/poudriere.d/freebsd_13-0x64-HEAD-options

La config de las opciones de compilación:

poudriere options -c -j freebsd_13-0x64 -p HEAD -f /usr/local/etc/poudriere.d/port-list

Actualizamos la jail y ports:

poudriere jail -u -j freebsd_13-0x64
poudriere ports -u -p HEAD

Compilamos los ports:

poudriere bulk -j freebsd_13-0x64 -p HEAD -f /usr/local/etc/poudriere.d/port-list

La parte del cliente quedaría del siguiente modo:

vi /usr/local/etc/pkg/repos/poudriere.conf

poudriere: {
    url: "http://poudriere.alfaexploit.com/packages/freebsd_13-0x64-HEAD/",
    mirror_type: "http",
    signature_type: "pubkey",
    pubkey: "/usr/local/etc/ssl/certs/poudriere.cert",
    enabled: yes,
}

Comprobamos que el contenido del repositorio esté accesible:

<html>
<head><title>Index of /packages/</title></head>
<body>
<h1>Index of /packages/</h1><hr><pre><a href="../">../</a>
<a href="freebsd_12-2x64-HEAD/">freebsd_12-2x64-HEAD/</a>                              10-May-2021 21:37                   -
<a href="freebsd_13-0x64-HEAD/">freebsd_13-0x64-HEAD/</a>                              17-May-2021 17:54                   -
</pre><hr></body>
</html>

Recompilamos todos los paquetes:

pkg-static upgrade -f

Si en el servidor de compilación utilizamos un script automático como el indicado aquí , debemos modificarlo también:

vi .scripts/updatePoudriere.sh

#!/usr/local/bin/bash
poudriere jail -u -j freebsd_13-0x64
poudriere ports -u -p HEAD
poudriere options -j freebsd_13-0x64 -p HEAD -f /usr/local/etc/poudriere.d/port-list
poudriere bulk -j freebsd_13-0x64 -p HEAD -f /usr/local/etc/poudriere.d/port-list

Poudriere - limpieza

Eliminamos la jail:

poudriere jail -d -j freebsd_12-2x64

Eliminamos el código fuente de los paquetes:

poudriere distclean -a -p HEAD

Eliminamos los logs:

poudriere logclean -a -j freebsd_12-2x64 -p HEAD

Eliminamos los paquetes compilados:

poudriere pkgclean -A -j freebsd_12-2x64 -p HEAD

Eliminamos algunos directorios residuales:

rm -rf /usr/local/poudriere/data/packages/freebsd_12-2x64-HEAD/
rm -rf /usr/local/etc/poudriere.d/freebsd_12-2x64-HEAD-options
rm /usr/local/etc/poudriere.d/freebsd_12-2x64-make.conf

Eliminamos la versión antigua del fichero data.json:

vi /usr/local/poudriere/data/logs/bulk/.data.json

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