Comment compacter la taille du fichier VDI de VirtualBox?


302

J'ai une machine virtuelle VirtualBox qui a configuré une très grande taille de disque dur (plus grande que l'hôte). Par erreur, un programme sur la machine virtuelle a généré de nombreux fichiers journaux et la taille du fichier VDI ne cesse de croître jusqu'à ce qu'il n'y ait plus d'espace disponible sur l'hôte.

Maintenant, j'ai supprimé les fichiers journaux, mais la taille du fichier VDI ne devient pas plus petite après avoir utilisé VBoxManage.exe modifyhd "C:\Virts\mybox-i386.vdi" compact

Existe-t-il un moyen de compacter réellement la taille du fichier VDI? Merci!

Réponses:


508

Vous devez suivre les étapes suivantes:

  1. Exécuter defrag dans l'invité (Windows uniquement)
  2. Nullify free space:

    Avec un invité Linux, lancez ceci:

    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
    

    Avec un invité Windows , téléchargez SDelete à partir de Sysinternals et lancez ceci:

    sdelete.exe c: -z
    

    (remplacez C: par la lettre de lecteur du VDI)

  3. Arrêtez la machine virtuelle invitée

  4. Maintenant, lancez la modifymediumcommande de VBoxManage avec l' --compactoption:

    Avec un hôte Linux, lancez ceci:

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

    Avec un hôte Windows, lancez ceci:

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

    Avec un hôte Mac, lancez ceci:

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

Cela réduit la taille de vdi.


16
Pour la personne suivante, ma commande ressemblait à ceci: "C: \ Program Files \ Oracle \ VirtualBox \ VBoxManage.exe" modifyhd "C: \ Utilisateurs \ daniel \ VirtualBox VMs \ .... \ thedisk.vdi" - -compact
Daniel

36
Selon la page de manuel de l' utilitaire zerofree Linux ( manpages.ubuntu.com/manpages/natty/man8/zerofree.8.html ), zerofree devrait être meilleur que dd pour ce travail. dd ne serait pas recommandé car "il est lent", "il agrandit (temporairement) l'image du disque au maximum", "il utilise (temporairement) tout l'espace disponible sur le disque, de sorte que d'autres actions d'écriture simultanées risquent d'échouer". Zerofree est disponible sur Ubuntu Linux via apt , ou vous pouvez le compiler vous-même.
Dakatine

27
Il est amusant que la page de manuel de zerofree indique qu'avec dd, les autres écritures simultanées échouent, mais zerofree nécessite que le système de fichiers soit monté en lecture seule! * duh *
Madarco

7
Conseil: Mettez les deux commandes sur une seule ligne, comme dd ...; rm /bigfilececi:, cela minimisera la durée avec un disque plein au cas où vous n'attendriez pas la ddfin de l'opération.
14h14

21
@ Dakatine Avec VirtualBox 4.3.10, le fichier d’image disque n’a pas atteint sa taille maximale. VirtualBox est suffisamment intelligent pour ne pas écrire les blocs zéro sur le disque physique.
14h14

12

Je suis sur un hôte Windows 7 avec des invités Windows. Voici un fichier de commandes que j'ai écrit pour Compacter tous les VDI dans une arborescence de dossiers.

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

J'ai laissé les liens dans les commentaires afin que vous puissiez (en quelque sorte) dire comment cela fonctionne.

modifier

Après tout cela, j’ai essayé l’ outil CloneVDI et il a fait du bon travail en beaucoup moins de temps et en un clic.


5
On pourrait penser que sur ce type de site, il y aurait une sorte de surbrillance syntaxique pour DOS, mais non. Il a l'air beaucoup plus joli dans Notepad ++
gars en CAD, le

1
@CAD_bloke qui nécessiterait un moteur d’analyse et lorsque vous tenez compte du nombre de langues différentes publiées sur SE, vous regardez un projet ÉNORME. Imaginez combien de versions et de dialectes de DOS il y a, par exemple, et avant même d’avoir Linux, etc.
Caltor le

Très bon point. Ironiquement, il est mis en évidence sur l'application iOS d'échange de pile.
CAD bloke

2
Ouais, CloneVDI est un moyen bien meilleur et plus rapide pour une utilisation personnelle
VarunAgw

6

Invité Debian sur un hôte Windows en utilisant discard / TRIM.

Ce n'est pas une réponse directe en soi, car je traite du problème, pas de la question. Au lieu de compacter périodiquement l'image, cette solution utilise discard pour supprimer automatiquement les blocs inutilisés de l'image de disque de la machine virtuelle hôte.

Cette solution nécessite un système de fichiers invité prenant en charge TRIM en continu. Le wiki Arch Linux contient une liste de systèmes de fichiers prenant en charge les opérations TRIM .

FDE et cryptoroot ne sont pas spécifiquement couverts, car il existe des problèmes de sécurité et aucune des autres solutions à cette question ne permettrait un compactage non plus. Le wiki Arch Linux contient des informations sur les périphériques TRIM et dm-crypt .

En théorie, cela fonctionnera pour tous les invités Linux sur des hôtes VBox utilisant le stockage VDI.

Configuration de l'hôte

Avec la VBox fermée et aucune machine virtuelle en cours d'exécution, ajoutez le support de suppression à vos disques en définissant les deux discardet nonrotationalpour chaque disque dans le fichier de configuration de la machine virtuelle. A cette époque discardn'est pas dans l'interface graphique, mais nonrotationalest exposé comme la case à cocher « Solid State Drive ». (ref: forums vbox, supprimer le support )

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

Démarrez la machine virtuelle et vérifiez que le support TRIM est activé:

sudo hdparm -I /dev/sda | grep TRIM

Configuration d'invité

Si LVM est utilisé, modifiez le paramètre de mise au rebut dans /etc/lvm/lvm.conf. (ref: wiki debian, exemple lvm.conf )

devices {
...
    issue_discards = 1
}

Dans fstab, ajoutez l' discardoption aux systèmes de fichiers que vous souhaitez supprimer automatiquement (ref: debian wiki, exemple avec 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

Remontez les systèmes de fichiers pour qu'ils récupèrent leurs nouvelles options.

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

Coupez manuellement les blocs libres maintenant avec fstrim. fstrimutilise le système de fichiers monté, pas le périphérique bloquant qui le sauvegarde. Au lieu de définir un rejet continu fstab, cela pourrait être fait sur un cron hebdomadaire. (Le cron hebdomadaire est recommandé pour les disques SSD physiques pouvant prendre en charge le support de TRIM, mais cela n’est pas pertinent ici, car les disques SSD sous-jacents sont gérés par le système d’exploitation hôte. Voir: avertissement de suppression de ssd ).

fstrim /
fstrim /build

À ce stade, la taille des systèmes de fichiers à l'intérieur de la machine virtuelle et celle des images de la machine virtuelle doivent être assez proches.

Testé avec:

  • Guest1: Debian 8.7, noyau: linux 4.8 grsec depuis les backports, système de fichiers: ext4
  • Guest2: Debian 9 RC2, noyau: linux 4.9, système de fichiers: ext4
  • Host1: VBox 5.1.14, Win7, image fmt: VDI
  • Host2: VBox 5.1.14, Win8.1, image fmt: VDI

2

Pour MacOS Guest, procédez comme suit:

  1. Annulez l'espace libre dans le système invité:

    diskutil secureErase freespace 0 "/Volumes/Macintosh HD"
    

    (remplacez / Volumes / Macintosh HD par le nom de votre lecteur)

  2. Arrêtez la machine virtuelle invitée

  3. Exécutez cette commande pour réduire la taille de l'image du disque VDI.

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

    OU

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

1

J'utilise ceci pour mon image VDI montée sur Debian virtuelle dans Windows VirtualBox. Ce n'est pas une solution générale, mais cela devrait au moins vous donner un aperçu de ce que je fais.

Commandes dans Debian:

root@debian:~# lsblk  # show partitions
NOM MAJ: MIN RM TAILLE RO TYPE MOUNTPOINT 
sdb 8:16 0 128G 0 disque 
Sdb1 8:17 0 128G 0 partie / mnt / web # CECI EST LA PARTAGE DES INTÉRÊTS!
sda 8: 0 0 64G 0 disque 
Sda1 8: 1 0 61,4G 0 partie / 
├─sda2 8: 2 0 1K 0 partie 
Sda5 8: 5 0 2,7G 0 partie 
[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

Commandes sous Windows:

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

J'espère que ça aide :)


1

Je ne souhaite pas activer la prise en charge TRIM dans le système d'exploitation, car chaque suppression de données imposera le compactage des données dans un fichier VDI, rendant le système invité inutilisable lorsque le fichier VDI se trouve sur un disque rotatif classique. Pour moi, le mieux est d'effectuer un compactage à la main, par exemple une fois par mois.

Lors du compactage normal, le contenu du fichier VDI est copié dans un nouveau fichier. Cela nécessite de l’espace libre (parfois grand) sur le disque hôte.

J'ai une solution similaire à celle proposée par Andrew Domaszek. Cela fonctionne très bien même avec NTFS (Windows10).

Pour faire ça:

  • créer une nouvelle machine virtuelle démarrant avec Live CD GPart (vous pouvez utiliser votre distribution Linux préférée).
  • Modifier les paramètres de la machine et configurer le contrôleur de disque SATA
  • Ajouter des fichiers VDI existants que vous souhaitez compacter
  • Modifiez les disques basés sur VDI pour qu'ils soient visibles en tant que SSD avec le support 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
    
  • démarrer la machine

  • Dans le shell root Linux, montez la partition NTFS mount /dev/sda2 /mnt
  • zéro espace libre dd if=/dev/zero of=/mnt/bigfile
  • rm /mnt/bigfile
  • forcer le compactage de VDI sans créer de nouveau fichier: fstrim -v /mnt

0

Une astuce très utile pour compléter la réponse acceptée est que vous pouvez vous en sortir sans aucune compression après la mise à zéro de l'espace invité, en utilisant un système de fichiers compressé sur l'hôte (par exemple, en choisissant de compresser le dossier des lecteurs virtuels sur Hôte Windows). En fait, cela permet d’économiser beaucoup d’espace, car les systèmes d’exploitation contiennent généralement beaucoup de fichiers texte ou binaires répétitifs (par exemple, un lecteur invité de 30 Go disposant de 15 Go d’espace réduit à zéro peut atteindre 4 Go sur le lecteur hôte).

Les mises en garde impliquent que l’accès au disque sur le matériel réel peut augmenter et que l’utilisation du processeur augmente légèrement.


0

NOTE IMPORTANTE POUR LES SYSTÈMES D'EXPLOITATION LEGACY (~ 1997-2007)

En général, les techniques des réponses données précédemment sont valables. CEPENDANT, il existe un cas particulier très important.

Pendant une période de quelques années - peut-être de 1997 à 2007 ou à peu près - les systèmes d'exploitation 32 bits étaient toujours la norme, mais des disques durs de plus de 2 Go étaient déjà utilisés. En conséquence, lorsque vous essayez de consommer tout l’espace libre en écrivant un fichier de zéros (ce qui devrait toujours être fait en tant que root, pour inclure l’espace libre privilégié de la racine, que personne ne peut toucher), vous pouvez voir:

Fichier trop large

au lieu de ce que vous attendez:

Pas d'espace disponible sur le périphérique.

Si cela se produit, vous avez probablement atteint une limite de taille de fichier de 2 Go. Cela était courant à l'époque car de nombreuses opérations sur les fichiers donnaient des résultats sous forme d'entiers 32 bits signés, de sorte que les valeurs négatives pouvaient générer des codes d'erreur. Cela signifiait effectivement que les résultats de compensation étaient limités à 2 ^ 31 octets sans mesures spéciales.

La solution de contournement est simple: continuez à créer des fichiers de mise à zéro différents et nommés de manière différente jusqu'à ce que le disque manque d'espace.

Si vous êtes un enseignant qui souhaite démontrer cette situation pour une classe, une image disque de 4 Go avec une ancienne copie de Red Hat Linux 7.0 suffit.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.