3 pasos para migrar de una tarjeta SD a un disco USB en Raspberry Pi

Captura

Los dispositivos Raspberry Pi vienen por defecto con una tarjeta SD con dos particiones en donde se almacenan los ficheros de inicio del sistema (/boot) y los datos del propio sistema operativo, de usuario y swap (/). Sin embargo, uno de los principales problemas en este almacenamiento es la cantidad de operaciones de I/O de disco que lleva a cabo el sistema operativo que a la larga afectan la integridad de los ficheros almacenados en una tarjeta SD que inicialmente no está diseñada para ello y por ello es muy común que después de un tiempo el filesystem se corrompa.

Para ello, en este artículo se explicará el proceso de migración de almacenamiento de una tarjeta SD a un disco duro externo USB, lo cual optimizará el desempeño, el espacio de almacenamiento y la integridad de los datos almacenados. Se dejará en la tarjeta SD el filesystem /boot y el filesystem / se migrará al disco duro.

Requerimientos

Paso 1: Montar y formatear el disco duro externo

Tal como se indica arriba, se requiere un disco duro externo con alimentación independiente. En mi caso, tengo un disco duro Western Digital Elements de 1TB que va muy bien para este caso.

Siendo así, lo primero es mirar el almacenamiento actual en la tarjeta SD (en mi caso es una tarjeta de 8GB):

pi@raspberrypi ~ $ df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/root       7.2G  3.0G  4.0G  43% /
devtmpfs        214M     0  214M   0% /dev
tmpfs            44M  416K   44M   1% /run
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs            87M     0   87M   0% /run/shm
/dev/mmcblk0p1   56M   20M   37M  36% /boot

Después, conectar el disco duro al puerto USB y mirar que el sistema operativo lo haya detectado:

root@raspberrypi / # lsusb
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.
Bus 001 Device 007: ID 1a40:0101 Terminus Technology Inc. 4-Port HUB
Bus 001 Device 008: ID 1058:1003 Western Digital Technologies, Inc. Elements 1000 GB

En este caso no hay problema, por lo que se procede a revisar las particiones que están definidas en ese disco duro externo:

root@raspberrypi /etc/network # lsblk
NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda           8:0    0 931.5G  0 disk
+-sda1        8:1    0 931.5G  0 part
mmcblk0     179:0    0   7.4G  0 disk
+-mmcblk0p1 179:1    0    56M  0 part /boot
+-mmcblk0p2 179:2    0   7.4G  0 part /

Como se ve, se tiene únicamente una partición. Para crear una nueva partición se utilizará gdisk, la versión evolucionada de fdisk, que se instala mediante el gestor de paquetes apt:

root@raspberrypi / # apt-get install gdisk
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following NEW packages will be installed:
  gdisk
0 upgraded, 1 newly installed, 0 to remove and 1 not upgraded.
Need to get 376 kB of archives.
After this operation, 795 kB of additional disk space will be used.
Get:1 http://mirrordirector.raspbian.org/raspbian/ wheezy/main gdisk armhf 0.8.5-1 [376 kB]
Fetched 376 kB in 1s (263 kB/s)
Selecting previously unselected package gdisk.
(Reading database ... 86486 files and directories currently installed.)
Unpacking gdisk (from .../gdisk_0.8.5-1_armhf.deb) ...
Processing triggers for man-db ...
Setting up gdisk (0.8.5-1) ...

Instalado gdisk, proceder con la creación de una nueva partición sobre el disco /dev/sda:

root@raspberrypi / # gdisk /dev/sda
GPT fdisk (gdisk) version 0.8.5

Partition table scan:
  MBR: MBR only
  BSD: not present
  APM: not present
  GPT: not present


***************************************************************
Found invalid GPT and valid MBR; converting MBR to GPT format.
THIS OPERATION IS POTENTIALLY DESTRUCTIVE! Exit by typing 'q' if
you don't want to convert your MBR partitions to GPT format!
***************************************************************


Warning! Secondary partition table overlaps the last partition by
32 blocks!
Try reducing the partition table size by 128 entries.
(Use the 's' item on the experts' menu.)

Con el comando “p” se listan las particiones existentes y con “d” se eliminan:

Command (? for help): p
Disk /dev/sda: 1953525168 sectors, 931.5 GiB
Logical sector size: 512 bytes
Disk identifier (GUID): B0E4F162-20DD-44BE-852F-EB90229E34E6
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 1953525134
Partitions will be aligned on 8-sector boundaries
Total free space is 29 sectors (14.5 KiB)

Number  Start (sector)    End (sector)  Size       Code  Name
   1              63      1953525166   931.5 GiB   0700  Microsoft basic data
   
Command (? for help): d
Using 1

Ahora, se crearán dos particiones (comando “n“): Una de 50GB para el sistema operativo (esta es la más importante en este artículo) y el resto (+/- 880GB) para almacenamiento general:

Command (? for help): n
Partition number (1-128, default 1):
First sector (34-1953525134, default = 40) or {+-}size{KMGTP}:
Last sector (40-1953525134, default = 1953525134) or {+-}size{KMGTP}: 50G
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300):
Changed type of partition to 'Linux filesystem'

Command (? for help): p
Disk /dev/sda: 1953525168 sectors, 931.5 GiB
Logical sector size: 512 bytes
Disk identifier (GUID): B0E4F162-20DD-44BE-852F-EB90229E34E6
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 1953525134
Partitions will be aligned on 8-sector boundaries
Total free space is 1848667540 sectors (881.5 GiB)

Number  Start (sector)    End (sector)  Size       Code  Name
   1              40       104857600   50.0 GiB    8300  Linux filesystem

Command (? for help): n
Partition number (2-128, default 2):
First sector (34-1953525134, default = 104857608) or {+-}size{KMGTP}:
Last sector (104857608-1953525134, default = 1953525134) or {+-}size{KMGTP}:
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300):
Changed type of partition to 'Linux filesystem'

Command (? for help): p
Disk /dev/sda: 1953525168 sectors, 931.5 GiB
Logical sector size: 512 bytes
Disk identifier (GUID): B0E4F162-20DD-44BE-852F-EB90229E34E6
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 1953525134
Partitions will be aligned on 8-sector boundaries
Total free space is 13 sectors (6.5 KiB)

Number  Start (sector)    End (sector)  Size       Code  Name
   1              40       104857600   50.0 GiB    8300  Linux filesystem
   2       104857608      1953525134   881.5 GiB   8300  Linux filesystem

Guardar los cambios con “w“:

Command (? for help): w

Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!

Do you want to proceed? (Y/N): Y
OK; writing new GUID partition table (GPT) to /dev/sda.
The operation has completed successfully.

Finalmente, formatear las particiones creadas como EXT4:

root@raspberrypi / # mke2fs -t ext4 -L rootfs /dev/sda1
mke2fs 1.42.5 (29-Jul-2012)
Filesystem label=rootfs
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
3276800 inodes, 13107195 blocks
655359 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=0
400 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks:
        32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
        4096000, 7962624, 11239424

Allocating group tables: done
Writing inode tables: done
Creating journal (32768 blocks):
done
Writing superblocks and filesystem accounting information: done

root@raspberrypi / # mke2fs -t ext4 -L rootfs /dev/sda2
mke2fs 1.42.5 (29-Jul-2012)
Filesystem label=rootfs
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
57778176 inodes, 231083440 blocks
11554172 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=0
7053 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks:
        32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
        4096000, 7962624, 11239424, 20480000, 23887872, 71663616, 78675968,
        102400000, 214990848

Allocating group tables: done
Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

Paso 2: Montar la nueva partición y migrar los datos

Creadas y formateadas las particiones, se procede con la copia de los datos de la tarjeta SD a la partición creada en el disco duro externo. En este caso, se usará la primera partición (/dev/sda1), dejando la segunda para almacenamiento general (/dev/sda2). La idea es montarla bajo /mnt como en este caso:

root@raspberrypi / # mount -t ext4 /dev/sda1 /mnt
root@raspberrypi / # df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/root       7.2G  3.0G  4.0G  43% /
devtmpfs        214M     0  214M   0% /dev
tmpfs            44M  392K   44M   1% /run
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs            87M     0   87M   0% /run/shm
/dev/mmcblk0p1   56M   20M   37M  36% /boot
/dev/sda1        50G   52M   47G   1% /mnt

Ahora, se debe realizar una copia de ficheros bajo / que mantenga los permisos y características de los ficheros igual a los originales. Para ello se usará “rsync” aunque también se puede usar “cp” (#cp -ax / /mnt) o “dd” (#dd bs=4M conv=noerror if=/dev/mmcblk0p2 of=/dev/sda1):

root@raspberrypi / #rsync -axv / /mnt

Este paso suele tardarse unos 10-15 minutos.

Paso 3: Modificar los ficheros de arranque (boot) y reiniciar el sistema

Cuando los pasos anteriores estén listos, se procede con la modificación del fichero /boot/cmdline, en el que se le indica al dispositivo en dónde se encuentra la partición con el sistema operativo. Como siempre, antes de hacer cualquier cambio se debe hacer una copia de seguridad:

root@raspberrypi / # cp /boot/cmdline.txt /boot/cmdline.backup

Luego, modificar el contenido del fichero para que refleje el nombre de la nueva partición que se ha creado y que reside en el disco USB externo, quedando de la siguiente manera:

root@raspberrypi / # more /boot/cmdline.txt
dwc_otg.lpm_enable=0 console=ttyAMA0,115200 console=tty1 root=/dev/sda1 rootfstype=ext4 elevator=deadline rootwait rootdelay=5

En este caso, se ha cambiado el parámetro “root” con el nombre de la partición del disco externo (/dev/sda1) y se ha agregado el parámetro “rootdelay“, que adiciona un periodo de espera para garantizar que los drivers del disco USB se carguen de forma correcta antes de proceder con el inicio del sistema operativo.

Hay que tener en cuenta que el sistema operativo de Raspberry Pi (en este caso Raspbian) no soporta nombres de particiones con UUID o labels, por lo que se usan las referencias tradicionales a /dev.

Para finalizar, se edita el fichero “fstab” ubicado en la nueva partición para que monte los nuevos filesystems. Se deshabilita la línea correspondiente a /dev/mmcblk0p2 y se remplaza por /dev/sda1:

root@raspberrypi /boot # pico /mnt/etc/fstab
root@raspberrypi /boot # more  /mnt/etc/fstab
proc            /proc           proc    defaults          0       0
/dev/mmcblk0p1  /boot           vfat    defaults          0       2
#/dev/mmcblk0p2  /               ext4    defaults,noatime  0       1
/dev/sda1  /       ext4    defaults,noatime        0       1
# a swapfile is not a swap partition, so no using swapon|off from here on, use  dphys-swapfile swap[on|off]  for that

Hecho esto, se reinicia el sistema (“reboot“) y se valida que los filesystems se hayan montado correctamente y que el sistema esté ubicado en /dev/sda1. Más adelante, se puede montar la partición /dev/sda2 en un punto de montaje deseado para almacenar datos de usuario.

EXTRA: Ampliar el tamaño del área de Swap de la Raspberry Pi

Como ya se tiene bastante almacenamiento disponible en el disco externo, se puede realizar una ampliación del fichero de swap (paginación) del sistema operativo. Para ello, se edita el fichero /etc/dphys-swapfile (que por lo general tiene un valor de 100MB) y se remplaza por 512, que es el valor en MB de la RAM del dispositivo:

root@raspberrypi / # cat /etc/dphys-swapfile
CONF_SWAPSIZE=512

Luego, se ejecuta el comando “dphys-swapfile” que re-genera un nuevo fichero con el tamaño indicado:

root@raspberrypi /opt/seafile-server-latest # dphys-swapfile setup
want /var/swap=512MByte, checking existing: deleting wrong size file (104857600), generating swapfile ... of 512MBytes

Para que los cambios se apliquen, se reinicia el servicio “dphys-swapfile“:

root@raspberrypi / # /etc/init.d/dphys-swapfile stop
Stopping dphys-swapfile swapfile setup ..., done.
root@raspberrypi / # /etc/init.d/dphys-swapfile start
Starting dphys-swapfile swapfile setup ...
want /var/swap=512MByte, checking existing: keeping it
done.

Con todo esto, se logrará tener un mejor almacenamiento y desempeño de la Raspberry Pi y evitar problemas de corrupción de datos.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.