web-dev-qa-db-ja.com

VirtualBoxのVDIファイルサイズを小さくする方法

私はVirtualBox VMを持っていて、これは非常に大きなハードディスクサイズ(Hostよりも大きい)を設定しています。私の間違いで、VM上のプログラムはたくさんのログファイルを生成し、VDIファイルのサイズはホストにスペースがなくなるまで増え続けています。

ログファイルを削除しましたが、VBoxManage.exe modifyhd "C:\Virts\mybox-i386.vdi" compactを使用した後でVDIファイルのサイズが小さくなっていません

VDIファイルのサイズを本当に小さくする方法はありますか?ありがとうございます。

298
DeepNightTwo

次の手順を実行する必要があります。

  1. ゲストでデフラグを実行する(Windowsのみ)
  2. 空き容量を無効にする:

    Linuxゲストでこれを実行します。

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

    または

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

    Windowsゲストで、SDeleteからダウンロードします。 Sysinternalsとこれを実行します。

    sdelete.exe c: -z
    

    (C:をVDIのドライブ文字に置き換えます)

  3. ゲストVMをシャットダウンします。

  4. --compactオプションを指定してVBoxManageの modifymedium コマンドを実行します。

    Linuxホストでこれを実行します。

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

    Windowsホストでこれを実行します。

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

    Macホストでこれを実行します。

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

これはvdiサイズを縮小します。

497
magicandre1981

承認された回答でコマンドを実行すると、このような役に立たないエラーメッセージが表示される場合

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

ファイル名の代わりにUUIDでコマンドを実行するだけです。

VBoxManage.exe modifyhd {aaaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeeee} --compact
37
DustWolf

私はWindowsゲストを持つWindows 7ホストにいます、これは私がフォルダーツリーのVDIのすべてを圧縮するために書いたバッチファイルです。

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

リンクをコメントに残したので、あなたは(ある種の)それがどのように動作するのかを知ることができます。

編集する

それで、結局のところ、私は CloneVDIツール を試してみましたが、それははるかに少ない時間とワンクリックで良い仕事をしました。

11
CAD bloke

Windowsホスト上の破棄/ TRIMを使用するDebianゲスト。

私は問題ではなく問題に取り組んでいるので、これ自体は直接的な答えではありません。このソリューションでは、定期的にイメージを圧縮するのではなく、破棄を使用してホストのVMディスクイメージ内の未使用ブロックを自動的に削除します。

このソリューションでは、継続的なTRIMをサポートするゲストファイルシステムが必要です。 Arch Linuxウィキには TRIM操作をサポートするファイルシステムのリストがあります

セキュリティ上の懸念があり、この問題に対する他の解決策では、どちらも圧縮を許可しないため、FDEとcryptorootは特にカバーされていません。 Arch Linuxウィキには TRIMとdm-crypt devices に関する情報があります。

理論的には、これはVDIストレージを使用するVBoxホスト上のすべてのLinuxゲストに有効です。

ホスト構成

VBoxが終了し、VMが実行されていない状態で、VMの設定ファイルで各ディスクにdiscardnonrotationalの両方を設定して、ディスクに廃棄サポートを追加します。現時点ではdiscardはGUIにはありませんが、nonrotationalは[ソリッドステートドライブ]チェックボックスとして表示されています。 (ref: vboxフォーラム、サポートを破棄する

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

VMを起動し、TRIMサポートが有効になっていることを確認します。

Sudo hdparm -I /dev/sda | grep TRIM

ゲスト構成

LVMが使用中の場合は、/etc/lvm/lvm.confの破棄設定を変更します。 (ref: debian wiki、lvm.confの例

devices {
...
    issue_discards = 1
}

Fstabで、自動破棄したいファイルシステムにdiscardオプションを追加します(ref: debian wiki、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

ファイルシステムをマウントし直して、新しいオプションを選択します。

Sudo mount -o remount /
Sudo mount -o remount /build

空きブロックを手動でfstrimでトリミングします。 fstrimはマウントされたファイルシステムを使用し、それを支えるブロックデバイスを使用しません。 fstabに継続的な破棄を設定する代わりに、これは毎週のクーロンで行うことができます。 (週単位のクーロンは、TRIMのサポートが疑わしい物理SSDには推奨されますが、基になるSSDはホストOSによって処理されるため、ここでは関係ありません。 ssd trim warning )。

fstrim /
fstrim /build

この時点で、VM内のファイルシステムのサイズとVMイメージのサイズの値はかなり近いはずです。

でテスト済み:

  • ゲスト1:Debian 8.7、カーネル:バックポートからのLinux 4.8 grsec、ファイルシステム:ext4
  • ゲスト2:Debian 9 RC2、カーネル:linux 4.9、ファイルシステム:ext4
  • ホスト1:VBox 5.1.14、Win7、画像fmt:VDI
  • ホスト2:VBox 5.1.14、Win8.1、画像fmt:VDI
6
Andrew Domaszek

MacOS Guestの場合は、次のようにします。

  1. ゲストシステムの空き容量を無効にします。

    diskutil secureErase freespace 0 "/Volumes/Macintosh HD"
    

    (/ Volumes/Macintosh HDをあなたのドライブ名に置き換えてください)

  2. ゲストVMをシャットダウンします。

  3. このコマンドを実行してVDIディスクイメージのサイズを縮小します

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

    OR

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

OSでTRIMサポートを有効にしたくありません。データを削除するたびにVDIファイルのデータ圧縮が強制され、VDIファイルが従来の回転ディスクにあるとゲストシステムが使用できなくなるためです。私にとっては、手で圧縮を実行するのが良いでしょう。月に1回.

通常の圧縮中に、VDIファイルの内容は新しいファイルにコピーされます。これには、ホストディスクにいくらか(時には大きな)空き容量が必要です。

私はAndrew Domaszekが指摘したのと同じような解決策をとった。 NTFS(Windows 10)でも非常にうまく動作します。

これをする:

  • gParted Live CDで起動する新しい仮想マシンを作成します(お気に入りのLinuxディストリビューションを使用できます)。
  • マシン設定を編集してSATAディスクコントローラを設定する
  • 圧縮したい既存のVDIファイルを追加します。
  • TRIMをサポートするSSDとして見えるようにVDIベースのディスクを変更します。

VBoxManage storageattach "gpared live" --storagectl "SATA" --port 0 --discard on --nonrotational on VBoxManage storageattach "gpared live" --storagectl "SATA" --port 1 --discard on --nonrotational on

  • 始動機
  • Linuxルートシェルで、NTFSパーティションをマウントしますmount /dev/sda2 /mnt
  • ゼロ空きスペースdd if=/dev/zero of=/mnt/bigfile
  • rm /mnt/bigfile
  • 新しいファイルを作成せずにVDIを強制的に圧縮する:fstrim -v /mnt
1
niziak

Windows VirtualBoxの仮想Debianにマウントされた私のVDIイメージにこれを使用します。これは一般的な解決策ではありませんが、少なくとも私がしていることの要旨をあなたに与えるべきです。

Debianのコマンド:

root@debian:~# lsblk  # show partitions
名前MAJ:最小RMサイズROタイプマウントポイント
 sdb 8:16 0 128G 0ディスク
└─sdb18:17 0 128G 0 part/mnt/web#このIS関心のある部分!
 sda 8:0 0 64G 0 disk 
├─sda18:1 0 61,4G 0 part/
├─sda28:2 0 1K 0パート
└─sda58:5 0 2,7G 0パート
 [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

Windowsのコマンド:

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

それが役に立てば幸い :)

1
Dejv

受け入れられた答えを補足するための非常にきちんとしたトリックは、ホスト上の圧縮ファイルシステムを使用することで、ゲストスペースをゼロにした後にまったく圧縮することなく逃げることができるということです。 Windowsホスト)オペレーティングシステムは多くの繰り返しのテキストファイルまたはバイナリファイルを保持する傾向があるため、実際にはこれによりはるかに多くのスペースを節約できるという利点があります(15GBのスペースをゼロにした30GBゲストドライブはホストドライブで4GBになります)。

警告には、実際のハードウェア上のドライブアクセスが増加し、CPU使用率がわずかに増加することが含まれます。

0
j riv

レガシー(〜1997-2007)オペレーティングシステムに関する重要事項

一般に、前述の回答の手法は有効です。ただし、非常に重要な特別なケースがあります。

おそらく1997年から2007年などの数年間、32ビットオペレーティングシステムが一般的でしたが、2 GBを超えるハードディスクが既に使用されていました。その結果、ゼロのファイルを書き込むことによってすべての空きスペースを消費しようとすると(他の人が触れることのできないルートの特権空きスペースを含めるために、常にルートとして実行する必要があります):

あまりにも大きなファイル

あなたが期待するものの代わりに:

デバイスにスペースが残っていません。

これが発生した場合、2GBのファイルサイズの制限に達している可能性があります。多くのファイル操作が符号付き32ビット整数で結果を返し、負の値がエラーコードを報告する可能性があるため、これは当時一般的でした。これは事実上、オフセット結果は特別な措置なしで2 ^ 31バイトに制限されたことを意味していました。

回避策は簡単です。ディスクのスペースが実際になくなるまで、別々の異なる名前のゼロ化ファイルを作成し続けます。

クラスでこの状況をデモンストレーションしたいインストラクターの場合、Red Hat Linux 7.0の古いコピーを含む4GBのディスクイメージで十分です。

0
breakpoint