Como compactar o tamanho do arquivo VDI do VirtualBox?

279

Eu tenho uma VM VirtualBox que configurou um tamanho de disco rígido muito grande (maior que o host). Por meu erro, 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 deletei 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!

    
por DeepNightTwo 07.01.2013 / 04:41

8 respostas

469

Você precisa seguir os seguintes passos:

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

    Com um Linux Guest , execute isto:

    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 , faça o download SDelete da Sysinternals e execute isto:

    sdelete.exe c: -z
    

    (substitua C: pela letra de unidade do VDI)

  3. Desligue a VM convidada

  4. Agora, execute o comando modifymedium do VBoxManage com a opção --compact :

    Com um host Linux , execute:

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

    Com um Windows Host , execute isto:

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

    Com um Mac Host , execute isto:

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

Isso reduz o tamanho do vdi.

    
por 07.01.2013 / 06:05
35

Se a execução do comando na resposta aceita produzir uma mensagem de erro inútil como esta

VBoxManage.exe: error: Cannot register the hard disk 'thedisk.vdi'
{aaaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeeee} because a hard disk 'thedisk.vdi'
with UUID {aaaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeeee} already exists

Basta executar o comando pelo UUID em vez do nome do arquivo:

VBoxManage.exe modifyhd {aaaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeeee} --compact
    
por 18.06.2014 / 09:20
11

Estou em um host do Windows 7 com convidados do Windows. Aqui está um arquivo em lote 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

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

editar

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

    
por 09.01.2015 / 11:25
5

Convidado Debian no host do Windows usando o descarte / TRIM.

Esta não é uma resposta direta em si, já que estou abordando o problema, não a questão. Em vez de compactar periodicamente a imagem, essa solução usa o descarte para remover automaticamente os blocos não utilizados da imagem de disco da VM do host.

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

FDE e cryptoroot não são especificamente abordados, pois há preocupações de segurança e nenhuma das outras soluções para essa questão permitiria a compactação também. O wiki do Arch Linux tem informações sobre dispositivos TRIM e dm-crypt .

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

Configuração do host

Com o VBox encerrado e nenhuma VM em execução, adicione o suporte ao descarte aos seus discos definindo discard e nonrotational para cada disco no arquivo de configuração da VM. No momento, discard não está na GUI, mas nonrotational está exposto como a caixa de seleção "Solid State Drive". (ref: fóruns do vbox, descarte o suporte )

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

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

sudo hdparm -I /dev/sda | grep TRIM

Configuração de convidado

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

devices {
...
    issue_discards = 1
}

Em fstab, adicione a opção discard aos sistemas de arquivos que você deseja descartar automaticamente (ref: debian wiki exemplo de 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

Ajuste manualmente os blocos livres agora com fstrim . fstrim usa o sistema de arquivos montado, não o dispositivo de bloco que o suporta. Em vez de definir o descarte contínuo em fstab , isso poderia ser feito em um cron semanal. (O cron semanal é recomendado para SSDs físicos que podem ter suporte questionável para TRIM, mas isso não é relevante aqui, pois os SSDs subjacentes são manipulados pelo sistema operacional host. Consulte: aviso de corte ssd ).

fstrim /
fstrim /build

Neste ponto, o tamanho dos sistemas de arquivos dentro da VM e o tamanho das imagens da VM devem ser muito próximos em valor.

Testado com:

  • Guest1: 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
por 24.02.2017 / 17:27
2

Para o MacOS Guest faça o seguinte:

  1. Anular o espaço livre no sistema convidado:

    diskutil secureErase freespace 0 "/Volumes/Macintosh HD"
    

    (substitua / Volumes / Macintosh HD com o nome do seu drive)

  2. Desligue a VM convidada

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

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

    OR

    VBoxManage modifymedium /path/to/thedisk.vdi --compact
    
por 16.12.2016 / 18:08
1

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

Comandos no Debian:

root@debian:~# lsblk  # show partitions
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT 
sdb 8:16 0 128G 0 disk 
└─sdb1 8:17 0 128G 0 part /mnt/web  # THIS IS THE PARTITION OF INTEREST!
sda 8:0 0 64G 0 disk 
├─sda1 8:1 0 61,4G 0 part / 
├─sda2 8:2 0 1K 0 part 
└─sda5 8:5 0 2,7G 0 part 
[SWAP] sr0 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:)

    
por 05.02.2016 / 12:31
1

Eu não quero ativar o suporte ao TRIM no sistema operacional, 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 em um disco rotacional clássico. Para mim, é melhor realizar compactação manual, por ex. 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 do host.

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

Para fazer isso:

  • crie uma nova máquina virtual que inicializa com o Live CD do GParted (você pode usar sua distro favorita do Linux).
  • Edite as configurações da máquina e defina o controlador de disco SATA
  • Adicione arquivos VDI existentes que você deseja compactar
  • Alterar discos baseados em VDI para serem 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ça a compactação de VDI sem criar novo arquivo: fstrim -v /mnt
por 15.09.2017 / 09:17
0

Um truque muito bom para suplementar a resposta aceita é que você pode sair sem compactar depois de zerar o espaço do convidado, usando um sistema de arquivos compactado no host (por exemplo, selecionando para compactar a pasta de unidades virtuais em NTFS propriedades em um host do Windows). Isso de fato tem o benefício de economizar muito mais espaço porque os sistemas operacionais tendem a conter muitos arquivos repetitivos de texto ou binários (por exemplo, uma unidade de convidado de 30GB que tinha 15GB de espaço zerado pode se transformar em 4GB na unidade host). p>

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

    
por 20.01.2018 / 08:13