- 2009-10-10 (Sat) 15:42
- ソフトウェア
VMware Workstation 使って新しいVM作れば簡単に出来るんだけど,貧乏人としては自前でmvdkファイルをどうにか書きたいなと.ネットで検索すると,物理ディスク全体を仮想ディスクにする方法はちらほら見られるけれど,パーティション単位で扱っている方法が見つからない.ディスク丸ごとだとちと怖いのでどうにかしたい.
ということで,実際に VMware Workstation で物理パーティションにアクセスする仮想ディスクを作って,その内容と fdisk の情報から自前でmvdkファイルを書くための情報を推測してみた.
とりあえず fdisk の情報.先頭にリカバリ情報のパーティションがあり,そのあとに二つのNTFSパーティションが置かれている.
Disk /dev/sda: 320.0 GB, 320072933376 bytes 255 heads, 63 sectors/track, 38913 cylinders Units = シリンダ数 of 16065 * 512 = 8225280 bytes Disk identifier: 0x00000021 デバイス Boot Start End Blocks Id System /dev/sda1 1 1275 10241406 27 不明 /dev/sda2 * 1276 13417 97530615 7 HPFS/NTFS /dev/sda3 13418 38913 204796620 7 HPFS/NTFS
そんで,最初のパーティションを仮想ディスクとする生成された vmdk ファイル.
# Disk DescriptorFile version=1 encoding="Shift_JIS" CID=edce33f3 parentCID=ffffffff createType="partitionedDevice" # Extent description RW 63 FLAT "partition-pt.vmdk" 0 RW 20482812 FLAT "\\.\PhysicalDrive0" 63 RW 195061230 ZERO RW 409593240 ZERO RW 5103 ZERO # The Disk Data Base #DDB ddb.virtualHWVersion = "7" ddb.uuid = "60 00 C2 9f 15 8c 38 89-2c be 12 94 46 3a 8c ea" ddb.geometry.cylinders = "16383" ddb.geometry.heads = "16" ddb.geometry.sectors = "63" ddb.geometry.biosCylinders = "1024" ddb.geometry.biosHeads = "255" ddb.geometry.biosSectors = "63" ddb.adapterType = "ide"
まず,パーティション単位で仮想ディスクとするには partitionedDevice というタイプを指定するらしい.そんで, Extent description にディスクのパーティション構造らしきものが書かれるらしい.
最初の行はディスク先頭のMBRを含む63セクタでしょう.多分RWの後の数字がセクタ数.そしてこの部分は物理ディスク上に書き込まれては困るので別ファイル(partition-pt.vmdk)に内容を置くと.ファイル名手前の FLAT はよく分からんけどデータの保存の形か何かかね? そんで最後の数字の 0 は開始セクタ番号か何かでしょう(イメージ中のセクタ数と考えるのが妥当か?).ところで行先頭のRWはread/writeなのかrawなのか?
んで,次の行が最初のパーティションを使うためのエントリのはず.RWの後の数字がfdiskで見たブロック数の倍になっているからパーティションのセクタ数で良いっぽい.ついで FLAT は相変わらず.そして最初のディスクなので先ほどのファイル名の変わりに"\\.\PhysicalDrive0"が置かれ,開始セクタと思われる63が続くと.
残りの行は各パーティションのセクタ数と ZERO が書かれるらしい.ZEROは使用しない領域を表すのかね?
DDBは仮想ディスクとしてのスペックなのであまり気にしない.ネット上に転がってる物理ディスク全体を仮想ディスクにする場合と同じ値みたいだし.
例がひとつでは分かりにくいので,三つ目のパーティションを使った仮想ディスクの vmdk ファイルも生成.
# Disk DescriptorFile version=1 encoding="Shift_JIS" CID=e82adf55 parentCID=ffffffff createType="partitionedDevice" # Extent description RW 63 FLAT "Ubuntu-pt.vmdk" 0 RW 20482812 ZERO RW 195061230 ZERO RW 409593240 FLAT "\\.\PhysicalDrive0" 215544105 RW 5103 ZERO # The Disk Data Base #DDB ddb.virtualHWVersion = "7" ddb.uuid = "60 00 C2 95 b8 17 da cc-f3 65 27 46 17 81 e6 07" ddb.geometry.cylinders = "16383" ddb.geometry.heads = "16" ddb.geometry.sectors = "63" ddb.geometry.biosCylinders = "1024" ddb.geometry.biosHeads = "255" ddb.geometry.biosSectors = "63" ddb.adapterType = "ide"
Extent description のエントリが少し変わった.最初の63セクタは同じ(ファイル名は違うけど).そして,今度は第一パーティションを使用しないので2行目が ZERO になった.変わりに,第三パーティションに対応する4行目が FLAT "\\.\PhysicalDrive0" になった.最後の数字は上三行のセクタ数の合計になっているので,パーティションの開始セクタ位置ってことで良いっぽい.
ということで,物理ディスク上のパーティションを使うvmdkファイルを書くポイントのまとめ.
- createType="partitionedDevice" とする
- Extent description をパーティションテーブルに沿って書く.各エントリは,RWの後にサイズをセクタ数で指定し,使用するパーティションなら FLAT の後にファイル名と開始セクタ位置を書き,使わないなら ZEROと書く.ファイル名は"\\.\PhysicalDrive0"とかで物理ディスク行き,通常ファイル名でローカルなファイルっぽい.サイズ(セクタ数)は,([End] - [Start]) * [sectors/track] * [heads] で求まる.例えば二番目のパーティションは 195061230 = (13417 - 1276 + 1) * 63 * 255.ただし,最初のパーティションはMBRがあるため 63 セクタ分引かれる(20482812 = (1275 - 1 + 1) * 63 * 255 - 63).
TODO: 拡張パーティションとかどうするんだろう? 本当に使えるのかこれ?
ということで,拡張パーティション入りの場合のExtent description と fdiskの出力 .
RW 63 FLAT "ubun2-pt.vmdk" 0 RW 20482812 ZERO RW 195061230 ZERO RW 376033455 ZERO RW 63 FLAT "ubun2-pt.vmdk" 63 RW 24579387 ZERO RW 63 FLAT "ubun2-pt.vmdk" 126 RW 8980272 FLAT "\\.\PhysicalDrive0" 616157073 RW 5103 ZERO
/dev/sda1 1 1275 10241406 27 不明 /dev/sda2 * 1276 13417 97530615 7 HPFS/NTFS /dev/sda3 13418 36824 188016727+ 7 HPFS/NTFS /dev/sda4 36825 38913 16779892+ 5 拡張領域 /dev/sda5 36825 38354 12289693+ 83 Linux /dev/sda6 38355 38913 4490136 83 Linux
拡張パーティションの持つ拡張パーティションブートレコードもローカルのファイルに持っておくらしい.拡張パーティションになっていようがいまいが,使うパーティションの最後の数字は先頭セクタ番号(それまでのセクタ数の合計)となるらしい.注意点は,拡張パーティション内の領域にある論理パーティションの場合には,RWの後のサイズ(セクタ数)が拡張パーティションブートレコードの分(63セクタ)を引いたサイズになること.例えば,上の例では 8980272 = (38913 - 38355 + 1) * 63 * 255 - 63 となっている.
うーん,パーティションテーブルの中身はどうすればいいのだろうか? dd で元のディスクのテーブルを抜き出したけど不正だと怒られた.よーわからん.
と思ったら抜き出すアドレス間違ってただけだった.元ディスクのパーティションテーブルを抜き出して一つのファイルにまとめてやれば問題ないらしい.
ということで,生成のためのスクリプトとサンプル入力をメモっておく:genvmdk.sh, genvmdk.awk, diskinfo.txt.使うにはメインのスクリプトに入力を食わせる.
./genvmdk.sh < diskinfo.txt
これで仮想ディスク本体の disk.vmdk とパーティションテーブル生成スクリプト gen-pt.sh ができる.あとは
sudo bash gen-pt.sh
とかして dd でパーティションテーブルを抜き取ってきて disk-pt.vmdk ができる.
スクリプトへの入力は,ヘッド数,トラックあたりのセクタ数,ディスク全体のデバイスファイル,仮想ディスクからアクセス可能なパーティション(今のところ一個だけ),fdiskの出力たち.
- Newer: ことはじめ