2013-01-07 03:41:45 +0000 2013-01-07 03:41:45 +0000
307
307

Como compactar o tamanho do ficheiro VDI da VirtualBox?

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

Agora apaguei os ficheiros de log mas o tamanho do ficheiro VDI não está a ficar mais pequeno depois de utilizar o VBoxManage.exe modifyhd "C:\Virts\mybox-i386.vdi" compact

Existe alguma forma de compactar realmente o tamanho do ficheiro VDI? Obrigado!

Respostas (8)

520
520
520
2013-01-07 05:05:34 +0000

Tem de fazer os seguintes passos:

  1. Executar defrag in the guest (apenas Windows)
  2. Nullify free space:

  3. Desligar o VM convidado

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

Isto reduz o tamanho do vdi.

12
12
12
2015-01-09 10:25:08 +0000

Estou num anfitrião Windows 7 com convidados Windows, Aqui está um ficheiro batch que escrevi para Compactar todas as VDIs numa á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 possa (mais ou menos) dizer como funciona.

editar

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

7
7
7
2017-02-24 16:27:40 +0000

Debian guest on Windows host using discard/TRIM.

Esta não é uma resposta directa em si, pois estou a abordar o problema, não a questão. Em vez de compactar periodicamente a imagem, esta solução utiliza o descarte para remover automaticamente os blocos não utilizados na imagem de disco VM do host.

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

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

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

Configuração do host

Com a VBox encerrada e sem VMs em execução, adicione suporte de descarte aos seus discos configurando ambos discard e nonrotational para cada disco no ficheiro de configuração para a VM. Neste momento o discard não está na GUI, mas o nonrotational está exposto como a caixa de verificação “Solid-state Drive”. (ref: fóruns vbox, suporte de descarte )

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

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

sudo hdparm -I /dev/sda | grep TRIM

Guest Configuration

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

devices {
...
    issue_discards = 1
}

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

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 peguem suas novas opções.

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

Aparar manualmente blocos livres agora com fstrim. fstrim usa o sistema de arquivos montado, não o dispositivo de blocos que o suporta. Em vez de definir o descarte contínuo em fstab, isto poderia ser feito num cron semanal. (O cron semanal é recomendado para SSDs físicos que podem ter suporte questionável para o TRIM, mas isto não é relevante aqui, uma vez que os SSDs subjacentes são tratados pelo sistema operativo anfitrião. ver:

fstrim /
fstrim /build

Neste ponto, o tamanho dos sistemas de ficheiros dentro da VM e o tamanho das imagens da VM devem estar bastante próximos do valor.

Testado com:

  • Guest1: Debian 8.7, kernel: linux 4.8 grsec de backports, sistema de ficheiros: ext4
  • Guest2: Debian 9 RC2, kernel: linux 4.9, sistema de ficheiros: ext4
  • Host1: VBox 5.1.14, Win7, imagem fmt: VDI
  • Host2: VBox 5.1.14, Win8.1, imagem fmt: VDI
2
2
2
2016-12-16 17:08:31 +0000

Para MacOS Guest* faça o seguinte:

  1. Nullify free space in guest system:

  2. Desligue o VM convidado:

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

1
1
1
2016-02-05 11:31:32 +0000

Eu uso isto para a minha imagem VDI montada em Debian virtual no Windows VirtualBox. Não é uma solução geral, mas deve pelo menos dar-lhe uma ideia geral do que faço.

Comandos em 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 em Windows:

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

Espero que ajude :)

1
1
1
2017-09-15 07:17:05 +0000

Não quero activar o suporte TRIM no SO, porque cada eliminação de dados forçará a compactação de dados no ficheiro VDI, tornando o sistema convidado inutilizável quando o ficheiro VDI está no disco rotativo clássico. Para mim é melhor realizar a compactação à mão, por exemplo, uma vez por mês.

Durante a compactação normal, o conteúdo do ficheiro VDI é copiado para um novo ficheiro. Isto requer algum (por vezes grande) espaço livre no disco anfitrião.

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

Para fazer isto:

  • crie uma nova máquina virtual que arranca com GParted Live CD (pode usar a sua distro Linux favorita).
  • editar definições da máquina e definir controlador de disco SATA
  • adicionar ficheiros VDI existentes que pretende compactar
  • alterar discos baseados em VDI para serem visíveis como SSD com suporte de TRIM:

  • iniciar máquina

  • em shell raiz Linux, montar 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 ficheiro: fstrim -v /mnt

0
0
0
2019-08-17 06:07:39 +0000

NOTA IMPORTANTE PARA OS SISTEMAS OPERACIONAIS LEGAIS (~1997-2007)

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

Durante um período de alguns anos - talvez 1997-2007 ou assim - os sistemas operativos de 32 bits ainda eram a norma, mas os discos rígidos com mais de 2GB já estavam em uso. Como resultado, ao tentar consumir todo o espaço livre escrevendo um ficheiro de zeros (que deve ser sempre feito como raiz, para incluir o espaço livre privilegiado da raiz, que ninguém mais pode tocar), pode ver:

Arquivo demasiado grande

em vez do que se espera:

Sem espaço no dispositivo.

Se isto ocorrer, é muito provável que tenha atingido uma limitação de tamanho de ficheiro de 2GB. Isto era comum na altura porque muitas operações de arquivo retornaram resultados em inteiros de 32 bits assinados, de modo que valores negativos poderiam reportar códigos de erro. Isto efectivamente significava que os resultados de compensação estavam limitados a 2^31 bytes sem medidas especiais.

A solução é simples: continue a criar ficheiros de zeragem separados, com nomes diferentes até o disco ficar sem espaço.

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

0
0
0
2018-01-20 07:13:01 +0000

Um truque muito simples para complementar a resposta aceita é que você pode escapar sem fazer nenhuma compactação após zerar o espaço do convidado, usando um sistema de arquivo comprimido no host (por exemplo, selecionando para comprimir a pasta das unidades virtuais nas propriedades NTFS em um host Windows). Isto de facto tem a vantagem de poupar muito mais espaço porque os sistemas operativos tendem a guardar muitos ficheiros repetitivos de texto ou binários (por exemplo, uma unidade convidada de 30GB que tinha 15GB de espaço zerado pode passar para 4GB na unidade anfitriã).

Caveats incluem que o acesso à unidade no hardware real pode aumentar e há um ligeiro aumento na utilização do CPU.