qcow2 funciona de uma maneira que só cresce, mas na verdade é bastante compreensível. Depois que o sistema operacional guest solicita uma gravação em um bloco não alocado anteriormente (não alocado pela VM no arquivo qcow2), a VM aloca algum espaço no sistema de arquivos host e a utiliza para armazenar informações para o convidado. Quando o sistema operacional guest remove o arquivo, ele não informa à VM que não precisa mais do bloco. E mesmo que isso acontecesse, você deve se lembrar que, por motivos de desempenho, os blocos são alocados em grupos - ou seja, se o sistema operacional guest solicitar 10 blocos de 512B, geralmente um espaço muito maior será alocado; veja a opção cluster_size
na página qemu-img(1)
man. Isso significa que, quando um bloco adjacente é gravado, ele já está alocado. Agora considere o caso, quando o convidado escreve dois arquivos no mesmo "cluster". Ambos teriam que ser removidos para recuperar o espaço no arquivo de imagem da VM.
Dito isso, há uma maneira de recuperar o espaço, embora eu não tenha certeza de que pode ser enquanto uma VM está sendo executada a partir da imagem. O procedimento é:
Na VM
- remova o que você não quer mais
- desfragmentar o sistema de arquivos
-
preenche o espaço livre com zeros, por ex. com
dd if=/dev/zero of=/tmp/zeros
-
Certifique-se de que os zeros sejam enviados para o disco (virtual) (isto é, não armazenados em cache pelo sistema operacional convidado) - eles devem aparecer na imagem da VM
- remova o arquivo criado
- encerre o sistema (pode não ser necessário)
Em seguida, reembale a imagem da VM no sistema host usando qemu-img convert
(de qcow2 para qcow2) no sistema host. Você pode usar a opção -S
para especificar o tamanho de um bloco zerado a ser considerado para otimização usando o arquivo esparso. Preste atenção também na opção -o preallocation=off
convert para evitar a criação de arquivos em tamanho real no início.
Isso obviamente significa que em algum momento você precisará de algo acima (tamanho máximo da imagem) + (tamanho real da imagem) de espaço livre no host. Por outro lado, é provavelmente a única maneira de garantir a compactação máxima da imagem final.
Você também pode tentar zerar cada arquivo que deseja remover antes de realmente removê-lo, por exemplo, com shred -n 0 -z
. No entanto, você não poderá recuperar tanto espaço quanto no caso de disco inteiro.
Além disso, em alguns sistemas de arquivos, isso pode não ter a saída desejada. Por exemplo, com o btrfs você está condenado de qualquer forma, já que tem sua própria camada de cópia na gravação - a menos que você o desative no guest (e não tenho certeza se é possível, já que muitos dos recursos desse sistema de arquivos dependem dele ), você está sem sorte.