Questão Como compactar o tamanho do arquivo VDI do VirtualBox?


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!


269


origem




Respostas:


Você precisa seguir os seguintes passos:

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

    Com um Convidado Linux Rode 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 Guest do Windowsdownload SDelete da Sysinternals e execute isto:

    sdelete.exe c: -z
    

    (substitua C: pela letra da unidade do VDI)

  3. Desligar a VM guest

  4. Agora corra o VBoxManage's modifymedium comando com o --compact opção:

    Com um Host Linux Rode isto:

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

    Com um Host do Windows Rode isto:

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

    Com um Host Mac Rode isto:

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

Isso reduz o tamanho do vdi.


452



Para a próxima pessoa, meu comando acabou ficando assim: "C: \ Arquivos de Programas \ Oracle \ VirtualBox \ VBoxManage.exe" modifica "C: \ Usuários \ daniel \ VirtualBox VMs \ .... \ thedisk.vdi" - -compactar - Daniel
De acordo com o zerofree Linux utility manpage (manpages.ubuntu.com/manpages/natty/man8/zerofree.8.html), zerofree deve ser melhor do que dd para este trabalho. dd não seria recomendado porque "é lento", "faz com que a imagem de disco (temporariamente) cresça até sua extensão máxima", "(temporariamente) usa todo o espaço livre no disco, portanto outras ações de gravação simultâneas podem falhar". Zerofree está disponível no Ubuntu Linux via apt, ou você pode compilar você mesmo. - Dakatine
É divertido que o manpage de zerofree afirma que com dd outras gravações simultâneas falharão, mas o zerofree precisa que o sistema de arquivos seja montado somente para leitura! * duh * - Madarco
Dica: Coloque os dois comandos em uma linha como esta: dd ...; rm /bigfile, isso minimizará o tempo com um disco cheio, caso você não esteja esperando pelo dd completar. - jlh
@Dakatine Usando o VirtualBox 4.3.10, o arquivo de imagem de disco não crescer na sua extensão máxima. O VirtualBox é inteligente o suficiente para não incomodar a gravação de todos os blocos zero no disco físico. - jlh


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

34





Eu 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

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

editar

Bem, depois de tudo isso, eu tentei o Ferramenta CloneVDI e fez um bom trabalho em muito menos tempo e em um clique.


11



Você pensaria que neste tipo de site haveria algum tipo de destaque de sintaxe para o DOS, mas não. Parece muito mais bonito no Notepad ++ - CAD bloke
@CAD_bloke que exigiria um mecanismo de análise e quando você considera o número de diferentes idiomas postados no SE, você está olhando para um projeto ENORME. Basta pensar em quantas versões e dialetos do DOS existem, por exemplo, e isso antes mesmo de você chegar ao Linux, etc. - Caltor
Ponto muito bom. Ironicamente, é destacado no aplicativo iOS de troca de pilha. - CAD bloke
Sim CloneVDI é muito melhor e mais rápido para uso pessoal - VarunAgw


Convidado Debian no host do Windows usando discard / 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 um lista de sistemas de arquivos que suportam operações TRIM.

FDE e cryptoroot são especificamente não cobertos, pois há preocupações de segurança e nenhuma das outras soluções para essa questão permitiria compactação. 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 sem VMs 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. Nesse momento discard não está na GUI, mas nonrotational é 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: debian wiki, exemplo lvm.conf)

devices {
...
    issue_discards = 1
}

No fstab, adicione o discard opção para os sistemas de arquivos que você deseja descartar automaticamente (ref: debian wiki, fstab example)

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

Cortar manualmente 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 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. 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

5





Para MacOS Guest faça isso:

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

    diskutil secureErase freespace 0 "/Volumes/Macintosh HD"
    

    (substituir / Volumes / Macintosh HD com o nome da sua unidade)

  2. Desligar a VM guest

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

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

    OU

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

2





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
NOME MAJ: MIN RM TAMANHO RO TIPO MONTAGEM
sdb 8:16 0 128G 0 disco
17─sdb1 8:17 0 128G 0 part / mnt / web # ESTA É A PARTE DE INTERESSE!
sda 8: 0 0 64G 0 disco
8─sda1 8: 1 0 61,4G 0 part /
├─sda2 8: 2 0 1K 0 parte
└─sda5 8: 5 0 2,7G 0 parte
[SWAP] sr0 11: 0 1 56,30 MB 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





Eu não quero ativar o suporte TRIM no sistema operacional, porque cada exclusão de dados forçará a compactação de dados no arquivo VDI, tornando o sistema de 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 host.

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

Para fazer isso:

  • crie uma nova máquina virtual que inicialize com o Live CD do GParted (você pode usar sua distro favorita do Linux).
  • Editar configurações da máquina e definir o controlador de disco SATA
  • Adicionar arquivos VDI existentes que você deseja compactar
  • Altere os 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

  • começar a 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

1





Um truque muito bom para suplementar a resposta aceita é que você pode sair sem fazer qualquer compactação após 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 propriedades NTFS 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 de texto ou binários repetitivos (por exemplo, uma unidade de convidado de 30 GB que tinha 15 GB de espaço zerado pode se transformar em 4 GB na unidade host).

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


0