Este artículo explica cómo compilar el soporte para el sistema de archivos ZFS en el kernel Linux en un sistema Debian/Devuan.



Anteriormente expliqué detalladamente todas las ventajas y características de ZFS en el artículo Introducción a ZFS en FreeBSD, el cual recomiendo ampliamente su lectura. ZFS es un sistema de archivos que se originó en los sistemas operativos Sun Solaris y fue portado a FreeBSD desde la versión 7. Actualmente es desarrollado y mantenido por el proyecto OpenZFS. A pesar de que ZFS soporta los sistemas operativos basados en Linux, es difícil proveer un soporte nativo para ZFS por incompatibilidades legales entre la licencia CDDL del código de ZFS y la licencia GPL que utiliza el kernel Linux. Sin embargo, es posible compilar ZFS como módulo del kernel, más allá de que (según la FSF) se prohíbe redistribuir el producto resultante como trabajo derivativo, por contener porciones de código licenciadas bajo la CDDL.

El proyecto ZFS on Linux se encarga de mantener y proveer soporte nativo para ZFS en Linux.

Compilar ZFS en Linux

Para comenzar, instalar las dependencias necesarias para compilar ZFS:

# apt-get install build-essential autoconf automake libtool gawk alien fakeroot ksh
# apt-get install zlib1g-dev uuid-dev libattr1-dev libblkid-dev libselinux-dev libudev-dev
# apt-get install libacl1-dev libaio-dev libdevmapper-dev libssl-dev libelf-dev
# apt-get install linux-headers-$(uname -r)

Desde el sitio del proyecto zfsonlinux en GitHUb, descargar la última versión estable:

Releases - zfsonlinux/zfs

Por ejemplo, descargar ZFS versión 0.8.2:

# wget https://github.com/zfsonlinux/zfs/releases/download/zfs-0.8.2/zfs-0.8.2.tar.gz
# wget https://github.com/zfsonlinux/zfs/releases/download/zfs-0.8.2/zfs-0.8.2.sha256.asc

Verificar la integridad del paquete:

root@debian:/usr/local/src# grep 'tar.gz' zfs-0.8.2.sha256.asc | sha256sum -c -
zfs-0.8.2.tar.gz: OK

Extraer el paquete:

# tar axf zfs-0.8.2.tar.gz
# cd zfs-0.8.2
# chown -R root:root ./
# chmod -R o-rwx ./

Configurar el paquete según las opciones,configuración y preferencias de cada sistema. En este ejemplo se compila sin systemd:

# ./configure \
    --disable-systemd \
    --enable-sysvinit \
    --disable-debug \
    --with-spec=generic \
    --with-linux=$(ls -1dtr /usr/src/linux-headers-*.*.*-common | tail -n 1) \
    --with-linux-obj=$(ls -1dtr /usr/src/linux-headers-*.*.*-amd64 | tail -n 1)

Compilar e instalar ZFS:

# make -j1 && make install

Luego instalar los scripts de inicio del servicio:

# cd /etc/init.d/
# ln -s /usr/local/etc/init.d/zfs-import /etc/init.d/
# ln -s /usr/local/etc/init.d/zfs-mount /etc/init.d/
# ln -s /usr/local/etc/init.d/zfs-share /etc/init.d/
# ln -s /usr/local/etc/init.d/zfs-zed /etc/init.d/

El paquete se instala por defecto en /usr/local. En este punto, se puede producir una condición de carrera. Si el sistema de archivos donde se aloja /usr/local está alojado en un volumen lógico LVM, este no estará disponible al momento de importar los sistemas de archivos ZFS. Esto se debe a que los scripts de inicio provistos por ZFS intentan levantar ZFS en runlevel 1 (single user), lo antes posible, sin embargo LVM inicia recién en runlevel >2 (al menos en Debian y derivados). Por ende, es necesario cambiar la configuración de init del script zfs-import para que inicie después de LVM. De esta forma los binarios de ZFS (instalados en un directorio dentro de /usr/local provisto por un volúmen lógico LVM) estarán disponibles al momento de ser ejecutado.

Configurar el servicio zfs-import para que inicie en runlevel 2:

### BEGIN INIT INFO
# Provides:          zfs-import
# Required-Start:    mtab lvm2
# Required-Stop:     $local_fs mtab
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# X-Start-Before:    zfs-mount
# X-Stop-After:      zfs-mount
# Short-Description: Import ZFS pools
# Description: Run the `zpool import` command.
### END INIT INFO

Se alteran tanto los niveles de incio (Default-Start), como los niveles de detención (Default-Stop) y dependencias (Required-Start).

Finalmente, habilitar los servicios de ZFS:

# update-rc.d zfs-import defaults
# update-rc.d zfs-mount defaults
# update-rc.d zfs-share defaults
# update-rc.d zfs-zed defaults

Reiniciar el sistema:

# reboot

Al iniciar el sistema, verificar que los módulos de ZFS hayan sido cargados exitosamente:

root@debian:~# lsmod | grep zfs
zfs                  3923968  8
zunicode              331776  1 zfs
zlua                  139264  1 zfs
zcommon                86016  1 zfs
znvpair                94208  2 zcommon,zfs
zavl                   16384  1 zfs
icp                   278528  1 zfs
spl                   106496  5 znvpair,zcommon,zfs,icp,zavl

En este punto ya es posible crear nuestro primer pool utilizando cualquier dispositivo disponible.

Crear un pool

Un pool de almacenamiento ZFS es una colección lógica de dispositivos que proveen espacio para los datasets. Por ejemplo, crear el pool ZFS "z01" empleando todo el disco sdb:

# zpool create z01 /dev/sdb

Crear un dataset

Un dataset es un sistema de archivos dentro de un pool ZFS. Se comporta como un sistema de archivos independiente, aunque comparte el espacio en disco disponible entre todos los sistemas de archivos del pool. El siguiente artículo demuestra los pasos necesarios: Crear y configurar un dataset ZFS en Linux

Para entender el funcionamiento de pools y datasets recomiendo leer el artículo Introducción a ZFS en FreeBSD.

Referencias