2010年12月8日水曜日

VirtualBoxで仮想ディスクのサイズを減らしてみた(2)

前回からの続きです。

・swap領域をゼロクリアする

不要なファイルの削除が終わったので、ここからはシングルユーザーモードに移行して作業を続けます。次に実行するのはswap領域のゼロクリアです。

仮想マシンのメモリに余裕があってswap領域をほとんど使っていないような場合でも、ゲストOSでシステムのハイバネートを実行していれば、メモリイメージがswap領域に書き込まれます。

一度swap領域に書き込まれた内容は、明示的に消去しない限りそのまま残っていますので、それをゼロクリアすることで仮想ディスクのサイズを減らすことが可能です。

ただし、正確に言えばここでゼロクリアするのはswap領域ではなく、swapパーティション(またはswapファイル)全体です。

swapパーティション全体をゼロクリアすれば、スーパーブロックやswapヘッダもその対象になりますが、そこにはパーティションのUUIDやラベルが記録されています。

最近のLinuxは使用するswap領域をUUIDやラベルで判断するようになっていますので、ゼロクリアした後に元のUUIDやラベルを付け直しておかないと、swap領域として使用されなくなる場合があります。

それを避けるため、手順としては、wipefsコマンドで調べたUUIDとラベルをあらかじめメモしておいて、パーティション/ファイル全体をddコマンドを使ってゼロクリアした後にmkswapコマンドでUUIDやラベルを含めてswap領域として初期化することになります。

swapヘッダには他にもページサイズやswapバージョン等が記録されていますが、ページサイズはカーネル次第ですし、最近のカーネルはバージョン1のswap領域しか利用できなくなったので、メモする必要はありません。

なお、複数のOSでswapパーティションを共有している場合や、パーティションのサイズだけを後から変更してパーティションテーブルに誤った情報が記録されているような場合、swapパーティション全体をゼロクリアすることで問題が発生することがあります。

VirtualBoxの仮想ディスクでそのような運用をしていることはあまり無いだろうとは思いますが、心当たりがある方は一応ご注意ください。


  1. 「端末」から
    $ sudo init 1
    を実行してシングルユーザーモードで起動しなおします。ゲストOSがUbuntu 10.10 日本語版の場合は下記の文字化けしたメニュー画面が表示されます。

  2. 下矢印キーを何度か入力して、左端にrootと書いてある一番下の項目を選択してからreturnキーを入力します。

    これ以降、何か手順を間違えて復旧できそうにない場合は、「shutdown -h now」コマンドで仮想マシンを終了してから、スナップショットを復元してやり直してください。
  3. 表示されるメッセージが日本語のままだと文字化けして読めないので「LANG=C」コマンドを実行してメッセージを英語にします。
    # LANG=C
  4. 「swapoff -a -v」コマンドを実行して、全てのswap領域を無効にします。
    # swapoff -a -v
    swapoff on /dev/sda5
    無効にされたswap領域のデバイスファイル名、またはswapファイル名が表示されますので、これをメモしておきます。今回は「/dev/sda5」のみです。
  5. swap領域のUUIDとラベルを「wipefs -n (swapパーティションのデバイスファイル名)」で確認します。
    ここでwipefsコマンドを使用するのは、swapパーティションのUUIDとラベルを一度に両方チェックできるコマンドが現時点でこれしか見つからなかったからですが、このコマンドの本来の用途はパーティションのスーパーブロックのゴミ情報の削除です。間違った引数で必要な情報を削除しないように慎重に入力してください。
    # wipefs -n /dev/sda5
    offset               type
    ----------------------------------------------------------------
    0xff6                swap   [other]
                         UUID:  ba2bcc50-0d11-4dfc-a8b9-9c1a2faabc77
    今回はUUIDしか見つかりませんでしたが、ラベルが存在する場合はその旨表示されます。各swapパーティション毎に実行して、UUIDとラベルをメモしてください。
  6. 「dd if=/dev/zero of=(swapパーティションのデバイスファイル名)」を実行してswapパーティションをゼロクリアします。
    # dd if=/dev/zero of=/dev/sda5
    dd: writing '/dev/sda5': No space left on device
    3458049+0 records in
    3458048+0 records out
    3541041152 bytes (3.5 GB) copied, 112.524 s, 31.5 MB/s
    「No space left on device」は出力サイズを省略したことで表示された警告ですので特に気にしないでください。
  7. mkswapコマンドでswapパーティションのUUIDとラベルを復元しつつswap領域を初期化します。今回は
    # mkswap -U ba2bcc50-0d11-4dfc-a8b9-9c1a2faabc77 /dev/sda5
    になりましたが、ラベルの指定も必要な場合はデバイスファイル名の前に「-L (ラベル) 」を追加してください。

続く

0 件のコメント:

コメントを投稿