Backup doméstico seguro con Linux, cifrado y ZFS (IV): Traspaso del sistema operativo a una microSD de 4GB

Antes de continuar lee:

Una vez decidido que el mejor curso de acción consiste en aprovechar la instalación de sistema operativo que tenía montada en la máquina virtual VirtualBox funcionando en el Microsoft Windows 8 de mi padre, hay que ver cómo reducir un disco virtual de 52GB a los 4GB que me caben en la tarjeta microSD que voy a utilizar.

Echando un vistazo al disco duro virtual veo que hay tres particiones: una partición de arranque de 250MB, una partición de sistema de 48GB y una partición de swap de 4GB. La partición del sistema operativo está utilizando solo 1.7GB, así que si reducimos el swap (o lo eliminamos por completo) podemos acomodar todo lo que necesitamos en la tarjeta microSD de 4GB.

El primer paso será copiar el disco duro virtual del Microsoft Windows 8 de mi padre a mi portátil con Linux. Es un disco virtual de 52 gigabytes, pero el fichero mide solo 9GB. Va creciendo con el uso, pero ahora mismo me cabe perfectamente en un pendrive de 16GB que tengo a mano. Lo muevo a mi portátil.

Normalmente reconfiguraría las particiones de una imagen de disco directamente desde mi Linux, pero como se trata de un disco duro virtual VDI no lo puedo gestionar directamente. Lo que hago es lanzar VirtualBox en mi máquina con ese disco duro virtual y usando un LiveCD de Linux. Con esto tengo acceso a la imagen VDI como si fuera un disco duro normal.

ATENCIÓN: Como a partir de ahora hago las operaciones dentro de la máquina virtual con el LiveCD, transcribiré los comandos copiados a mano en papel. Puede haber algún error y no voy a mostrar las respuestas a los comandos que introduzco.

La partición de arranque es fácil. Las otras dos particiones están, en realidad, contenidas en un Logical Volume Management cifrado con LUKS, conteniendo dos volúmenes lógicos. Uno para el sistema operativo y el otro para el swap. Esto me complica la vida. Lo primero que tengo que hacer es abrir la partición LUKS. Su clave está en la propia partición de arranque:

$ mount /dev/sda1 /mnt  # Partición de arranque
$ cryptsetup luksOpen --key-file /mnt/z-keyfile /dev/sda5 X

Una vez que desciframos la partición importamos el LVM:

$ vgscan
$ vgchange -a y

Ahora nos aparecerá un LVM llamado csi. Ahí dentro hay dos volúmenes lógicos: sistema operativo y swap. El volumen de sistema operativo mide 48GB, pero solo tiene ocupados 1.7GB. Reducimos el tamaño del sistema de ficheros y, después, del volumen lógico en sí:

$ resize2fs /dev/csi/root 500000
$ lvresize -L2500M /dev/csi/root
$ resize2fs /dev/csi/root

Esto reduce el tamaño del sistema de ficheros a 2GB [1] (recordemos que está usando 1.7GB), luego reduce el tamaño del volumen lógico a 2.5GB y, finalmente, amplia el tamaño del sistema de ficheros para ocupar todo el volumen lógico [2].

Una vez hecho esto (cambiar el tamaño del sistema de ficheros puede ser una operación lenta porque mueve datos de un lado a otro [3]) enchufamos la tarjeta microSD a la máquina virtual. Queremos crear una tabla de particiones y un sistema de arranque. La imagen VDI actual ya contiene un sistema de arranque válido. Para no comernos el coco simplemente desmonto la partición de arranque y copio los primeros 300 megabytes del disco VDI a la tarjeta microSD:

$ umount /mnt    # Esto es la partición de arranque /dev/sda1
$ dd if=/dev/sda of=/dev/sdb bs=1048576 count=300

Ahora tenemos en la microSD un sistema de arranque y una partición de arranque de 250 megabytes. También hay un fragmento de una partición extendida. Debemos hacer lo siguiente empleando la herramienta fdisk:

  1. Eliminamos la partición lógica dentro de la partición extendida.
  2. Eliminamos la partición extendida. Esta partición no nos sirve porque dice ocupar 50GB cuando solo hemos copiado de ella unos 50MB y la microSD solo mide 4GB.
  3. Creamos una nueva partición extendida ocupando toda la tarjeta microSD. Más o menos 3.5GB.
  4. Dentro de esa partición extendida creamos una partición lógica, usando toda la partición extendida.

Nos quedará una cosa de este estilo:

Disk /dev/sdb: 3951 MB, 3951034368 bytes
122 heads, 62 sectors/track, 1020 cylinders, total 7716864 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
Disk identifier: 0x000a735d

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1   *        2048      499711      248832   83  Linux
/dev/sdb2          499712     7716863     3608576    5  Extended
/dev/sdb5          501760     7716863     3607552   83  Linux

Ahora volvemos a montar la partición de arranque, pero la que acabamos de copiar (debería ser idéntica a la original, y así nos aseguramos), creamos un volumen cifrado LUKS dentro del cual protegeremos un LVM. Queremos que dicho LVM se llame csi, como el original, así que cambiamos el nombre del LVM original a csi2:

$ mount /dev/sdb1 /mnt
$ cryptsetup luksFormat /dev/sdb5 /mnt/z-keyfile
$ cryptsetup luksOpen --key-file /mnt/z-keyfile XX
$ vgrename csi csi2
$ pvcreate /dev/mapper/XX
$ vgcreate csi /dev/mapper/XX

Ahora activamos el nuevo LVM, recreamos los volúmenes originales y copiamos los datos de la partición de sistema operativo que redujimos a 2.5GB más arriba:

$ vgscan
$ vgchange -a y
$ lvcreate -n swap_1 -L 500M csi
$ mkswap -F /dev/csi/swap_1
$ lvcreate -n root -L 2500M csi
$ dd if=/dev/csi2/root of=dev/csi/root bs=65536

Obsérvese que el nuevo swap ocupa solo 500MB en vez de los 4 GB originales. Queda por evaluar la conveniencia de eliminar el swap por completo. De momento se pueden hacer pruebas con swapoff -a [4].

Ahora montamos /dev/csi/root y hacemos lo siguiente:

  1. Borramos el fichero /etc/udev/rules.d/70-persistent-net.rules de la tarjeta microSD (no el fichero del sistema operativo en funcionamiento). Aquí se guardan, de forma persistente, las asignaciones entre interfaces de red y sus nombres. Con el cambio de máquina queremos que todo empiece de cero. Es decir, que las interfaces de red de la máquina nueva empiecen en eth0.
  2. Editamos el fichero /etc/fstab de la tarjeta microSD (no el fichero del sistema operativo en funcionamiento) e indicamos que la partición de sistema (la partición root) y la particion de arranque (la partición boot) deben montarse con la opción de noatime. Esto mejora el paupérrimo rendimiento de escritura de la tarjeta microSD y aumenta su vida útil evitando escrituras innecesarias [4]. A cambio no perdemos nada de interés.

Expulsamos la tarjeta microSD de la máquina virtual, la metemos en el HP ProLiant MicroServer Gen8 G1610T 1P 2GB-U B120i NHP SATA Server y funciona a la primera.

Tras hacer algunas pruebas, actualizar el sistema, etc., volvemos a sacar la tarjeta microSD del ProLiant, la enchufo en mi portátil y copio los 4GB de la tarjeta, sector a sector, en un servidor remoto [5]. Por si las moscas.

Actualización 20150105: Sigue leyendo en Backup doméstico seguro con Linux, cifrado y ZFS (IV): Redimensionamiento LVM e identificación de discos duros.

[1] El tamaño de bloque en esta partición es de 4096 bytes. Por tanto, 500000 bloques son 2GB.
[2]

Reducir el tamaño del sistema de ficheros un poco más de lo necesario y luego ampliarlo hasta completar el tamaño del volumen es una buena práctica que nos evitará disgustos si afinamos demasiado y reducimos el volumen más de lo que necesita el sistema de ficheros. Un sistema de ficheros de 2GB puede ocupar un poco más de 2GB en el disco físico. No tenerlo en cuenta es catastrófico. Por ello yo prefiero hacer los tres pasos y reducir el tamaño del sistema de ficheros primero bastante más que la reducción de tamaño del volumen lógico. En este caso me aseguro un colchón de seguridad de 500MB. No pierdo espacio porque el paso final pide al sistema de ficheros que complete el volumen.

Actualización 20150105: Novedades sobre este tema en Backup doméstico seguro con Linux, cifrado y ZFS (IV): Redimensionamiento LVM e identificación de discos duros.

[3] Si se va la luz o el ordenador se cuelga durante esta operación tendremos una partición completamente corrupta. En este caso mantengo una copia del VDI original de 9GB que me permite repetir el proceso en caso de error o contingencias inesperadas.
[4] (1, 2) Hay más información sobre la microSD que estamos utilizando, como su velocidad y por qué esta no es un problema, en mi artículo anterior: Backup doméstico seguro con Linux, cifrado y ZFS (IV): Elección de sistema operativo y configuración. También hablo del swap y el "Out of Memory" Killer.
[5] Aunque solo estamos utilizando unos 2GB de la tarjeta microSD de 4GB no podemos comprimir nada porque el grueso de los datos están cifrados con LUKS. Tendremos que transmitir y almacenar 4GB.