Primeiro, verifique se o espaço livre está realmente vazio e não contém sobras de arquivos excluídos. A maneira mais fácil de conseguir isso é criar um arquivo enorme no disco, contendo apenas bytes nulos e, em seguida, excluí-lo.
# 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
Depois, compacte-o com uma ferramenta como gzip
ou xz
. Mesmo nos níveis mais baixos de compactação, uma série longa de zeros será bem compactada:
# ls -s
4096M foo.img
# gzip foo.img
# ls -s
11M foo.img.gz
Observe que você deve descompactar a imagem ao gravá-la no disco. Isso irá descompactá-lo 'ao vivo':
# cat foo.img.gz | gunzip | dd of=/dev/sda
Note que o dispositivo de saída (sda) deve ter tamanho suficiente para caber na imagem original , caso contrário os dados serão perdidos ou corrompidos.
Um método alternativo, se você quiser continuar usando a imagem - por exemplo, com uma máquina virtual - é converter a imagem bruta em um dos formatos de imagem usados pelo software de virtualização; por exemplo. qcow2 para Qemu, VDI para VirtualBox ou VMDK para VMware.
Note que isso ainda exige que você prepare a imagem limpando o espaço livre usando o método acima.
# qemu-img convert -f raw -O qcow2 foo.img foo.qcow
# qemu-img convert -f raw -O vmdk foo.img foo.vmdk
Mas se for gravada em um disco real novamente, será preciso convertê-lo novamente em uma imagem não processada.