小さくなって欲しいときもあります
仮想化を使っていると仮想ディスクを大きくする話は良く見るのですが Windows でディスクを小さくする話をあんまり見なかったのでちょっと試してみました。といっても近頃の Windows ならばパーティションを小さくすることくらい簡単です。
「コンピュータの管理」から「ディスクの管理」を探しだせば右クリックで縮小ができます。http://www.atmarkit.co.jp/fwin2k/win2ktips/941diskshrink/diskshrink.html おっと、こんなページもありました。
で、問題は EC2 の場合なんかです。EBS ボリュームは今のところ後からサイズ変更ができません。サイズを変更しようと思うとスナップショットを撮ってそこからボリュームを作り直したりする必要があります。更にスナップショットからより大きなボリュームは作れるのですが、元のボリュームよりも小さなボリュームは作れません。どーしよう。小さなボリューム作って dd で突っ込んでみましょう。
注意
下記手順は適当な思いつきでその後の長期運用など試していないので新しく作ったボリュームを利用していて何の問題も無いという保証はできません。このままにしろ改善するにしろ自己責任でね!
作業環境を準備する
先ずは作業用のインスタンスが欲しいので Amazon Linux の最新版を起動してみます。今だと amzn-ami-pv-2013.03.0.x86_64-ebs ってのが最新です。ログインしたら /etc/yum.repos.d/epel.repo の enabled=0 を
$ sudo vi /etc/yum.repos.d/epel.repo
でも何でもいいので 1 にします。これで epel の利用準備が完了です。epel から ntfsprogs をインストールします。
$ sudo yum install ntfsprogs
ntfsresize が使えるようになりました。
小さくなって欲しいボリュームを用意する
次に Windows インスタンスを立てて stop します。Amazon Linux を立てる前に立てておいた方がいい、かな? パスワードが取得できる前に stop していいのかどうかとか良く分かっていません。でも変なことはしない方が良いに違いありません。stop したら /dev/sda1 のボリュームをデタッチして作業用 Amazon Linux にアタッチします。とその前に、本番環境だったらここでスナップショット取得ですね。
$ sudo fdisk -l -u /dev/sdf ディスク /dev/sdf: 32.2 GB, 32212254720 バイト ヘッド 255, セクタ 63, シリンダ 3916, 合計 62914560 セクタ Units = セクタ数 of 1 * 512 = 512 バイト セクタサイズ (論理 / 物理): 512 バイト / 512 バイト I/O size (minimum/optimal): 512 bytes / 512 bytes ディスク識別子: 0xb3009496 デバイス ブート 始点 終点 ブロック Id システム /dev/sdf1 * 2048 718847 358400 7 HPFS/NTFS パーティション 1 は、シリンダ境界で終わっていません。 /dev/sdf2 718848 62912511 31096832 7 HPFS/NTFS
「境界で終わっていません」と何だか怖い言葉が出てきていますがきっと何かの間違いでしょう。sdf1 は起動用か何かで sdf2 にシステムが入っているものと思われます。今回のターゲットは sdf2 です。
ntfsresize でごにょごにょする
ntfsresize は空打ちすると丁寧な help が出てくる親切なコマンドなので一度叩いておきましょう。で、情報を取得してみます。
$ sudo ntfsresize -i /dev/sdf2 ntfsresize v2011.4.12 (libntfs-3g) Device name : /dev/sdf2 NTFS volume version: 3.1 Cluster size : 4096 bytes Current volume size: 31843152384 bytes (31844 MB) Current device size: 31843155968 bytes (31844 MB) Checking filesystem consistency ... 100.00 percent completed Accounting clusters ... Space in use : 24170 MB (75.9%) Collecting resizing constraints ... You might resize at 24169693184 bytes or 24170 MB (freeing 7674 MB). Please make a test run using both the -n and -s options before real resizing!
7674 MB 小さくできると教えてくれました。ありがとう! では早速。
$ sudo ntfsresize -s 24170M -P /dev/sdf2 ntfsresize v2011.4.12 (libntfs-3g) Device name : /dev/sdf2 NTFS volume version: 3.1 Cluster size : 4096 bytes Current volume size: 31843152384 bytes (31844 MB) Current device size: 31843155968 bytes (31844 MB) New volume size : 24169992704 bytes (24170 MB) Checking filesystem consistency ... Accounting clusters ... Space in use : 24170 MB (75.9%) Collecting resizing constraints ... Needed relocations : 112369 (461 MB) WARNING: Every sanity check passed and only the dangerous operations left. Make sure that important data has been backed up! Power outage or computer crash may result major data loss! Are you sure you want to proceed (y/[n])? y Schedule chkdsk for NTFS consistency check at Windows boot time ... Resetting $LogFile ... (this might take a while) Relocating needed data ... Updating $BadClust file ... Updating $Bitmap file ... Updating Boot record ... Syncing device ... Successfully resized NTFS on device '/dev/sdf2'. You can go on to shrink the device for example with Linux fdisk. IMPORTANT: When recreating the partition, make sure that you 1) create it at the same disk sector (use sector as the unit!) 2) create it with the same partition type (usually 7, HPFS/NTFS) 3) do not make it smaller than the new NTFS filesystem size 4) set the bootable flag for the partition if it existed before Otherwise you won't be able to access NTFS or can't boot from the disk! If you make a mistake and don't have a partition table backup then you can recover the partition table by TestDisk or Parted's rescue mode.
ファイルを移動して縮小してくれました。移動が入るのでちょっと時間が掛かるかも。環境次第ですね。
fdisk で partition を小さくする
残念ながら ntfsresize は partition size までは小さくしてくれませんでした。仕方がないので fdisk で partition を切り直してあげましょう。大きさは ntfsresize で -s で指定したのと同じにしてあげます。切り直すとシステムタイプとやらが Linux に戻ってしまうので NTFS に戻すのを忘れずに。
$ sudo fdisk /dev/sdf 警告: DOS互換モードは廃止予定です。このモード (コマンド 'c') を止めることを 強く推奨します。 and change display units to sectors (command 'u'). コマンド (m でヘルプ): c DOS互換フラグは設定されていません コマンド (m でヘルプ): u セクタ数 の表示/項目ユニットを変更します コマンド (m でヘルプ): p ディスク /dev/sdf: 32.2 GB, 32212254720 バイト ヘッド 255, セクタ 63, シリンダ 3916, 合計 62914560 セクタ Units = セクタ数 of 1 * 512 = 512 バイト セクタサイズ (論理 / 物理): 512 バイト / 512 バイト I/O size (minimum/optimal): 512 bytes / 512 bytes ディスク識別子: 0xb3009496 デバイス ブート 始点 終点 ブロック Id システム /dev/sdf1 * 2048 718847 358400 7 HPFS/NTFS /dev/sdf2 718848 62912511 31096832 7 HPFS/NTFS コマンド (m でヘルプ): d パーティション番号 (1-4): 2 コマンド (m でヘルプ): n コマンドアクション e 拡張 p 基本パーティション (1-4) p パーティション番号 (1-4): 2 最初 セクタ (718848-62914559, 初期値 718848): 初期値 718848 を使います Last セクタ, +セクタ数 or +size{K,M,G} (718848-62914559, 初期値 62914559): +24170M コマンド (m でヘルプ): t パーティション番号 (1-4): 2 16進数コード (L コマンドでコードリスト表示): 7 領域のシステムタイプを 2 から 7 (HPFS/NTFS) に変更しました コマンド (m でヘルプ): p ディスク /dev/sdf: 32.2 GB, 32212254720 バイト ヘッド 255, セクタ 63, シリンダ 3916, 合計 62914560 セクタ Units = セクタ数 of 1 * 512 = 512 バイト セクタサイズ (論理 / 物理): 512 バイト / 512 バイト I/O size (minimum/optimal): 512 bytes / 512 bytes ディスク識別子: 0xb3009496 デバイス ブート 始点 終点 ブロック Id システム /dev/sdf1 * 2048 718847 358400 7 HPFS/NTFS /dev/sdf2 718848 50219007 24750080 7 HPFS/NTFS コマンド (m でヘルプ): w パーティションテーブルは変更されました! ioctl() を呼び出してパーティションテーブルを再読込みします。 ディスクを同期しています。
さて、これで若しかするとぶっ壊れてしまったかもしれませんし上手くいってるかもしれません。試しに mount してみましょうか。
$ sudo mount /dev/sdf2 /mnt $ ls /mnt $Recycle.Bin Documents and Settings Program Files ProgramData Users bootmgr BOOTNXT PerfLogs Program Files (x86) System Volume Information Windows pagefile.sys $ df Filesystem 1K-ブロック 使用 使用可 使用% マウント位置 /dev/xvda1 8256952 1015968 7157128 13% / tmpfs 848352 0 848352 0% /dev/shm /dev/xvdf2 23603508 23602984 524 100% /mnt
大変、使用% が 100% だわ!!! このままだと起動しない気がしてきました。やり過ぎたか。。。
dd で新規ボリュームに流し込みましょう
7GB くらい小さくできたので、というかそもそも GB 単位で小さくすれば良かったですね。ともかく、余裕を見て 24GB の EBS ボリュームを作って /dev/sdg にアタッチします。そして、同じ感じでパーティションを切ってあげましょう。
$ sudo fdisk /dev/sdg デバイスは正常な DOS 領域テーブルも、Sun, SGI や OSF ディスクラベルも 含んでいません 新たに DOS ディスクラベルをディスク識別子 0x7e1c6893 で作成します。 あなたが書き込みを決定するまで、変更はメモリ内だけに残します。 その後はもちろん以前の内容は修復不可能になります。 警告: 領域テーブル 4 の不正なフラグ 0x0000 は w(書き込み)によって 正常になります 警告: DOS互換モードは廃止予定です。このモード (コマンド 'c') を止めることを 強く推奨します。 and change display units to sectors (command 'u'). コマンド (m でヘルプ): c DOS互換フラグは設定されていません コマンド (m でヘルプ): u セクタ数 の表示/項目ユニットを変更します コマンド (m でヘルプ): n コマンドアクション e 拡張 p 基本パーティション (1-4) p パーティション番号 (1-4): 1 最初 セクタ (2048-50331647, 初期値 2048): 初期値 2048 を使います Last セクタ, +セクタ数 or +size{K,M,G} (2048-50331647, 初期値 50331647): 718847 コマンド (m でヘルプ): n コマンドアクション e 拡張 p 基本パーティション (1-4) p パーティション番号 (1-4): 2 最初 セクタ (718848-50331647, 初期値 718848): 718848 Last セクタ, +セクタ数 or +size{K,M,G} (718848-50331647, 初期値 50331647): 50219007 コマンド (m でヘルプ): t パーティション番号 (1-4): 1 16進数コード (L コマンドでコードリスト表示): 7 領域のシステムタイプを 1 から 7 (HPFS/NTFS) に変更しました コマンド (m でヘルプ): t パーティション番号 (1-4): 2 16進数コード (L コマンドでコードリスト表示): 7 領域のシステムタイプを 2 から 7 (HPFS/NTFS) に変更しました コマンド (m でヘルプ): a パーティション番号 (1-4): 1 コマンド (m でヘルプ): p ディスク /dev/sdg: 25.8 GB, 25769803776 バイト ヘッド 255, セクタ 63, シリンダ 3133, 合計 50331648 セクタ Units = セクタ数 of 1 * 512 = 512 バイト セクタサイズ (論理 / 物理): 512 バイト / 512 バイト I/O size (minimum/optimal): 512 bytes / 512 bytes ディスク識別子: 0x7e1c6893 デバイス ブート 始点 終点 ブロック Id システム /dev/sdg1 * 2048 718847 358400 7 HPFS/NTFS /dev/sdg2 718848 50219007 24750080 7 HPFS/NTFS コマンド (m でヘルプ): w パーティションテーブルは変更されました! ioctl() を呼び出してパーティションテーブルを再読込みします。 ディスクを同期しています。
で、器ができたので dd で流し込みます。
$ sudo dd if=/dev/sdf of=/dev/sdg bs=512 count=1 1+0 records in 1+0 records out 512 bytes (512 B) copied, 0.0217699 s, 23.5 kB/s $ sudo dd if=/dev/sdf1 of=/dev/sdg1 bs=1M 350+0 records in 350+0 records out 367001600 bytes (367 MB) copied, 23.7274 s, 15.5 MB/s $ sudo dd if=/dev/sdf2 of=/dev/sdg2 bs=1M 24170+0 records in 24170+0 records out 25344081920 bytes (25 GB) copied, 992.344 s, 25.5 MB/s