¿Cómo compactar el tamaño de archivo VDI de VirtualBox?


302

Tengo una VM VirtualBox que configuró un tamaño de disco duro muy grande (más grande que el host). Por mi error, un programa en la VM generó muchos archivos de registro y el tamaño del archivo VDI sigue creciendo hasta que no hay espacio en el host.

Ahora he eliminado los archivos de registro pero el tamaño del archivo VDI no se está reduciendo después de usar VBoxManage.exe modifyhd "C:\Virts\mybox-i386.vdi" compact

¿Hay alguna forma de compactar realmente el tamaño del archivo VDI? ¡Gracias!

Respuestas:


509

Tienes que hacer los siguientes pasos:

  1. Ejecute la desfragmentación en el invitado (solo Windows)
  2. Anular espacio libre:

    Con un invitado Linux, ejecute esto:

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

    O:

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

    Con un invitado de Windows , descargue SDelete de Sysinternals y ejecute esto:

    sdelete.exe c: -z
    

    (reemplace C: con la letra de unidad del VDI)

  3. Apague la máquina virtual invitada

  4. Ahora ejecute el modifymediumcomando VBoxManage con la --compactopción:

    Con un host Linux, ejecute esto:

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

    Con un host de Windows ejecute esto:

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

    Con un host Mac ejecute esto:

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

Esto reduce el tamaño de vdi.


16
Para la siguiente persona, mi comando terminó así: "C: \ Archivos de programa \ Oracle \ VirtualBox \ VBoxManage.exe" modifyhd "C: \ Users \ daniel \ VirtualBox VMs \ .... \ thedisk.vdi" - -compacto
Daniel

36
De acuerdo con la página de manual de la utilidad zerofree Linux ( manpages.ubuntu.com/manpages/natty/man8/zerofree.8.html ), zerofree debería ser mejor que dd para este trabajo. dd no se recomendaría porque "es lento", "hace que la imagen del disco (temporalmente) crezca al máximo", "usa (temporalmente) todo el espacio libre en el disco, por lo que otras acciones de escritura concurrentes pueden fallar". Zerofree está disponible en Ubuntu Linux a través de apt , o puede compilarlo usted mismo.
Dakatine

27
Es divertido que la página de manual de zerofree indique que con dd otras escrituras concurrentes fallarán, ¡pero zerofree necesita que el sistema de archivos se monte solo lectura! * duh *
Madarco

77
Consejo: coloque los dos comandos en una línea de la siguiente manera: dd ...; rm /bigfileesto minimizará el tiempo con un disco lleno en caso de que no esté esperando ddque se complete.
jlh

21
@Dakatine Usando VirtualBox 4.3.10, el archivo de imagen de disco no creció al máximo. VirtualBox es lo suficientemente inteligente como para no molestarse en escribir todos los bloques cero en el disco físico.
jlh

12

Estoy en un host de Windows 7 con invitados de Windows. Aquí hay un archivo por lotes que escribí para compactar todos los VDI en un árbol de carpetas

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

Dejé los enlaces en los comentarios para que pueda (más o menos) decir cómo funciona.

editar

Bueno, después de todo eso, probé la herramienta CloneVDI e hizo un buen trabajo en mucho menos tiempo y con un solo clic.


55
Pensarías que en este tipo de sitio habría algún tipo de resaltado de sintaxis para DOS, pero no. Se ve mucho más bonito en Notepad ++
CAD bloke

1
@CAD_bloke que requeriría un motor de análisis y cuando considera la cantidad de idiomas diferentes publicados en SE, está viendo un proyecto ENORME. Solo piense cuántas versiones y dialectos de DOS hay, por ejemplo, y eso incluso antes de llegar a Linux, etc.
Caltor

Muy buen punto. Irónicamente, se destaca en la aplicación iOS de intercambio de pila.
CAD bloke

2
Sí, CloneVDI es una forma mucho mejor y más rápida para uso personal
VarunAgw

6

Invitado de Debian en el host de Windows usando descartar / TRIM.

Esta no es una respuesta directa per se, ya que estoy abordando el problema, no la pregunta. En lugar de compactar periódicamente la imagen, esta solución utiliza el descarte para eliminar automáticamente los bloques no utilizados en la imagen del disco VM del host.

Esta solución requiere un sistema de archivos invitado que admita TRIM continuo. El wiki de Arch Linux tiene una lista de sistemas de archivos que admiten operaciones TRIM .

FDE y cryptoroot no están cubiertos específicamente, ya que existen problemas de seguridad y ninguna de las otras soluciones a esta pregunta permitiría la compactación. La wiki de Arch Linux tiene información sobre dispositivos TRIM y dm-crypt .

En teoría, esto funcionará para todos los invitados de Linux en hosts VBox que usan almacenamiento VDI.

Configuración del host

Con VBox salido y sin máquinas virtuales en ejecución, agregue soporte de descarte a sus discos configurando ambos discardy nonrotationalpara cada disco en el archivo de configuración para la máquina virtual. En este momento discardno está en la GUI, pero nonrotationalestá expuesto como la casilla de verificación "Unidad de estado sólido". (ref: foros de vbox, soporte de descarte )

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

Inicie la VM y verifique que el soporte TRIM esté habilitado:

sudo hdparm -I /dev/sda | grep TRIM

Configuración de invitado

Si LVM está en uso, cambie la configuración de descarte en /etc/lvm/lvm.conf. (ref: debian wiki, ejemplo lvm.conf )

devices {
...
    issue_discards = 1
}

En fstab, agregue la discardopción a los sistemas de archivos que desea descartar automáticamente (ref: debian wiki, ejemplo 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

Vuelva a montar los sistemas de archivos para que recojan sus nuevas opciones.

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

Recorte manualmente los bloques libres ahora con fstrim. fstrimusa el sistema de archivos montado, no el dispositivo de bloque que lo respalda. En lugar de configurar el descarte continuo fstab, esto podría hacerse en un cron semanal. (Se recomienda el cron semanal para los SSD físicos que pueden tener soporte cuestionable para TRIM, pero esto no es relevante aquí ya que los SSD subyacentes son manejados por el sistema operativo host. Ver: advertencia de recorte ssd ).

fstrim /
fstrim /build

En este punto, el tamaño de los sistemas de archivos dentro de la VM y el tamaño de las imágenes de la VM deberían tener un valor bastante cercano.

Probado con:

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

2

Para MacOS Guest, haga esto:

  1. Anular espacio libre en el sistema de invitado:

    diskutil secureErase freespace 0 "/Volumes/Macintosh HD"
    

    (reemplace / Volumes / Macintosh HD con el nombre de su unidad)

  2. Apague la máquina virtual invitada

  3. Ejecute este comando para reducir el tamaño de la imagen del disco VDI

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

    O

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

1

Lo uso para mi imagen VDI montada en Debian virtual en Windows VirtualBox. No es una solución general, pero al menos debería darte una idea de lo que hago.

Comandos en Debian:

root@debian:~# lsblk  # show partitions
NOMBRE MAJ: MIN RM TAMAÑO RO TIPO MOUNTPOINT 
SDB 8:16 0 128G 0 disco 
└─sdb1 8:17 0 128G 0 part / mnt / web # ¡ESTA ES LA PARTICIÓN DE INTERÉS!
sda 8: 0 0 64G 0 disco 
Dasda1 8: 1 0 61,4G 0 parte / 
Dasda2 8: 2 0 1K 0 parte 
Dasda5 8: 5 0 2,7G 0 parte 
[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 en Windows:

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

Espero eso ayude :)


1

No quiero habilitar el soporte TRIM en el sistema operativo, porque cada eliminación de datos forzará la compactación de datos en el archivo VDI, haciendo que el sistema invitado sea inutilizable cuando el archivo VDI esté en un disco rotativo clásico. Para mí es mejor realizar la compactación a mano, por ejemplo, una vez al mes.

Durante la compactación normal, el contenido del archivo VDI se copia en un archivo nuevo. Esto requiere un espacio libre (a veces grande) en el disco host.

Tengo una solución similar a la señalada por Andrew Domaszek. Funciona muy bien incluso con NTFS (Windows10).

Para hacer esto:

  • cree una nueva máquina virtual que arranque con GParted Live CD (puede usar su distribución de Linux favorita).
  • Edite la configuración de la máquina y configure el controlador de disco SATA
  • Agregue archivos VDI existentes que desea compactar
  • Cambie los discos basados ​​en VDI para que sean visibles como SSD con soporte 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
    
  • máquina de arranque

  • En el shell raíz de Linux, monte la partición NTFS mount /dev/sda2 /mnt
  • cero espacio libre dd if=/dev/zero of=/mnt/bigfile
  • rm /mnt/bigfile
  • forzar la compactación de VDI sin crear un nuevo archivo: fstrim -v /mnt

0

Un truco muy bueno para complementar la respuesta aceptada es que puede escapar sin hacer ninguna compactación después de poner a cero el espacio de invitado, utilizando un sistema de archivos comprimido en el host (por ejemplo, seleccionando comprimir la carpeta de unidades virtuales en las propiedades NTFS en un Host de Windows). De hecho, esto tiene el beneficio de ahorrar mucho más espacio porque los sistemas operativos tienden a contener una gran cantidad de texto repetitivo o archivos binarios (por ejemplo, una unidad de invitado de 30 GB que tenía 15 GB de espacio a cero puede convertirse en 4 GB en la unidad host).

Las advertencias incluyen que el acceso a la unidad en el hardware real puede aumentar y hay un ligero aumento en el uso de la CPU.


0

NOTA IMPORTANTE PARA LEGADO (~ 1997-2007) SISTEMAS OPERATIVOS

En general, las técnicas en las respuestas dadas anteriormente son válidas; SIN EMBARGO, hay un caso especial muy importante.

Durante un período de algunos años, quizás 1997-2007 más o menos, los sistemas operativos de 32 bits seguían siendo la norma, pero los discos duros de más de 2 GB ya estaban en uso. Como resultado, cuando intente consumir todo el espacio libre escribiendo un archivo de ceros (que siempre debe hacerse como root, para incluir el espacio libre privilegiado de root, que nadie más puede tocar), puede ver:

Archivo demasiado grande

en lugar de lo que esperas:

No queda espacio en el dispositivo.

Si esto ocurre, lo más probable es que haya alcanzado una limitación de tamaño de archivo de 2GB. Esto era común en ese momento porque muchas operaciones de archivos arrojaban resultados en enteros de 32 bits con signo, de modo que los valores negativos podían informar códigos de error. Esto efectivamente significó que los resultados de compensación se limitaron a 2 ^ 31 bytes sin medidas especiales.

La solución es sencilla: siga creando archivos de puesta a cero separados y con nombres diferentes hasta que el disco realmente se quede sin espacio.

Si usted es un instructor que desea demostrar esta situación para una clase, una imagen de disco de 4GB con una copia antigua de Red Hat Linux 7.0 es suficiente.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.