sábado 27 de septiembre de 2008

dd y backups de particiones de disco

Antes hablé muy bién de dd_rescue, aunque yo me declaro un habitual de dd. Supongo que es lo que he utilizado toda la vida y me siento más cómodo, aunque no escondo que dd_rescue es superior. Al menos lo parece.

El uso que le doy habitualmente a dd es el de crear backups de particiones completas. Hace poco he necesitado una copia de una partición Windows con NTFS, y he aprovechado para tomar unos pantallazos que presento a continuación a modo de ejemplo:

Primero, con fdisk he hecho una consulta de lo que tenía en /dev/sda, el disco que contiene la partición Windows a copiar:

nouser@nohost:~# fdisk -l /dev/sda

Disk /dev/sda: 120.0 GB, 120034123776 bytes
255 heads, 63 sectors/track, 14593 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Disk identifier: 0x04f6f9c9

Device Boot Start End Blocks Id System
/dev/sda1 1 192 1536000 27 Unknown
Partition 1 does not end on cylinder boundary.
/dev/sda2 * 192 3379 25600000 7 HPFS/NTFS
/dev/sda3 3379 10390 56320000 7 HPFS/NTFS
/dev/sda4 10391 14593 33760597+ 5 Extended
/dev/sda5 * 10391 14414 32322748+ 83 Linux
/dev/sda6 14415 14593 1437786 82 Linux swap / Solaris

La partición a copiar es /dev/sda2, la primera con boot flag.

El directorio donde pretendo hacer el backup es /media/disk/backup/:

nouser@nohost:~# test -d /media/disk/backup/
nouser@nohost:~# echo $?
0

Este directorio cuelga del device...

nouser@nohost:~# df -h /media/disk/backup/
Filesystem Size Used Avail Use% Mounted on
/dev/sdb1 466G 320G 147G 69% /media/disk

... /dev/sdb1 . Esta comprobación es sólo para asegurar que no creo la imagen del disco, en el mismo disco que pretendo copiar.

La copia con dd sería así:

nouser@nohost:~# dd if=/dev/sda2 of=/media/disk/backup/windows_base.dd conv=noerror 2>/tmp/windows_base.dd.err

if y of son la entrada (device) y salida (ruta filesystem), mientras que conv=noerror es para que dd siga con el proceso de copia si encuentra errores de disco. Si los hubiera, los veremos en /tmp/windows_base.dd.err. Tras los errores habría que decidir si el backup se da por bueno o no.

Aún sin errores, dd ofrece una estadística final a traves de stderr con lo que al acabar, si todo ha ido bien, /tmp/windows_base.dd.err debería contener sólo algo así:

nouser@nohost:~# tail /tmp/windows_base.dd.err
51200000+0 records in
51200000+0 records out
26214400000 bytes (26 GB) copied, 1497.58 s, 17.5 MB/s

Pero éste no era mi caso (todavía). Lo que obtuve en concreto fué lo siguiente:

nouser@nohost:~# tail /tmp/windows_base.dd.err
dd: writing to `/media/disk/backup/windows_base.dd': File too large
8388608+0 records in
8388607+1 records out
4294967295 bytes (4.3 GB) copied, 181.249 s, 23.7 MB/s

O sea, dd sólo había sido capaz de copiar 4.3 GB (cuando en realidad la partición era de 26 GB). Mi problema fué que la partición encargada de recibir el "ghost" era un disco multimedia formateado con FAT32, y este tipo de filesystem presenta esta limitación en lo que se refiere al tamaño de los ficheros que hospeda (Microsoft tenía que ser).

Una forma de salir del paso es la que nos explican aquí mediante el uso del comando split.

Pero yo preferí hacerme con otro disco y crear un nuevo filesystem con ext3, utilizando las mismas rutas/mountpoints de antes (/media/disk/backup). Y lanzé de nuevo el comando de antes, que esta vez funcionó.

Tras botar y guarrear la partición con Windows, volví a Linux y recuperé su estado original desde la copia que había hecho previamente:

nouser@nohost:~# cd /media/disk/backup
nouser@nohost:/media/disk/backup# dd if=windows_base.dd of=/dev/sda2 conv=noerror 2>/tmp/windows_a_su_sitio.err
nouser@nohost:/media/disk/backup# tail /tmp/windows_a_su_sitio.err
51200000+0 records in
51200000+0 records out
26214400000 bytes (26 GB) copied, 2378.93 s, 11.0 MB/s

Finalmente, para los que prefieran una solución parecida sin tener que recurrir a la línea de comandos, partimage es una buena opción. Aquí un tutorial desde debianadmin.com.