仮想ディスクを圧縮して分割する [プログラム]
もらった仮想環境のディスクイメージ(debian)が、5GB強もありました。
まず、ファイルサイズが大きすぎて、DOSフォーマットされたUSBメモリに書き込めません。
それに、仮想環境内で作業ファイルを削除したところ、実際の使用量は1GB程度少なく、4GBを下回っているようです。
仮想ディスクを圧縮してみましょう。そして、仮想ディスクを「2GBごとに分割したタイプ」に変更しましょう。
まず圧縮ですが、
VMwareでは、VMware toolsをインストールすれば
ならば、VirtualBoxのツールでなんとかしましょう。しかも、VirtualBoxを起動することなしに、です。
VirtualBoxのツールであるvboxmanageは機能が豊富で、いろいろな仮想ディスクイメージの操作ができます。これを使います。
しかしながら、VirtualBoxのツールでは、直接仮想ディスクイメージを圧縮する方法は提供されていないようです。一度、未使用領域を0クリアする必要があり、少々手順が煩雑です。
ということで、以下は、その備忘録です。
流れとしては、
1. 仮想ディスクをRAWイメージに変換する
次のコマンドを使います。infileには、元の仮想ディスクイメージのファイルを指定します。
ただし、VirtualBoxを使っている場合には、もし、infileと同じUUIDの仮想システムを登録していたら、「同じUUIDがすでにある」と言われて実行できません。この場合には、
できたRAWイメージを確認します。
次に、パーティションを確認します。
2. RAWイメージ内の各パーティションをマウントして、未使用領域を0クリアする
以下は、losetupを使う方法ですが、kpartxを使ったほうが簡単そうです(実際に試したわけではありません)。
直接mountする方法もあります。
まず、マウントしようとするパーティションをloopデバイスに割り当てます。
また、オフセットバイトは、マウントしようとしているパーティションが 2048(セクタ)からなら、2048*512=1048576です。
割り当てができれば、
そして、念のため、ファイルシステムをチェックしたほうがよいでしょう。
マウントしたら、未使用領域をゼロクリアします。bsは指定しないほうがよいです。
ディスクへちゃんと書き込んだあと、ゼロクリアに使用したファイルを削除します。
マウントを解除し、ループデバイスへの割り当てを解除します。
最後に、出来上がったファイルが問題ないか、VitrualBoxなどで新しい仮想マシンを作ってHDDとして指定して、確認します。
まず、ファイルサイズが大きすぎて、DOSフォーマットされたUSBメモリに書き込めません。
それに、仮想環境内で作業ファイルを削除したところ、実際の使用量は1GB程度少なく、4GBを下回っているようです。
仮想ディスクを圧縮してみましょう。そして、仮想ディスクを「2GBごとに分割したタイプ」に変更しましょう。
まず圧縮ですが、
VMwareでは、VMware toolsをインストールすれば
で圧縮できたはずです。が、うまくVMware toolsがインストールできませんでした。vmware-toolbox-cmd disk shrink /
ならば、VirtualBoxのツールでなんとかしましょう。しかも、VirtualBoxを起動することなしに、です。
VirtualBoxのツールであるvboxmanageは機能が豊富で、いろいろな仮想ディスクイメージの操作ができます。これを使います。
しかしながら、VirtualBoxのツールでは、直接仮想ディスクイメージを圧縮する方法は提供されていないようです。一度、未使用領域を0クリアする必要があり、少々手順が煩雑です。
ということで、以下は、その備忘録です。
流れとしては、
- 仮想ディスクをRAWイメージに変換する
- RAWイメージ内の各パーティションをマウントして、未使用領域を0クリアする
- RAWイメージを2GBごとに分割したタイプに変換する(このときに圧縮される)
1. 仮想ディスクをRAWイメージに変換する
次のコマンドを使います。infileには、元の仮想ディスクイメージのファイルを指定します。
vboxmanage clonehd infile outfile.raw --format RAW
ただし、VirtualBoxを使っている場合には、もし、infileと同じUUIDの仮想システムを登録していたら、「同じUUIDがすでにある」と言われて実行できません。この場合には、
vboxmanage list hddsで、登録している仮想システムのUUIDをチェックします。必要ならば、同一のUUIDを持つ仮想システムを削除するなどで対応します。
できたRAWイメージを確認します。
file outfile.rawすると、まさにhddのrawイメージになっているのが確認できるでしょう。
次に、パーティションを確認します。
fdisk -lu outfile.raw正しくパーティションが表示されていればOKです。
2. RAWイメージ内の各パーティションをマウントして、未使用領域を0クリアする
以下は、losetupを使う方法ですが、kpartxを使ったほうが簡単そうです(実際に試したわけではありません)。
直接mountする方法もあります。
mount outfile.raw /mnt -o loop,offset=オフセットバイトしかし、ここでは安全のため、それを手動で行ないます。
まず、マウントしようとするパーティションをloopデバイスに割り当てます。
losetup /dev/loop0 outfile.raw -o オフセットバイトここで、loop0は未使用のループデバイスを指定します。
また、オフセットバイトは、マウントしようとしているパーティションが 2048(セクタ)からなら、2048*512=1048576です。
割り当てができれば、
file -s /dev/loop0として、マウントしようとしている目的のファイルシステムであることを確認します。
そして、念のため、ファイルシステムをチェックしたほうがよいでしょう。
fsck -f /dev/loop0異常がなければ、マウントします。
mount /dev/loop0 /mnt
マウントしたら、未使用領域をゼロクリアします。bsは指定しないほうがよいです。
dd if=/dev/zero of=/mnt/.zero.fill bs=4kパーティションを埋め尽くしたらエラーで終了しますので、それまで待ちます。
ディスクへちゃんと書き込んだあと、ゼロクリアに使用したファイルを削除します。
sync; sync; sync
rm /mnt/.zero.fill
マウントを解除し、ループデバイスへの割り当てを解除します。
umount /mnt
losetup -d /dev/loop0
3. RAWイメージを2GBごとに分割したタイプに変換する(このときに圧縮される)
次のコマンドを使います。分割(2GBごとに)の指定もします。
vboxmanage convertfromraw outfile.raw outfile.vmdk --format VMDK --variant Split2G.vmdkは圧縮されたファイルになります。
最後に、出来上がったファイルが問題ないか、VitrualBoxなどで新しい仮想マシンを作ってHDDとして指定して、確認します。