¿Cómo cambiar el tamaño del archivo img creado con dd?

19

Tengo una imagen DD de una tarjeta SD de 4GB que tiene dos particiones, estas dos particiones solo están usando aproximadamente 800 MB y, como tal, deseo reducir el tamaño de la imagen.

¿Alguien sabe de una manera de eliminar el "espacio libre" del archivo img?

A_Porcupine
fuente
es posible que desee agregar cuál es el resultado deseado. es decir: imagen de vuelta a la tarjeta, para almacenar en CD.
Wayne

Respuestas:

8

Primero asegúrese de que el espacio libre esté realmente vacío y que no contenga restos de archivos eliminados. La forma más fácil de lograr esto es crear un archivo enorme en el disco, que contenga solo bytes nulos, y luego eliminarlo.

# losetup --find --partscan foo.img
# lsblk
NAME      MAJ:MIN RM    SIZE RO TYPE MOUNTPOINT
loop0       7:0    0   4096M  0 loop 
├─loop0p1 259:0    0   2048M  0 loop 
└─loop0p2 259:1    0   2048M  0 loop 
# for part in /dev/loop0p*; do
    mount $part /mnt
    dd if=/dev/zero of=/mnt/filler conv=fsync bs=1M
    rm /mnt/filler
    umount /mnt
  done
dd: error writing ‘/mnt/filler’: No space left on device
dd: error writing ‘/mnt/filler’: No space left on device
# losetup --detach /dev/loop0

Luego comprímalo con una herramienta como gzipo xz. Incluso en los niveles de compresión más bajos, una larga serie de ceros se comprime bien:

# ls -s
4096M foo.img
# gzip foo.img
# ls -s
11M foo.img.gz

Tenga en cuenta que debe descomprimir la imagen al volver a escribirla en el disco. Esto lo descomprimirá 'en vivo':

# cat foo.img.gz | gunzip | dd of=/dev/sda

Tenga en cuenta que el dispositivo de salida (sda) debe tener el tamaño suficiente para adaptarse a la imagen original ; de lo contrario, los datos se perderán o se dañarán.


Un método alternativo, si desea seguir usando la imagen, por ejemplo, con una máquina virtual, es convertir la imagen en bruto en uno de los formatos de imagen utilizados por el software de virtualización; por ejemplo, qcow2 para Qemu, VDI para VirtualBox o VMDK para VMware.

Tenga en cuenta que esto aún requiere que prepare la imagen limpiando el espacio libre utilizando el método anterior.

# qemu-img convert -f raw -O qcow2 foo.img foo.qcow

# qemu-img convert -f raw -O vmdk foo.img foo.vmdk

Pero si va a volver a escribirse en un disco real, debe volver a convertirlo en una imagen sin formato.

usuario1686
fuente
1
¿Cómo puede estar seguro de que todos los archivos que están almacenados actualmente en las particiones no están físicamente dispersos en el disco?
Valerio Santinelli
porque supongo que los archivos no se escriben secuencialmente en el disco y si un archivo está al final del almacenamiento, cuando reduzca el tamaño, perderé el contenido de ese archivo.
Valerio Santinelli
Porque el OP pregunta cómo reducir una imagen de disco sin perder datos. Si trunca una imagen con un tamaño determinado, no puede estar seguro de que se conservarán los datos.
Valerio Santinelli
@ValerioSantinelli: ¿Dónde sugiero exactamente truncar la imagen?
user1686
1
@ValerioSantinelli: Al usar la herramienta adecuada para cambiar el tamaño del sistema de archivos para su sistema de archivos, por ejemplo, resize2fso ntfsresize(Linux no tiene ninguna herramienta para FAT), antes de escribirla en el dispositivo más pequeño, o al crear un nuevo sistema de archivos y copiar solo los archivos.
user1686
22

Usar resize2fses mucho más fácil

resize2fs -M xxx.img

primero se le pedirá que e2fsck, así que:

e2fsck -f -y xxx.img

(¡La imagen NO se debe montar!)

Nota: esto solo funcionará si la imagen es de una sola partición, si es un dispositivo de bloque completo con múltiples particiones, vea la respuesta anterior ...

Serge Wagner
fuente
Solo una nota: para particiones múltiples, use losetup --find --partscan xxx.imgpara configurar el archivo de imagen como un dispositivo de bucle. luego ejecute lsblkpara encontrar las particiones del dispositivo de bucle.
Yihui Xiong
Parece que no funciona para la imagen ISO que contiene el sistema operativo. Después de cambiar el tamaño del sistema, no inicie.
SR
Sistema operativo @SR Linux?
Rolf
1
Esta es una respuesta muy buena, pero resize2fsson solo para extNparticiones de tipo. Otros tipos de particiones requerirán otras herramientas.
Rolf
2

También lo probé con qemu-img , y funcionó de maravilla :

qemu-img resize test.img 2G

Estamos cambiando el tamaño test.imgpara que sea 2G (2GB).

Funcionó sin problemas para mí.

Phil Roggenbuck
fuente
1
Impresionante, funcionó perfectamente para mí también, comprimiendo una imagen de Raspbian. ¡totalmente trabajando!
ffleandro
Bueno, todo funciona, sin embargo, después del arranque, la ejecución df -hmuestra el tamaño original. ¿Cómo es esto posible?
ffleandro
Aparentemente, qemu-img no funciona en la tabla de particiones, entonces, ¿cómo comprime el archivo .img?
ffleandro
Puedo cambiar el tamaño de un disco .img a 1M, lo que definitivamente rompe la imagen del disco. ¿Alguna idea para hacer que el cambio de tamaño sea más seguro?
lesca
1

He usado el enfoque separado con mi computadora Ubuntu 16.10:

1) Asigne el archivo img a la siguiente partición de bucle disponible losetup, como se describe en publicaciones anteriores como se indica arriba

2) Compruebe con lsblkqué unidad de bucle está asignado su archivo de imagen, p. Ej./dev/loop0

3) Ejecutar sudo gparted /dev/loop0

4) Reducir la (s) partición (es) de bucle según se considere apropiado; asegúrese de tener estas particiones desmontadas.

5) Ejecute fdisk /dev/loop0, luego ingrese p, esto le mostrará el tamaño del bloque y el número de bloque final de las diversas particiones.

6) Ejecutar dd if=/dev/loop0 of=shrunk_image_file.img, aplicar a ese comando las opciones bs=[BlockSize]y count=[EndBlockNumberOfLastLoopPartition+1]tendrá un archivo de imagen reducido y de tamaño correcto.

VeryNoob
fuente