Usar un fichero como un Disco
En Linux todo son ficheros
Si recordáis, en artículos anteriores ya hemos comentado que Linux, todo son ficheros y se tratan como tales: Los dispositivos son ficheros, los directorios son ficheros y los ficheros son ficheros...
Usando ficheros como discos
Dado que todo son ficheros, puede que un determinado momento necesitemos disponer de un "disco" extra para realizar alguna tarea sobre él o simplemente practicar comandos de particionado o de formateo.
Creando un fichero
Para transformar un fichero en un dispositivo (o disco), lo primero que deberemos hacer es crearlo del tamaño que vayamos a necesitar.
Vamos a usar el comando dd
que nos permite crear un fichero del tamaño deseado de una forma muy sencilla.
La sintaxis para usar dd
es la siguiente:
dd if=dispositivo-entrada of=dispositivo-salida [opciones]
Como dispositivo de entrada vamos a usar /dev/zero
para generar caracteres nulos con los que "rellenar el fichero".
Como dispositivo de salida vamos a indicar el nombre de un fichero
en el que escribiremos.
En la parte de opciones indicaremos como parametro el tamaño de bloque (bs
o block-size) que deseamos usar y además cuantas veces vamos iterar para generar multiples bloques mediante el parámetro count
Vamos a crear nuestro primer fichero disco
de un tamaño aproximado de 200 Mb:
# Generar fichero vacio de 200 Mb en una única escritura
dd if=/dev/zero of=disco bs=200M count=1
1+0 records in
1+0 records out
209715200 bytes (210 MB, 200 MiB) copied, 0,146605 s, 1,4 GB/s
Obtenemos el siguiente resultado en pantalla:
Formateando el fichero
Ahora simplemente podemos formatear el fichero para que se comporte como un sistema de ficheros y poderlo montar y usarlo como si fuese un disco, necesitamos privilegios de root
para realizarlo:
# Formatear como ext4 el fichero
sudo mkfs.ext4 disco
En la pantalla veremos:
Compramos que tipo de fichero
es mediante el comando file
:
file disco
disco: Linux rev 1.0 ext4 filesystem data,
UUID=47a317b3-0455-473b-a770-9ad740abe910
(extents) (64bit) (large files) (huge files)
Montando el fichero como si fuese un disco
Para poderlo usar simplemente necesitaremos crear un punto de montaje y como usuario root
montar nuestro nuevo dispositivo (fichero):
# Crear punto de montaje (pruebas en /tmp):
mkdir -p /tmp/punto-montaje
# Montar fichero (disco):
sudo mount disco /tmp/punto-montaje/
Podemos comprobar si está montado correctamente, y el tamaño del disco:
# Comprobamos si esta montado...
mount|grep -i disco
/tmp/disco on /tmp/punto-montaje type ext4 (rw,relatime)
# Comprobar tamaño del "disco"
df -h /tmp/punto-montaje/
S.ficheros Tamaño Usados Disp Uso% Montado en
/dev/loop0 182M 14K 168M 1% /tmp/punto-montaje
Podemos observar que tanto el tamaño del disco, como el espacio disponible no se corresponde con el total de tamaño del fichero.
Esto se debe a que al formatear el dispositivo con el File System deseado, hay cierto espacio que se reserva para gestionar la tabla de particiones, el journaling, etc.
Podemos acceder al disco, cambiandonos simplemente al punto de montaje y usarlo como si fuese un dispositivo normal.
cd /tmp/punto-montaje/
ls -l
total 12
drwx------ 2 root root 12288 ago 22 01:34 lost+found
Una vez usado, para desmontarlo simplemente escribiremos:
sudo umount /tmp/punto-montaje
Fichero como disco con Particiones
Ahora vamos a ver algo un poco más avanzado. Vamos a crear un fichero, crear particiones dentro de él, formatear cada partición y montarlas.
Creación del fichero
El procedimiento es identico y usaremos el comando dd
tal y como hicimos anteriormente:
# Creamos fichero de tamaño aprox de 220 Mb
dd if=/dev/zero of=disco-particion bs=220M count=1
1+0 records in
1+0 records out
230686720 bytes (231 MB, 220 MiB) copied, 0,0999712 s, 2,3 GB/s
Particionado del fichero
Podemos usar el comando fdisk
(como root) para crear las particiones que deseemos en el fichero disco-particion
que hemos creado.
En nuestro caso para simplificar unicamente voy a crear 2 particiones:
sudo fdisk disco-particion
Y vamos contestando a cada una de las preguntas:
Bienvenido a fdisk (util-linux 2.38.1).
Los cambios solo permanecerán en la memoria, hasta que decida escribirlos.
Tenga cuidado antes de utilizar la orden de escritura.
El dispositivo no contiene una tabla de particiones reconocida.
Created a new DOS (MBR) disklabel with disk identifier 0xe3693333.
Orden (m para obtener ayuda): n
Tipo de partición
p primaria (0 primaria(s), 0 extendida(s), 4 libre(s))
e extendida (contenedor para particiones lógicas)
Seleccionar (valor predeterminado p): p
Número de partición (1-4, valor predeterminado 1): 1
Primer sector (2048-450559, valor predeterminado 2048):
Último sector, +/-sectores o +/-tamaño{K,M,G,T,P} (2048-450559, valor predeterminado 450559): +110M
Crea una nueva partición 1 de tipo 'Linux' y de tamaño 110 MiB.
Orden (m para obtener ayuda): n
Tipo de partición
p primaria (1 primaria(s), 0 extendida(s), 3 libre(s))
e extendida (contenedor para particiones lógicas)
Seleccionar (valor predeterminado p): p
Número de partición (2-4, valor predeterminado 2): 2
Primer sector (227328-450559, valor predeterminado 227328):
Último sector, +/-sectores o +/-tamaño{K,M,G,T,P} (227328-450559, valor predeterminado 450559):
Crea una nueva partición 2 de tipo 'Linux' y de tamaño 109 MiB.
Orden (m para obtener ayuda): w
Se ha modificado la tabla de particiones.
Se están sincronizando los discos.
Comprobar particiones
Para comprobar si se han creado las particiones usaremos de nuevo el comando dd
con el parámetro --list
:
sudo fdisk -l disco-particion
Disco disco-particion: 220 MiB, 230686720 bytes, 450560 sectores
Unidades: sectores de 1 * 512 = 512 bytes
Tamaño de sector (lógico/físico): 512 bytes / 512 bytes
Tamaño de E/S (mínimo/óptimo): 512 bytes / 512 bytes
Tipo de etiqueta de disco: dos
Identificador del disco: 0xe3693333
Disposit. Inicio Comienzo Final Sectores Tamaño Id Tipo
disco-particion1 2048 227327 225280 110M 83 Linux
disco-particion2 227328 450559 223232 109M 83 Linux
Otra forma de verlo sería mediante el comando file
:
file disco-particion
disco-particion: DOS/MBR boot sector;
partition 1 : ID=0x83, start-CHS (0x0,32,33), end-CHS (0xe,38,24),
startsector 2048, 225280 sectors;
partition 2 : ID=0x83, start-CHS (0xe,38,25), end-CHS (0x1c,11,47),
startsector 227328, 223232 sectors
Calculando el Offset de las Particiones del Fichero
Si intentas acceder a las particiones de fichero, verás que no puedes realizar ninguna operación con ellas.
Para poder gestionarlas, hay que usar el valor de offset
(desplazamiento) para indicar a los comandos necesarios (formate o montaje) a que posición tiene que acceder para realizar la operación indicada.
Paso 1. Obtener el valor del tamaño del sector
Aunque por defecto el valor suele ser de 512 bytes, es recomendable comprobarlo.
Si observas el resultado del comando fdisk -l disco-particion
verás que el valor se mostraba en la línea:Tamaño de sector (lógico/físico): 512 bytes / 512 bytes
Paso 2. Obtener el offset
de inicio de cada partición
Debemos fijarnos en que sector se inicia cada partición:
La 1ª particion disco-particion1
comienza en el sector 2048
La 2ª partición disco-particion2
comienza en el sector 227328
Para calcular el offset
simplemente se multiplica el tamaño de sector por el sector de inicio de cada partición.
Podemos hacer la operación desde la propia terminal sin necesidad de usar una calculadora:
# Calcular offset de disco-particion1 (sector 2048):
echo $((2048 * 512))
1048576
# Calcular offset de disco-particion2 (sector 227328):
echo $((227328 * 512))
116391936
Formatear las Particiones del Fichero
Con los valores de offset
calculados ya puedes formatear cada una de sus particiones.
Al comando mkfs
deberás indicarle como dispositivo el nombre del fichero y como parámetro extra el offset calculado anteriormente:-E offset=ValorOFFSET
:
# Formatear la 1ª particion (como ext4)
sudo mkfs.ext4 disco-particion -E offset=1048576
# Formatear la 2ª particion (como ext4)
sudo mkfs.ext4 disco-particion -E offset=116391936
Montar las Particiones del Fichero
Al igual que con el formateo, para realizar el montaje de cada partición podemos usar el comando mount
, pero indicaremos la posición de inicio en la que buscar el sistema de ficheros, mediante el parámetro -o
le indicaremos el offset
:
# Montar 1ª partición:
sudo mount -o offset=1048576 disco-particion /tmp/montaje-part1/
# Montar 2ª partición:
sudo mount -o offset=116391936 disco-particion /tmp/montaje-part2/
Mediante un montaje directo con mount
al intentar montar la 2ª partición nos encontraremos con el error:mount: ya existe un dispositivo de bucle que solapa con disco-particion.
Para poder montar varias veces el mismo fichero usaremos el comando losetup
y también usaremos los valores de los offset
obtenidos.
# losetup 1ª particion (en loop-1)
sudo losetup /dev/loop1 --offset 1048576 disco-particion
# losetup 2ª particion (en loop-2)
sudo losetup /dev/loop2 --offset 116391936 disco-particion
# Montar loopN en punto de montaje:
2282 sudo mount /dev/loop1 /tmp/montaje-part1/
2283 sudo mount /dev/loop2 /tmp/montaje-part2/
Si comprobamos el montaje y tamaño disponible:
df -h
S.ficheros Tamaño Usados Disp Uso% Montado en
...
/dev/loop1 200M 2,8M 182M 2% /tmp/montaje-part1
/dev/loop2 97M 14K 90M 1% /tmp/montaje-part2
Script para calcular offset
Si quieres simplificar aun más cálculo del offset
, te dejo un script sencillo para que puedas obtener las particiones y los valores de desplazamiento de cada partición para cualquier dispositivo:
Para su uso debes usarlo como usuario root
o mediante sudo
.
Si lo ejecutas sin ningún parámetro te mostrará la ayuda de uso:
sudo ./offset-fileImage.sh
--------------------------------------------------------------
USAGE 1:
./offset-fileImage.sh file-image.img
Return the list of all existing partitions of the file-image
--------------------------------------------------------------
USAGE 2:
./offset-fileImage.sh file-image.img NUMBER
Returns the offset number of the file-image partitions
to format or mount it.
--------------------------------------------------------------