2013年11月2日土曜日

vmware-mount

vmwareの中で動かしている仮想マシン、うっかり/etc/hostsを消してしまって。
特にカスタマイズもしてなかったのでリポジトリ管理もしてないファイルだったんだけど、元通りじゃないと気持ち悪いので、仮想ディスクvmdkのバックアップから発掘しようかな、と思って作業した時のメモ。
バックアップから別の仮想マシンを起動すれば簡単なんだけど、面倒だからvmdkを直接マウントしようとして、結論から言えばもっと面倒だった、という話。

まず、普通に生活していればvmware-mountが便利に使えたはず。だったんだけど、中で動かしていた仮想マシンがNetBSDだったので、そのままだとうまく動いてくれなかった。ので、vmware-mountが中でやってると思われるmountコマンドを引数を適切に指定して呼ぶ必要がありました。
% sudo mount disk.vmdk /mnt/tmp -t ufs
-o ro,loop=/dev/loop1,offset=2719232,ufstype=44bsd
最近じゃ違うのかもしれないけど、僕は昔からNetBSDでは奥ゆかしきufsを使い続けてるので-t ufsをつけて、-oの方にはufstype=44bsdを指定。ufstypeを指定しないとoldが選ばれて、マウントはできるけど一切読めない状態になるので注意。あとufsはread onlyでしかサポートされてないのでroも必要。ここまではmanを読めばすぐわかる話。で、問題なのはoffsetの探し方。

ここで指定するoffsetはvmdkのヘッダサイズと読みたいパーティションの位置を足したもの。とりあえずvmdkのヘッダサイズがよくわからなかったので適当に推測。以下、仮想マシンの中での作業。
% disklabel /dev/wd0
(snip)
#        size    offset     fstype [fsize bsize cpg/sgs]
 a:   2097900        63     4.2BSD   2048 16384 21880  # (Cyl.      0*-   2220*)
 b:   1048950   2097963       swap                     # (Cyl.   2220*-   3330*)
 c:  41942977        63     unused      0     0        # (Cyl.      0*-  44384*)
 d:  41943040         0     unused      0     0        # (Cyl.      0 -  44384*)
(snip)
って感じの状態なので、とりあえずディスクの先頭に何が書いてあるか確認。
% hexdump -C /dev/wd0d | head -n 20
って感じで見れば、先頭から0x100付近にNetBSDのMBRのエラーメッセージが見えるので、これをキーにディスクイメージ側を探索。以下はホストでの作業。
% hexdump -C disk.vmdk|less
"BSD"をキーに探せばすぐに該当箇所が見つかる。僕の場合0x290120付近。ここからちょっと遡ると0x290000がディスクの先頭と一致することがわかる。

ここまでわかれば簡単。読みたいパーティションはoffset 63からなので
% expr 63 \* 512 + `printf %d 0x290000`
2719232

ふぅ。ちなみに最初の段階でvmdkが複数のファイルに別れてたりする場合はvmware-vdiskmanagerを使って単一ファイルのフォーマットに変換してから作業する必要があるはず。