ZFS

Esta entrada es sobre el sistema de ficheros ZFS, el mismo fue desarrollado por Sun (ahora Oracle) y tiene como fuerte preservar al integridad de la data. A pesar de ser código abierto, por incompatibilidad de licencias no puede ser incluido en el Kernel de Linux, pero sí su implementación usando fuse.

En mi caso necesito un sistema de archivos para mi información familiar, fotos, vídeos, música, etc. Mayormente los formatos que tengo ya tienen compresión por ellos mismos, por lo cual un sistema de archivos con compresión no me serviría de mucho, de hecho sería contraproducente ya que consumiría ciclos de CPU casi que por el gusto.

Para esta prueba vamos a usar un archivo común como disco, zfs permite usar discos, particiones o archivos. Primero creamos un archivo de 512MB:

# dd if=/dev/zero of=rawdisk.1 bs=4096 count=131072

Luego pasamos a crear nuestro pool o contenedor de volúmenes, en este caso no vamos a crear ningún volumen extra en él, lo usaremos tal cual:

# zpool create testpool /home/paco/zfs-test/rawdisk.1

Además de crear el sistema de archivos también lo monta en /testpool y lo deja listo para usar. La información del pool se almacena en /var/lib/zfs/.

Podemos ver el estado con:

# zpool status
 pool: testpool
 state: ONLINE
 scrub: none requested
config:

    NAME                             STATE     READ WRITE CKSUM
    testpool                         ONLINE       0     0     0
      /home/paco/zfs-test/rawdisk.1  ONLINE       0     0     0

errors: No known data errors

De momento todo bien, vamos a copiar unos archivos de imágenes en formato JPEG a /testpool/ para intentar simular corrupción de la data, una vez copiado los archivos pasaremos a desmontar la unidad:

# zfs unmount /testpool

Ahora modificamos algunos bytes de nuestro disco duro (rawdisk.1), las imágenes que copié tienen de encabezado las letras «JFIF», buscaremos esto en nuestra data y lo modificaremos un poco:

# hexdump -C rawdisk.1 | less 

0040ac00  ff d8 ff e0 00 10 4a 46  49 46 00 01 02 01 00 48  |......JFIF.....H|
0040ac10  00 48 00 00 ff e1 1d 7a  45 78 69 66 00 00 49 49  |.H.....zExif..II|
0040ac20  2a 00 08 00 00 00 0f 00  0f 01 02 00 09 00 00 00  |*...............|
0040ac30  c2 00 00 00 10 01 02 00  10 00 00 00 cb 00 00 00  |................|
0040ac40  12 01 03 00 01 00 00 00  01 00 00 00 1a 01 05 00  |................|

De «JFIF» vamos a cambiar «IF» por algo aleatorio, para ello usamos lo siguiente:

# echo $(((0x0040ac00)+8))
 4238344
# dd if=/dev/random of=rawdisk.1 seek=4238344  bs=1 count=2 conv=notrunc

La primera columna de la salida de hexdump muestra la posición (en hexadecimal) de la data, en nuestro caso 0x0040ac00 corresponde al byte «ff», de allí empezamos a contar, 1 es «d8», 2 es «ff», 3 es «e0» y así hasta llegar a «IF», que es 49 y 46 respectivamente (se puede comprobar con una tabla ascii, man ascii), la cuenta nos da 8, por lo cual convertimos a decimal y sumamos 8, luego ese valor es la posición (en bytes) desde la cual iniciaremos el daño.

Repetimos el proceso con otros JFIF y volvemos a cargar el sistema de archivos:

# zfs mount testpool

Verificamos su integridad (esto se ejecuta periódicamente, pero se puede hacer manual para adelantar el proceso):

# zpool scrub testpool

Y ahora:

# zpool status testpool   
  pool: testpool
 state: ONLINE
status: One or more devices has experienced an error resulting in data
    corruption.  Applications may be affected.
action: Restore the file in question if possible.  Otherwise restore the
    entire pool from backup.
   see: http://www.sun.com/msg/ZFS-8000-8A
 scrub: scrub completed after 0h0m with 2 errors on Fri Dec 14 23:59:27 2012
config:

    NAME                             STATE     READ WRITE CKSUM
    testpool                         ONLINE       0     0     2
      /home/paco/zfs-test/rawdisk.1  ONLINE       0     0     4

errors: 2 data errors, use '-v' for a list

¡Tenemos 2 errores!, hacemos caso y agregamos ‘-v’:

# zpool status -v testpool
  pool: testpool
 state: ONLINE
status: One or more devices has experienced an error resulting in data
    corruption.  Applications may be affected.
action: Restore the file in question if possible.  Otherwise restore the
    entire pool from backup.
   see: http://www.sun.com/msg/ZFS-8000-8A
 scrub: scrub completed after 0h0m with 2 errors on Fri Dec 14 23:59:27 2012
config:

    NAME                             STATE     READ WRITE CKSUM
    testpool                         ONLINE       0     0     2
      /home/paco/zfs-test/rawdisk.1  ONLINE       0     0     4

errors: Permanent errors have been detected in the following files:

        /testpool/1920-1200-11295.jpg
        /testpool/1920-1200-217.jpg

No solo se detectó el error, sino que también nos dice los archivos afectados. Los mismos no pueden ser recuperados y nos pide restaurar la copia de respaldo que no tenemos. Si hubiésemos creado dos discos y creado el pool como mirror, zfs los hubiera podido recuperar por nosotros.

La ventaja de tener este tipo de detección es que nos permite tomar acciones antes de que los errores destruyan más nuestra información.

Referencias:

  1. ZFS en la wikipedia
  2. Implementación de ZFS en Linux usando fuse
  3. Guía de administración de ZFS (Solaris, en inglés)

Acerca de Paco

Manuel Argüelles, Panameño, programador, vegetariano, pervertido y buena gente.
Esta entrada fue publicada en Uncategorized. Guarda el enlace permanente.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *