Compactar HDs virtuais com EXT2/3/4

Tenho algumas máquinas virtuais do VirtualBox com o Fedora. À medida que mais dados são escritos no sistema de arquivos, mesmo que você apague-os, o tamanho do disco virtual (VDI/VMDK/VHD) não diminui quando é do tipo "dinamicamente alocado". Os blocos não mais usados precisam ser escritos com zeros para conseguirmos compactá-lo.

Faz falta uma ferramenta aos moldes do SDelete disponível para Windows, que permite zerar os blocos não usados com o sistema rodando. Hans Peter Anvin fez algum tempo atrás na lista de desenvolvimento do EXT4 um pedido para a adição de uma opção no e2fsck aque cuidasse disso (offline). Até agora nada surgiu.

Por enquanto usamos o zerofree. Instale-o dentro da máquina virtual:

# yum -y install zerofree

Ele requer que a partição na qual rodará esteja desmontada ou montada somente leitura. Minhas MVs têm apenas uma partição (sem swap).

Considerarei aqui que a partição a ser limpa é /dev/sda1.

No Fedora (e demais distribuições que usem o systemd), você tem duas opções. A primeira é reiniciar e temporariamente adicionar às opções de boot single (rescue.target), que é equivalente ao modo single user do SysVinit. Depois, remonte a partição raiz no modo somente leitura e rode o zerofree.

# mount -o remount,ro /
# zerofree -v /dev/sda1
# sync
# poweroff

Com o segundo método não é preciso reiniciar. No modo muiltiusuário, faça o systemd mudar para o rescue.target. Demais passos são os mesmos:

# systemctl isolate rescue.target
# mount -o remount,ro /
# zerofree -v /dev/sda1
# sync
# poweroff

Agora, com a MV desligada, faça o VirtualBox compactar o arquivo do HD virtual:

$ VBoxManage modifyhd "Fedora 16.vdi" --compact

Notas:

- Para verificar se a partição raiz está montada como somente leitura, use o findmnt:

# findmnt /
TARGET SOURCE    FSTYPE OPTIONS
/      /dev/sda1 ext4   ro,relatime,seclabel,data=ordered

- O sync não é obrigatório, mas não custa nada.
- No Windows, você terá que passar o caminho completo do VBoxManage, pois a pasta do VirtualBox não fica no PATH.
- Não funciona via SSH; o daemon não fica ativo no rescue.target.

Comentários