Como compactar o tamanho do arquivo VDI do VirtualBox?


301

Eu tenho uma VM VirtualBox que configurou um tamanho de disco rígido muito grande (maior que o host). Por engano, um programa na VM gerou muitos arquivos de log e o tamanho do arquivo VDI continua crescendo até que não haja espaço no host.

Agora eu apaguei os arquivos de log, mas o tamanho do arquivo VDI não está diminuindo depois de usar VBoxManage.exe modifyhd "C:\Virts\mybox-i386.vdi" compact

Existe uma maneira de realmente compactar o tamanho do arquivo VDI? Obrigado!

Respostas:


507

Você precisa executar as seguintes etapas:

  1. Execute a desfragmentação no convidado (somente Windows)
  2. Anular espaço livre:

    Com um convidado Linux, execute o seguinte:

    dd if=/dev/zero of=/var/tmp/bigemptyfile bs=4096k ; rm /var/tmp/bigemptyfile
    

    Ou:

    telinit 1
    mount -o remount,ro /dev/sda1
    zerofree -v /dev/sda1
    

    Com um Windows Guest , baixe o SDelete da Sysinternals e execute:

    sdelete.exe c: -z
    

    (substitua C: pela letra da unidade do VDI)

  3. Encerrar a VM convidada

  4. Agora execute o modifymediumcomando do VBoxManage com a --compactopção:

    Com um host Linux, execute o seguinte:

    vboxmanage modifymedium --compact /path/to/thedisk.vdi
    

    Com um host do Windows, execute o seguinte:

    VBoxManage.exe modifymedium --compact c:\path\to\thedisk.vdi
    

    Com um host Mac, execute o seguinte:

    VBoxManage modifymedium --compact /path/to/thedisk.vdi
    

Isso reduz o tamanho do vdi.


15
Para a próxima pessoa, meu comando acabou assim: "C: \ Arquivos de programas \ Oracle \ VirtualBox \ VBoxManage.exe" modifyhd "C: \ Usuários \ daniel \ VMs VirtualBox \ .... \ thedisk.vdi" - -Compact
Daniel

36
De acordo com a página de manual do zerofree Linux ( manpages.ubuntu.com/manpages/natty/man8/zerofree.8.html ), o zerofree deve ser melhor que o dd para este trabalho. dd não seria recomendado porque "é lento", "faz com que a imagem do disco (temporariamente) cresça na sua extensão máxima", "ele (temporariamente) usa todo o espaço livre no disco, portanto outras ações de gravação simultâneas podem falhar". O Zerofree está disponível no Ubuntu Linux via apt , ou você pode compilá-lo.
Dakatine

27
É divertido que a página de manual do zerofree declare que, com o dd, outras gravações simultâneas falharão, mas o zerofree precisa que o sistema de arquivos seja montado como somente leitura! * duh *
Madarco 25/02

7
Dica: Coloque os dois comandos em uma linha da seguinte forma: dd ...; rm /bigfileisso minimizará o tempo com um disco cheio, caso você não esteja esperando dda conclusão.
jlh

21
@ Dakatine Usando o VirtualBox 4.3.10, o arquivo de imagem de disco não cresceu na sua extensão máxima. O VirtualBox é inteligente o suficiente para não se preocupar em gravar todos os zero blocos no disco físico.
jlh

12

Estou em um host do Windows 7 com convidados do Windows. Aqui está um arquivo em lotes que escrevi para compactar todos os VDIs em uma árvore de pastas

echo off
mode con:cols=140 lines=200
cls
:: see https://forums.virtualbox.org/viewtopic.php?p=29272#p29272
:: How can I reduce the size of a dynamic VDI on disk?
:: but that page says to use sdelete -s which is suboptimal. 
:: use -z as per http://technet.microsoft.com/en-us/sysinternals/bb897443.aspx

:: First run the sdelete -z c: inside the VMs that zero-out all the free space
:: THEN run this batch file 

Title Compacting Free space on Virtual Machine VMs

:: http://ss64.com/nt/for_r.html
:: http://stackoverflow.com/questions/8836368/windows-batch-file-how-to-loop-through-files-in-a-directory/8836401#8836401

Setlocal EnableDelayedExpansion
:: http://ss64.com/nt/delayedexpansion.html ... 
:: Notice that within the for loop we use !variable! instead of %variable%.

For /R %CD% %%G IN (*.vdi) DO (
 set ohai=%%G
 set lastfive=!ohai:~-5!
:: Skip snapshots which are named {guid}.vdi
 if NOT !lastfive!==}.vdi (
 echo .
 echo Compacting %%G
 "C:\Program Files\Oracle\VirtualBox\VboxManage.exe" modifyhd "%%G" --compact )
 )

pause 
exit

Deixei os links nos comentários para que você possa (mais ou menos) dizer como funciona.

editar

Bem, depois de tudo isso, tentei a ferramenta CloneVDI e ela fez um bom trabalho em muito menos tempo e com apenas um clique.


5
Você pensaria que nesse tipo de site haveria algum tipo de sintaxe destacada para o DOS, mas não. Parece muito mais bonito no Notepad ++
CAD bloke

1
@CAD_bloke que exigiria um mecanismo de análise e quando você considera o número de idiomas diferentes publicados no SE, está vendo um projeto ENORME. Basta pensar quantas versões e dialetos do DOS existem, por exemplo, e isso antes mesmo de chegar ao Linux etc.
Caltor

Muito bom ponto. Ironicamente, ele é destacado no aplicativo iOS de troca de pilhas.
CAD bloke

2
Sim CloneVDI é muito melhor e muito mais rápido para uso pessoal
VarunAgw

6

Convidado Debian no host do Windows usando descarte / TRIM.

Esta não é uma resposta direta, pois estou abordando o problema, não a pergunta. Em vez de compactar periodicamente a imagem, essa solução usa o descarte para remover automaticamente blocos não utilizados na imagem de disco da VM do host.

Esta solução requer um sistema de arquivos convidado que suporte o TRIM contínuo. O wiki do Arch Linux possui uma lista de sistemas de arquivos que suportam operações TRIM .

O FDE e o cryptoroot especificamente não são cobertos, pois existem preocupações com a segurança e nenhuma das outras soluções para essa pergunta permitiria a compactação. O wiki do Arch Linux possui informações sobre dispositivos TRIM e dm-crypt .

Em teoria, isso funcionará para todos os convidados do Linux nos hosts VBox usando armazenamento VDI.

Configuração do host

Com o VBox encerrado e sem VMs em execução, adicione suporte de descarte aos discos, definindo ambos discarde nonrotationalpara cada disco no arquivo de configuração da VM. No momento, discardnão está na GUI, mas nonrotationalé exposto como a caixa de seleção "Solid-state Drive". (ref: fóruns vbox, suporte para descarte )

<AttachedDevice discard="true" nonrotational="true" type="HardDisk" [..other options..] >

Inicialize a VM e verifique se o suporte ao TRIM está ativado:

sudo hdparm -I /dev/sda | grep TRIM

Configuração do convidado

Se o LVM estiver em uso, altere a configuração de descarte em /etc/lvm/lvm.conf. (ref: wiki debian, exemplo lvm.conf )

devices {
...
    issue_discards = 1
}

No fstab, adicione a discardopção aos sistemas de arquivos que você deseja descartar automaticamente (ref: debian wiki, exemplo do fstab )

UUID=8db6787f-1e82-42d8-b39f-8b7491a0523c   /   ext4    discard,errors=remount-ro   0   1
UUID=70bfca92-8454-4777-9d87-a7face32b7e7   /build  ext4    discard,errors=remount-ro,noatime   0   1

Remonte os sistemas de arquivos para que eles escolham suas novas opções.

sudo mount -o remount /
sudo mount -o remount /build

Corte manualmente blocos livres agora com fstrim. fstrimusa o sistema de arquivos montado, não o dispositivo de bloco que o suporta. Em vez de definir o descarte contínuo fstab, isso pode ser feito em um cron semanal. (O cron semanalmente é recomendado para SSDs físicas que podem ter suporte questionável para TRIM, mas isso não é relevante aqui desde SSDs subjacentes são tratados pelo sistema operacional hospedeiro ver:. Aviso guarnição ssd ).

fstrim /
fstrim /build

Nesse ponto, o tamanho dos sistemas de arquivos dentro da VM e o tamanho das imagens da VM devem ter um valor bastante próximo.

Testado com:

  • Convidado1: Debian 8.7, kernel: linux 4.8 grsec de backports, sistema de arquivos: ext4
  • Guest2: Debian 9 RC2, kernel: linux 4.9, sistema de arquivos: ext4
  • Host1: VBox 5.1.14, Win7, imagem fmt: VDI
  • Host2: VBox 5.1.14, Win8.1, imagem fmt: VDI

2

Para o MacOS Guest, faça o seguinte:

  1. Anular espaço livre no sistema convidado:

    diskutil secureErase freespace 0 "/Volumes/Macintosh HD"
    

    (substitua / Volumes / Macintosh HD pelo nome da sua unidade)

  2. Encerrar a VM convidada

  3. Execute este comando para reduzir o tamanho da imagem do disco VDI

    VBoxManage modifyhd /path/to/thedisk.vdi --compact
    

    OU

    VBoxManage modifymedium /path/to/thedisk.vdi --compact
    

1

Eu uso isso para minha imagem VDI montada no Debian virtual no Windows VirtualBox. Não é uma solução geral, mas deve, pelo menos, dar uma idéia do que faço.

Comandos no Debian:

root@debian:~# lsblk  # show partitions
NOME MAJ: TAMANHO MÍN. RM RO TIPO DE MONTAGEM 
sdb 8:16 0 128G 0 disco 
8:─sdb1 8:17 0 128G 0 parte / mnt / web # ESTA É A PARTIÇÃO DE INTERESSE!
sda 8: 0 0 64G 0 disco 
├─sda1 8: 1 0 61,4G 0 parte / 
├─sda2 8: 2 0 1K 0 partes 
└─sda5 8: 5 0 2,7G 0 parte 
11: 0 1 56,3M 0 rom
root@debian:~# service mysql stop  # terminate all operations with partition
root@debian:~# service apache2 stop  # terminate all operations with partition
root@debian:~# umount /mnt/web  # unplug partition
root@debian:~# apt-get install zerofree  # install tool for filling in zeros to empty space
root@debian:~# zerofree -v /dev/sdb1  # fill with zeros
root@debian:~# poweroff  # shut down machine

Comandos no Windows:

C:\Program Files\Oracle\VirtualBox>VBoxManage.exe modifyhd --compact "D:\VirtualBox VMs\web.vdi"  # convert zeros to empty space

Espero que ajude :)


1

Não quero habilitar o suporte TRIM no SO, porque cada exclusão de dados forçará a compactação de dados no arquivo VDI, tornando o sistema convidado inutilizável quando o arquivo VDI estiver no disco rotativo clássico. Para mim, melhor é fazer a compactação manualmente, por exemplo, uma vez por mês.

Durante a compactação normal, o conteúdo do arquivo VDI é copiado para o novo arquivo. Isso requer algum espaço livre (às vezes grande) no disco host.

Eu tenho uma solução semelhante à apontada por Andrew Domaszek. Funciona muito bem mesmo com NTFS (Windows10).

Para fazer isso:

  • crie uma nova máquina virtual que inicialize com o GParted Live CD (você pode usar sua distribuição Linux favorita).
  • Edite as configurações da máquina e defina o controlador de disco SATA
  • Adicione arquivos VDI existentes que você deseja compactar
  • Altere os discos baseados em VDI para ficarem visíveis como SSD com suporte a TRIM:

    VBoxManage storageattach "gpared live" --storagectl "SATA" --port 0 --discard on --nonrotational on
    VBoxManage storageattach "gpared live" --storagectl "SATA" --port 1 --discard on --nonrotational on
    
  • iniciar máquina

  • No shell raiz do Linux, monte a partição NTFS mount /dev/sda2 /mnt
  • zero espaço livre dd if=/dev/zero of=/mnt/bigfile
  • rm /mnt/bigfile
  • forçar a compactação de VDI sem criar novo arquivo: fstrim -v /mnt

0

Um truque muito interessante para complementar a resposta aceita é que você pode fugir sem fazer nenhuma compactação depois de zerar o espaço do convidado, usando um sistema de arquivos compactado no host (por exemplo, selecionando compactar a pasta de unidades virtuais nas propriedades NTFS em um Host do Windows). Na verdade, isso tem o benefício de economizar muito mais espaço, porque os sistemas operacionais tendem a armazenar muitos arquivos repetitivos de texto ou binários (por exemplo, uma unidade de convidado de 30 GB com 15 GB de espaço zerado pode virar 4 GB na unidade host).

Advertências incluem que o acesso à unidade no hardware real pode aumentar e há um ligeiro aumento no uso da CPU.


0

NOTA IMPORTANTE PARA SISTEMAS OPERACIONAIS LEGADOS (~ 1997-2007)

Em geral, as técnicas nas respostas dadas anteriormente são válidas; No entanto, existe um caso especial muito importante.

Por um período de alguns anos - talvez entre 1997 e 2007 - sistemas operacionais de 32 bits ainda eram a norma, mas discos rígidos maiores que 2 GB já estavam em uso. Como resultado, ao tentar consumir todo o espaço livre escrevendo um arquivo de zeros (que sempre deve ser feito como root, para incluir o espaço livre privilegiado do root, no qual ninguém mais pode tocar), você pode ver:

Arquivo muito grande

em vez do que você espera:

Não há espaço no dispositivo.

Se isso ocorrer, é provável que você tenha atingido uma limitação de tamanho de arquivo de 2 GB. Isso era comum na época, porque muitas operações de arquivo retornavam resultados em números inteiros de 32 bits, para que valores negativos pudessem relatar códigos de erro. Isso significava efetivamente que os resultados do deslocamento eram limitados a 2 ^ 31 bytes sem medidas especiais.

A solução alternativa é simples: continue criando arquivos de zeros separados e com nomes diferentes até o disco ficar sem espaço.

Se você é um instrutor que deseja demonstrar essa situação para uma aula, uma imagem de disco de 4 GB com uma cópia antiga do Red Hat Linux 7.0 é suficiente.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.