Transferir una imagen de disco a través de la red. Bash y más

Publicado el 08 abril 2015 por Gaspar Fernández Moreno @gaspar_fm


Foto: nrkbeta Flickr (CC-by)

Todo surgió cuando quería cambiar el disco duro de mi mediacenter. El disco duro lo tenía en mi ordenador de trabajo y el mediacenter (que hace también las veces de router/firewall y demás) no podía desenchufarlo. Es verdad que para un disco duro montado y activo no es la mejor forma, pero ya puestos, quería hacer el experimento, por lo que elegí algunas particiones que no tenían demasiada actividad (que luego fsck se encargue )

Para lo que sí puede servir es para crear imágenes de discos duros y transmitirlas a un servidor central para su almacenaje, ya sea por problemas de sitio, que no tengas espacio suficiente en algún dispositivo externo, o porque por seguridad se quiere transmitir a un servidor remoto o también, porque se tengan que instalar muchos ordenadores con configuraciones parecidas y, una vez configurado uno (ya sea con Windows, o cualquier UNIX), los configuramos todos desde aquí.

Eso sí, para ejecutar esto necesitamos Bash, dd (que suele con los *nix), pv (podemos pasar de el, pero se agradece), bzip2 (para comprimir) y netcat (para transmitir). ¡Manos a la obra!

¡ Tened cuidado cuando estéis probando esto ! ¡ Podéis escribir directamente en el disco y perder información !

En la máquina destino: Servidor

En la máquina donde queremos copiar la imagen. El destino, hará de servidor (podríamos invertir los papeles suelo). En esa máquina (suponiendo que el disco destino sea (/dev/sdd1) y que el puerto que queremos el 19000), en un terminal, escribiremos esto:

En esta línea:

  • nc (netcat) será el encargado de la transmisión de datos, con -l 19000 lo ponemos en modo escucha por el puerto 19000
  • bzip2 será el programa de compresión encargado de descomprimir (para eso el -d)
  • dd escribirá en el dispositivo (le ponemos sudo porque esta operación requerirá privilegios de escritura en dicho dispositivo), con bs=16M especificamos el tamaño del bloque, y of=/dev/sdd1 especifica el dispositivo.

Si queremos que se almacene en un archivo directamente, sin escribir en ningún dispositivo:

En la máquina origen: cliente

Esta imagen será la que emitirá la imagen, se conectará con el host servidor, la comprimirá y se la pasará. Nuestro dispositivo de origen será /dev/sda1 y la máquina con la que conectaremos 192.168.0.20:

En este caso:

  • ORIGIN=/dev/sda1 : Lo ponemos para no tener que repetir /dev/sda1 en la instrucción y evitar fallos del copia y pega
  • dd : Como antes, es el encargado de interactuar con el disco, como ahora extraemos información de él (of="$ORIGIN"), en este caso es lo mismo que of=/dev/sda1
  • pv : Nos indicará el progreso, ¿ cuántos bytes lleva copiados ? creará una barra de progreso que podemos mirar para ver cuánto queda. Es muy útil porque la transmisión de un disco duro por red es muy lenta y queremos saber cuánto queda. Con -s especificamos el tamaño que lo calcularemos con lo siguiente:
  • lsblk : Extrae información de un dispositivo de bloques, tiene una salida compleja, por eso, con -n le quitamos encabezados, con -b especificamos la salida en bytes, con -o SIZE decimos que sólo queremos que nos diga el tamaño del dispositivo, y "$ORIGIN" indicará el dispositivo, que aquí es /dev/sda1 (si queremos podemos poner esto directamente). Además, todo está entre $(...) para pasar el valor resultante al argumento -s de pv.
  • bzip2 : será el compresor esta vez, por eso -c.
  • nc : se encarga de la transmisión por red, conectará con el host 192.168.0.20 y el puerto 19000

¡Y listo! Pasado un rato, hemos transmitido la imagen de disco que necesitábamos.