Tengo un montón de imágenes de disco, hechas con ddrescue, en una partición EXT, y quiero reducir su tamaño sin perder datos, sin dejar de ser montable.
¿Cómo puedo llenar el espacio vacío en el sistema de archivos de la imagen con ceros y luego convertir el archivo en un archivo disperso para que este espacio vacío no se almacene en el disco?
Por ejemplo:
> du -s --si --apparent-size Jimage.image
120G Jimage.image
> du -s --si Jimage.image
121G Jimage.image
Sin embargo, esto en realidad solo tiene 50G de datos reales, por lo que la segunda medición debería ser mucho más pequeña.
Esto supuestamente llenará el espacio vacío con ceros:
cat /dev/zero > zero.file
rm zero.file
Pero si los archivos dispersos se manejan de manera transparente , en realidad podría crear un archivo disperso sin escribir nada en el disco virtual, irónicamente evitando que convierta la imagen del disco virtual en un archivo disperso. :) ¿Lo hace?
Nota: Por alguna razón, sudo dd if=/dev/zero of=./zero.file
funciona cuando cat
no funciona en una imagen de disco montada.
fuente
sudo cat /dev/zero > zero.file
no funciona porque su bash (que se ejecuta como usted, no root) realiza la redirección antes de ejecutar elsudo
comando. Ver unix.stackexchange.com/questions/1416/…Respuestas:
En primer lugar, los archivos dispersos solo se manejan de forma transparente si busca, no si escribe ceros.
Para que quede más claro, el ejemplo de Wikipedia
no no escribir los ceros, se abrirá el archivo de salida, busque (saltar) 5 MB y luego escribir cero ceros (es decir, nada en absoluto). Este comando ( no de Wikipedia)
¡escribirá 5MB de ceros y no creará un archivo disperso!
Como consecuencia, un archivo que ya no es escaso no se convertirá mágicamente en escaso más adelante.
En segundo lugar, para hacer un archivo con muchos ceros ralos, usted tiene que cp se
o también puede usar la opción --sparse de tar 's o rsync ' s.
fuente
cat /dev/zero > zero.file
está perfectamente bien llenar el espacio vacío con ceros.dd
para escribir ceros o para buscar.cat
comando llenará todo su disco (o al menos la cantidad no reservada para root o por cuotas) con ceros "reales", y no creará archivos dispersos.Quizás la forma más fácil de esparcir un archivo en su lugar sería usar la
fallocate
utilidad de la siguiente manera:Fallocate (1) es proporcionado por el paquete util-linux en Debian .
fuente
fallocate --dig-holes
resultó en un archivo 103GiB del original 299GiB, mientras quecp --sparse=always
me dio 93GiB, todos con la misma suma SHA1 (tamaños verificados a través dedu -B1G
vsdu --apparent-size -B1G
). Entoncesfallocate
parece dar resultados inferiores.Editando mi respuesta para completar:
losetup --partscan --find --show disk.img
Supongamos que da / dev / loop1 como el disco y solo hay una partición, de lo contrario, debemos repetir esto para cada partición con FS montable (ignorar la partición de intercambio, etc.).
mkdir -p /mnt/tmp mount /dev/loop1p1 /mnt/tmp dd if=/dev/zero of=/mnt/tmp/tempfile
Deja que termine al fracaso con ENOSPC.
/bin/rm -f /mnt/tmp/tempfile umount /mnt/tmp losetup -d /dev/loop1
'dd' tiene una opción para convertir un archivo con ceros a un archivo disperso:
dd if=disk.img of=disk-sparse.img conv=sparse
fuente
zerofree
puede ser más rápido que montar y escribir ceros en el sistema de archivos, y hacer que la imagen del disco crezca menos si ya contenía muchos ceros.¿Quiere decir que su imagen creada con ddrescue es, digamos, 50 GB y en realidad algo mucho menos sería suficiente?
Si ese es el caso, ¿no podrías simplemente crear una nueva imagen con dd:
y luego crea un sistema de archivos en él:
luego simplemente monte la imagen y copie todo, desde la imagen anterior a la nueva. ¿Eso funcionaría para ti?
fuente
PartImage puede crear imágenes de disco que solo almacenan los bloques usados de un sistema de archivos, reduciendo drásticamente el espacio requerido al ignorar los bloques no utilizados. No creo que pueda montar directamente las imágenes resultantes, pero va:
Debe producir lo que desea (incluso podría ser posible pegar el último paso, no lo he intentado).
fuente
Ahora hay una herramienta llamada virt-sparsify que hará esto. Llena el espacio vacío con ceros y luego copia la imagen en un archivo disperso. Sin embargo, requiere instalar muchas dependencias.
fuente
Sospecho que necesitará un programa personalizado escrito con esa especificación si eso es REALMENTE lo que desea hacer. Pero es...?
Si realmente tiene muchas áreas de cero, cualquier buena herramienta de compresión lo reducirá significativamente. Y tratar de escribir archivos dispersos no funcionará en todos los casos. Si recuerdo correctamente, incluso los archivos dispersos ocupan un mínimo de 1 bloque de almacenamiento de salida donde el bloque de entrada contiene CUALQUIER bit que no sea cero. Por ejemplo, supongamos que tenía un archivo que tenía un promedio de incluso 1 bit distinto de cero por bloque de 512 bytes, no se puede escribir "escasamente". Por cierto, no perderá datos si comprime el archivo con zip, bzip, bzip2 o p7zip. No son como compresión mpeg o jpeg con pérdida.
Por otro lado, si necesita realizar lecturas de búsqueda aleatoria en el archivo, la compresión podría ser más problemática de lo que vale y volverá a la escritura dispersa. Un programador competente de C o C ++ debería poder escribir algo así en una hora o menos.
fuente
cp --sparse=always
funciona bien