Backup doméstico seguro con Linux, cifrado y ZFS (VII): Volvemos a la tarjeta microSD original

Tras todo este proceso y algo de limpieza, nos preparamos para mover el servicio de vuelta a la tarjeta microSD de 4 GB. No quiero desperdiciar una microSD rápida e innecesariamente grande para mis necesidades.

Advertencia

Este documento supone que no estamos usando LVM en el disco duro de nuestro portátil. Es mi caso, ya que uso ZFS.

Si no es así, hay que tener mucho cuidado con comandos como vgchange. Revisa los parámetros permitidos en el manual para indicar sobre qué grupos de volúmenes LVM actuar.

2   Comprobamos que los datos nos caben en la tarjeta microSD de 4 GB

Lo primero es verificar que los datos nos caben en la tarjeta microSD de 4 GB original:

# df -k /
Filesystem           1K-blocks    Used Available Use% Mounted on
/dev/mapper/csi-root  14535424 2799888  11117596  21% /

Vemos que el servicio ocupa 2.8 GB, que cabe perfectamente en la tarjeta microSD original de 4 GB.

3   Analizamos y copiamos la tarjeta microSD de 16 GB

  1. Apagamos el servidor ProLiant y extraemos la tarjeta microSD de 16 GB. La enchufamos al portátil.

  2. Examinamos el particionado de esa tarjeta microSD:

    # fdisk /dev/sdb
    
    Welcome to fdisk (util-linux 2.27.1).
    Changes will remain in memory only, until you decide to write them.
    Be careful before using the write command.
    
    
    Command (m for help): p
    Disk /dev/loop0: 14.9 GiB, 15931539456 bytes, 31116288 sectors
    Units: sectors of 1 * 512 = 512 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disklabel type: dos
    Disk identifier: 0x000c0c07
    
    Device       Boot  Start      End  Sectors  Size Id Type
    /dev/sdb1 *      2048   499711   497664  243M 83 Linux
    /dev/sdb2      501758 31116287 30614530 14.6G  5 Extended
    /dev/sdb5      501760 31116287 30614528 14.6G 83 Linux
    
    Command (m for help):
    

    Tomamos nota del sector de inicio de cada partición.

  3. Como vamos a hacer procesos muy delicados, el primer paso será hacer una copia de la tarjeta microSD en mi disco duro. Trabajaremos sobre esa copia, dejando la microSD inalterada.

    # ddrescue /dev/sdb /tmp/Proliant-SD-20181227-Ubuntu_18_04.dump
    GNU ddrescue 1.19
    Press Ctrl-C to interrupt
    rescued:    15931 MB,  errsize:       0 B,  current rate:   16318 kB/s
       ipos:    15931 MB,   errors:       0,    average rate:   22502 kB/s
       opos:    15931 MB, run time:   11.80 m,  successful read:       0 s ago
    Finished
    

    Nota

    El comando ddrescue es conveniente, pero, si no disponemos de él, podemos usar el venerable comando dd.

4   Abrimos LUKS y cambiamos las identificaciones LVM

  1. Configuramos el sistema para que tome ese fichero y lo considere como un dispositivo de bloques. Es decir, como un disco duro o una tarjeta de memoria microSD. Para ello usamos dispositivos loop:

    # losetup /dev/loop0 --offset 1024K /tmp/Proliant-SD-20181227-Ubuntu_18_04.dump
    # losetup /dev/loop1 --offset 250880K /tmp/Proliant-SD-20181227-Ubuntu_18_04.dump
    

    Aquí creamos dos dispositivos virtuales, uno contiene el sistema de ficheros de arranque y otro, la partición LUKS.

    Los offsets indicados se corresponden con el principio de cada partición, teniendo en cuenta que cada sector ocupa 512 bytes.

  2. Montamos el sistema de ficheros de arranque y lo usamos para, tomando la clave de acceso almacenada en él, abrir la partición LUKS virtual:

    # mkdir -p /mnt/16G/boot /mnt/16G/root
    # mount /dev/loop0 /mnt/16G/boot
    # ls -la /mnt/16G/boot/z-keyfile
    -r-------- 1 root root 3904 Jul 25  2016 /mnt/16G/boot/z-keyfile
    # cryptsetup luksOpen /dev/loop1 --key-file /mnt/16G/boot/z-keyfile tarjeta16G
    
  3. Con la partición LUKS abierta, se la presentamos al sistema LVM:

    # vgscan
      Reading all physical volumes.  This may take a while...
      Found volume group "csi" using metadata type lvm2
    

    csi es nombre del volume group LVM que nos interesa. Todo ha ido bien.

  4. Vamos a conectar la tarjeta original microSD de 4 GB.

    Advertencia

    Esta tarjeta microSD contiene el mismo volumen lógico LVM, con los mismos UUID, etc. Esto es desastroso porque el kernel verá el mismo LVM por dos lugares diferentes, considerará que es un volumen multipath y enviará lecturas y escrituras por las dos rutas, corrompiendo ambas tarjetas.

    Este es un problema que ya me encontré en su día haciendo copias de seguridad sector a sector y cuya solución documenté en 2012 en el artículo LVM and cloning HDs.

    Los comandos a ejecutar son:

    # vgchange -a n
      0 logical volume(s) in volume group "csi" now active
    # pvchange --uuid /dev/tarjeta16G
      Physical volume "/dev/tarjeta16G" changed
      1 physical volume changed / 0 physical volumes not changed
    # vgchange -u csi
      Volume group "csi" successfully changed
    # vgscan
      Reading all physical volumes.  This may take a while...
      Found volume group "csi" using metadata type lvm2
    # vgchange -a y
      1 logical volume(s) in volume group "csi" now active
    # vgrename csi csi2
      Volume group "csi" successfully renamed to "csi2"
    

5   Conectamos la tarjeta microSD de 4 GB y montamos todos los datos

  1. Montamos los datos de la copia de la tarjeta microSD de 16 GB:

    # vgchange -a y
      1 logical volume(s) in volume group "csi2" now active
    # mount /dev/mapper/csi2-root /mnt/16G/root/
    
  2. Conectamos la tarjeta microSD de 4 GB al portátil.

  3. Montamos el sistema de ficheros de la tarjeta microSD de 4 GB y usamos el fichero de acceso para desbloquear su partición LUKS:

    # mkdir -p /mnt/4G/boot /mnt/4G/root
    # mount /dev/sdb1 /mnt/4G/boot
    # cryptsetup luksOpen /dev/sdb5 --key-file /mnt/4G/boot/z-keyfile tarjeta4G
    
  4. Ahora que tenemos el LUKS de la microSD abierto, se lo damos a conocer al LVM:

    # vgscan
      Reading all physical volumes.  This may take a while...
      Found volume group "csi" using metadata type lvm2
      Found volume group "csi2" using metadata type lvm2
    # vgchange -a y
      2 logical volume(s) in volume group "csi" now active
      1 logical volume(s) in volume group "csi2" now active
    
  5. Montamos los datos de la tarjeta microSD de 4 GB:

    # mount /dev/mapper/csi-root /mnt/4G/root/
    

6   Eliminamos el espacio de swap y lo añadimos al sistema de ficheros root

Aunque soy un gran amante del swap, como regla general no deberíamos hacer swap sobre una tarjeta microSD. Suelen ser lentas y el número de escrituras antes de que falle está limitado. Además, necesito esos 500 MB de espacio que reservé el 2014.

Esta máquina tiene poca RAM, 2 GB, pero no necesito más para el uso que le estoy dando ahora mismo.

Los pasos serían los siguientes:

  1. Destruyo el volumen lógico LVM asociado al swap:

    # lvremove /dev/csi/swap_1
    Do you really want to remove and DISCARD active logical volume swap_1? [y/n]: y
      Logical volume "swap_1" successfully removed
    
  2. Asigno el espacio liberado al sistema de ficheros root:

    # lvresize -r -l+100%FREE /dev/mapper/csi-root
      Size of logical volume csi/root changed from 2.96 GiB (758 extents) to 3.45 GiB (883 extents).
      Logical volume root successfully resized.
    resize2fs 1.42.13 (17-May-2015)
    Filesystem at /dev/mapper/csi-root is mounted on /mnt/4G/root; on-line resizing required
    old_desc_blocks = 1, new_desc_blocks = 1
    The filesystem on /dev/mapper/csi-root is now 904192 (4k) blocks long.
    

7   Usamos rsync para copiar los datos a la microSD de 4 GB

  1. Copiamos los datos del sistema de ficheros de arranque:

    # rsync --numeric-ids -a --inplace --delete --delete-excluded \
            --stats --progress -v --itemize-changes \
            /mnt/16G/boot/ /mnt/4G/boot/
    ...
    
  2. Copiamos los datos del sistema de ficheros root:

    # rsync --numeric-ids -a --inplace --delete --delete-excluded \
            --stats --progress -v --itemize-changes \
            --exclude /proc/\* \
            --exclude /sys/\* \
            --exclude /dev/\* \
            --exclude /run/\* \
            --exclude /tmp/\* \
            /mnt/16G/root/ /mnt/4G/root/
    ...
    

    Escapamos el asterisco (*) en los parámetros --exclude porque queremos que sean interpretados por rsync y no por el shell.

8   Desmontamos los sistemas de ficheros, cerramos los LVM y los LUKS

  1. Desmontamos todo, una vez que completamos la copia:

    # sync
    # umount /mnt/4G/boot
    # umount /mnt/16G/boot
    # umount /mnt/4G/root
    # umount /mnt/16G/root
    
  2. Cerramos los LVMs:

    # vgchange -a n csi csi2
      0 logical volume(s) in volume group "csi" now active
      0 logical volume(s) in volume group "csi2" now active
    
  3. Cerramos los LUKS:

    # cryptsetup luksClose tarjeta4G
    # cryptsetup luksClose tarjeta16G
    
  4. Eliminamos los dispositivos loop:

    # losetup -d /dev/loop0
    # losetup -d /dev/loop1
    

9   Copia de seguridad de la tarjeta microSD de 4 GB

Por si las moscas:

# ddrescue /dev/sdb /tmp/Proliant-SD-20181227-Ubuntu_18_04.dump

Subo este fichero a mi nube personal.

10   Instalación y comprobación en el servidor ProLiant

Extraemos la tarjeta microSD de nuestro portátil, la conectamos al servidor ProLiant, lo arrancamos y comprobamos que todo funciona correctamente.

La tarjeta microSD de 16 GB vuelve al cajón de disponible para usos futuros.