Máquina del tiempo con btrfs y snapper

Llevaba bastante tiempo buscando un método "más rápido" de poder realizar mis copias de seguridad. Aunque sigo usando el método que mencionaba en artículos anteriores de hacer tars con pigz, para las copias incrementales del día a día era matar moscas a cañonazos.

Así que nada, un día me compré un disco externo adicional y decidí poner en funcionamiento 3 cosas que tenía por probar:

  • Cifrado completo de disco/partición con LUKS.
  • El filesystem btrfs
  • Los checks de integridad de btrfs (scrub)
  • La compresión y los snapshots de btrfs

Estos son los resultados:

Después de particionar el disco, inicializarlo con LUKS y crear el filesystem btrfs, podemos ver la estructura con lsblk:

$ lsblk 
NAME                                          MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT
[...]
sdb                                             8:16   0   1.8T  0 disk  
├─sdb1                                          8:17   0     1T  0 part  /run/media/fran/wd20ntfs
└─sdb2                                          8:18   0 837.6G  0 part  
  └─luks-0aad2fa7-f2c9-4acb-81f5-xxxxxxxxxxxx 253:5    0 837.6G  0 crypt /run/media/fran/wd20brtfs

Con btrfs obtenemos algo más de información sobre el filesytem:

$ sudo btrfs subvolume list -puta /run/media/fran/wd20btrfs/ 
ID      gen     parent  top level       uuid    path
--      ---     ------  ---------       ----    ----
257     944     5       5               75a8331b-9cd3-0d46-b773-9aaba88b6369    root
514     950     5       5               c767358c-83e0-134f-9698-2ae535742284    backup
556     951     514     514             54f942af-31e7-6e4c-ae4a-691d4642ddfd    <FS_TREE>/backup/.snapshots
558     828     556     556             add72c57-3f1b-a143-8902-cc0242e971bf    <FS_TREE>/backup/.snapshots/2/snapshot
559     841     556     556             9e6e71aa-8ddc-ee44-a0cc-628ab659c544    <FS_TREE>/backup/.snapshots/3/snapshot
560     848     556     556             fc44d63a-393d-294e-b868-6d12c9e5515f    <FS_TREE>/backup/.snapshots/4/snapshot

snapper es una herramienta desarrollada por SUSE que permite automatizar la creación de snapshots btrfs. Originalmente estaba pensada para dar la característica de rollback en caso de querer dar marcha atrás una actualización del sistema, pero es suficientemente potente para poder encargarse también de otros discos de datos.

$ sudo btrfs subvolume show /run/media/fran/wd20btrfs/                                                   
/run/media/fran/wd20btrfs is btrfs root

$ sudo btrfs subvolume show /run/media/fran/wd20btrfs/backup/
/run/media/fran/wd20btrfs/backup
    Name:                   backup
    uuid:                   c767358c-83e0-134f-9698-2ae535742284
    Parent uuid:            -
    Creation time:          2015-01-20 22:03:20
    Object ID:              514
    Generation (Gen):       950
    Gen at creation:        202
    Parent:                 5
    Top Level:              5
    Flags:                  -
    Snapshot(s):
                            .snapshots/2/snapshot
                            .snapshots/3/snapshot
                            .snapshots/4/snapshot
                            .snapshots/5/snapshot

$ btrfs filesystem df /run/media/fran/wd20btrfs
Data, single: total=119.01GiB, used=118.45GiB
System, DUP: total=8.00MiB, used=32.00KiB
System, single: total=4.00MiB, used=0.00B
Metadata, DUP: total=2.50GiB, used=1.70GiB
Metadata, single: total=8.00MiB, used=0.00B
GlobalReserve, single: total=512.00MiB, used=0.00B

$ sudo btrfs scrub status -d /run/media/fran/wd20btrfs/
scrub status for 7bb1d318-c7a9-40d8-995a-972a9d43544f
scrub device /dev/mapper/luks-0aad2fa7-f2c9-4acb-81f5-5197751fee3e (id 1) status
scrub started at Fri Apr 17 21:48:08 2015, running for 25 seconds
total bytes scrubbed: 847.03MiB with 0 errors

$ sudo btrfs scrub status -d /run/media/fran/wd20btrfs/
scrub status for 7bb1d318-c7a9-40d8-995a-972a9d43544f
scrub device /dev/mapper/luks-0aad2fa7-f2c9-4acb-81f5-5197751fee3e (id 1) history
scrub started at Fri Apr 17 21:48:08 2015 and finished after 3460 seconds
total bytes scrubbed: 121.84GiB with 0 errors

$ sudo btrfs prop list /run/media/fran/wdbuttercrypt/                                                        
ro                  Set/get read-only flag of subvolume.
label               Set/get label of device.
compression         Set/get compression for a file or directory

$ sudo btrfs prop get /run/media/fran/wdbuttercrypt/                                                         
ro=false
label=wdbuttercrypt

$ sudo btrfs prop get /run/media/fran/wdbuttercrypt/backupdedup/                                             
ro=false
compression=zlib

La configuración de snapper es, en principio, bastante sencilla.

#> snapper create-config  -f btrfs -t root /run/media/fran/wd15btrfs
#> snapper list-configs
Config | Subvolume                
-------+--------------------------
root   | /run/media/fran/wd15btrfs

jnuc /etc/snapper/configs #> snapper list
Type   | # | Pre # | Date | User | Cleanup | Description | Userdata
-------+---+-------+------+------+---------+-------------+---------
single | 0 |       |      | root |         | current     |

jnuc /etc/snapper/configs #> snapper create

jnuc /etc/snapper/configs #> snapper list
Type   | # | Pre # | Date                     | User | Cleanup | Description | Userdata
-------+---+-------+--------------------------+------+---------+-------------+---------
single | 0 |       |                          | root |         | current     |         
single | 1 |       | Wed Sep 23 13:37:16 2015 | root |         |             |

# btrfs subvol list -puta /run/media/fran/wd15btrfs
ID      gen     parent  top level       uuid    path
--      ---     ------  ---------       ----    ----
257     135     5       5               afb541bd-5459-e245-84af-eca6c17c1eaf    backupdedup
379     124     5       5               49b14378-0390-cf48-a81e-08a84b8b88a5    .snapshots
380     123     379     379             b1650ae6-4baf-e744-8b3a-26f4d5dd6fb9    <FS_TREE>/.snapshots/1/snapshot

Con esto vemos como crear nuestro primer filesystem que será controlado por snapper. Ahora solo es cuestión de invocar snapper create cada vez que vayamos a hacer cambios significativos en el filesystem, o queramos tener un punto de restauración en ese momento.

Snapper tambien nos permite hacer cosas muy interesantes, como por ejemplo controlar las diferencias que hay entre dos snapshots creados anteriormente:

snapper status 0..1

Happy hacking :)