2012/05/13

Fusion で Mac OS X のカーネルデバッグ

● Kernel space is the last frontier 

...とまでは言わないが、しかしカーネルコードをみたりいじったりするのは非常に楽しい。一方で、カーネル空間でのミスは簡単にOSクラッシュを引き起こす。なんだかんだいって OSがなんとかしてくれるユーザランドでのアプリケーション開発やブラウザの上のスクリプト書きとは違う厄介さがある。

通常、カーネル内に組み込まれるコードのデバッグには2マシンデバッグが行われる。開発中のコードを実行するテストマシンとは別にデバッグ用のマシンを用意し、何らかの方法で接続、デバッグ用のマシンでデバッガを動かし観察するというものだ。接続方法は、昔ならシリアルケーブル、最近だと(少々癖はあるが) TCP/IP が利用できる。
もっとも、私はこれまで2マシンデバッグできる贅沢な環境でコードを書いたことがない。昔作った W-ZERO3用のシリアルドライバは、気合い一発の printf デバッグだった...、ファイルに書き出す前に落ちるので、WindowServer 殺してコンソールモードにしてログをはき出させ、死んだ瞬間の画面をメモって開発するという。今にしてみれば呆れた方法だった。

Mac OS X はネットワーク越しの 2マシンデバッグをサポートしている。方法については Mac OS X のドキュメントに記載があるので読んでみると良い。

とはいえ、2台もMacを横に並べて開発を行うのは少々面倒だ。仮想環境を使えばこの2マシンデバッグも簡単にできるのではないか?という事で試してみた。


● 仮想環境でカーネルデバッグを行うには

まず Mac Developer Program には入っておいた方がいい。年 $99 の有償プログラムだが、その価値はあるだろう。

開発環境である Xcode は無償でダウンロードできる。なので有償プログラムに入らなくてもアプリケーションや KEXT の開発は出来なくもない。ただし Xcode 以外の開発リソース、例えばカーネルシンボルなどその他配布物が有償登録せずに手に入るかは確認していない。


Fusion を使った2マシンデバッグの大枠の手順は、以下のページに既に記載されている。先の Apple のドキュメントとあわせて読んでおくといいだろう。
"Reverse Engineering Mac OS X : Mac OS X Kernel debugging with VMware"
http://reverse.put.as/2009/03/05/mac-os-x-kernel-debugging-with-vmware/
上記の記事は、まだ Lion のリリースされていない 2009 年のもののため、OS X のインストール方法が少々あやしいことを書いていたりするが、さくっと忘れてほしい。Lion の場合は インストールアプリケーションの下から InstallESD.iso さえ取り出せれば、細工せずとも普通にインストールが可能だ。

上記記事を参考に、私のやった手順を以下に記す。

以降、Xcode4 で開発を行い、ビルドを実行するホスト環境を Develop Machine、実際にコードを実行しテストを行うゲスト環境を  Target Machine と書く。


● ゲスト環境( Target Machine ) での準備

まず、仮想環境上に Mac OS X Lion をインストールする。

アップデートなどが終わったところで一度シャットダウン、停止状態でスナップショットをとっておく。今後何度も何度もクラッシュさせることになるので、安全な状態を確保しておくのは必要なことだ。

ゲスト環境のネットワーク接続は NAT のままで構わない。ただ、IPアドレスはDHCPではなく固定IPに書き換えておいた方が楽かも知れない。Fusion の DHCPサービスは概ね同じIPアドレスを割り当ててくれるが、変わると少々ややこしいことになるので気になる場合は固定IPに変更をしておくといい。

Develop Machine から Target Machine へファイルをコピーする手段を整えておく。ファイル共有を使ってもいいし、scp をつかっても良い。私は  Target Machine のアカウントの .ssh/authorized_keys に Develop Machine での自分のアカウントのSSHの公開鍵を入れておき、パスワードなしで簡単コピーできるようにしておいた。

続けて、カーネルデバッグ特有の設定を行う。

Apple のドキュメントだと NVRAM に引数を設定するようになっているが、仮想環境では nvram ではなく /Library/Preferences/SystemConfiguration/com.apple.Boot.plist に記載する。このファイルは管理者権限ではないと編集できないので、sudo  を使って vi なり nano なりで編集して欲しい。

デフォルトでは、
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Kernel Flags</key>
<string></string>
</dict>
</plist>
となっているのを
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Kernel Flags</key>
<string>-v debug=0x04 pmuflag=1</string>
</dict>
</plist>
に修正する。「-v」は verbose オプションで、起動時に黒画面に起動メッセージが表示されるようになる。

-v を指定すると、起動中のメッセージが表示される
さらにカーネルクラッシュした場合に、画面の上にコンソールメッセージを出して止まってくれる。一般ユーザには忌み嫌われるクラッシュ画面だが、カーネル開発をしているときにはこの断末魔の悲鳴は重要なヒントになる。

通常のクラッシュ時の画面
debug= でカーネルデバッグを指定した場合
MACアドレスとIPアドレスが表示されているのが分かる
-v オプションを指定した場合

debug=0x04 はデバッグオプションの設定で、Apple のドキュメントによると以下の通りだ

シンボル
フラグ値
意味
DB_HALT0x01OS起動時に一時停止を行い、デバッガーの接続を待つ
DB_PRT0x02コンソール画面に kernel 内の printf 出力を表示させる
DB_NMI0x04NMI (Non Maskable Interrupt) 信号でOSを一時停止しデバッガーに落とす
DB_KPRT0x08kprintf の出力をシリアルポートに出す
DB_SLOG0x10外部のGDBではなく組み込みのddb(kdb)をデフォルトデバッガにする
 (ただし、通常のDarwinカーネルにddb は組み込まれていない)
DB_ARP0x20デバッガに ARP テーブルの操作やルータを介した通信を許す(セキュリティーホールになるので注意) -- なお、どのカーネルにも本機能は含まれていない
DB_KDP_BP_DIS0x08古いGDBをサポートする
DB_LOG_PI_SCRN0x08グラフィカルなクラッシュ画面を表示させない

先の Reverse Engineering Mac OS X のドキュメントでは debug=0x01 を指定している。

 Target Machine の起動時に一時停止されるので、その間に Develop Machine の GDB で接続するというものだ。その理由として「仮想環境でどうやって NMI を起こせばいいか分からなかった(because I couldn’t find a way to create NMI events inside the virtual machine.)」とある。

確かに通常は「Command-Option-Control-Shift-Escape」か「Command-Power」キー操作でNMIが発生すると Apple のドキュメントにはあるが、仮想マシン内ではこれはうまく動かないようだ。

そこで Reverse Engineering Mac OS X では起動時に一時停止する手段をとったが、これだと起動のたびに GDB の atacch が必要になり面倒だ。そこで、強制的にデバッガを起動する KEXT 「PseudoNMI」を用意した。

ソースコードは GitHub に置いたので好きにみてほしい。
https://github.com/shiro-t/PseudoNMI

使い方は以下の通りだ。

  1. この PseudoNMI.kext をダウンロード
  2. パーミッションなどを調整する(所有権は root:wheel で、読み取りと実行のみに)
  3. sudo kextload ./PseudoNMI.kext」でカーネルに組み込む。
  4. sudo sysctl -w debug.pseudo_nmi=1」を実行する

sysctl を実行すると、内部的にNMIが発行されたのと同じ処理が動く。debug=0x04 が設定定されていれば外部デバッガーの接続待ちになり、そうでなければクラッシュする。


接続は TCP/IP を通じて行われる。ただし、そのままでは上手くいかないので、あらかじめ ARPテーブルに設定が必要だ。

ARP テーブルとは IPアドレスと Ethernet でのハードウェアアドレス(MACアドレス)を紐付けする対応表で、通常はカーネルが自動的に保守をしている。
カーネルは知らないIPアドレスへの通信が行われる際に ARP というプロトコルを使ってそのIPアドレスに対応するMACアドレスを手に入れている。その都度手に入れていたのではネットワークに負荷がかかるので、カーネル内のメモリに一定期間保管している。このARPテーブルの内容は「arp -a」コマンドで確認できる。

ARPによる処理は自動的に行われるので通常は気にする必要がない。ただ、デバッガ起動時はどうも自動的に手に入れた値を全てクリアしてしまっているようで、そのままでは通信できなくなる。そこで、あらかじめ固定的な値を組み込んでおく必要があるのだ。

手順としては、まず、Develop Machine 側の IPアドレスとMACアドレスを手に入れる。これは仮想マシンがどの方式でネットワークに繋がっているかによる。NAT の場合は vmnet8 というホスト側の仮想NICを通じて仮想マシンと繋がっている。このNATネットワークは 「192.168.x.0/24」のネットワークで、x の部分はインストール時に決定される。

そして、192.168.x.1 はデフォルトルータとして使われ、Develop Machine そのものの通信は 192.168.x.2 で行われる。
192.168.x.2 に対応する MAC アドレスは、Develop Machine  ifconfig vmnet8 を実行するか、 Target Machine 側で arp -a で ARP テーブルを表示させて確認できる。

IPアドレスと MAC アドレスの対が分かったら、 Target Machine 側で以下コマンドを実行する
sudo arp -s 192.168.x.2 aa:aa:aa:aa:aa:aa
これでOSが再起動されるまで削除されない ARPテーブルの設定がなされる。
仮想マシンのネットワーク構成を変えない限りこの値は一定のため、以下設定を /Library/LaunchDaemons におくことで起動の都度 自動設定させることも可能だ。


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>Label</key>
        <string>jp.nest.debug.static_arp</string>
        <key>ProgramArguments</key>
        <array>
                <string>/usr/sbin/arp</string>
                <string>-s</string>
                <string>192.168.203.2</string>
                <string>0:50:56:f6:cc:a8</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
</dict>
</plist>

このファイルを /Library/LaunchDaemons に配置したあとでリブートしてもよし、「sudo launchctl load /Library/LaunchDaemons/jp.nest.debug.static_arp.plist」を実行して読み込ませても良い。

これで、ゲスト側の準備は完了だ。


● ホスト環境(Develop Machine) でのデバッグ設定

さて、ホスト側の設定にうつる。

まず、Kernel Debug Kit を手に入れる。Kernel Debug Kit はシンボル情報(バイナリ中のどこがどの名前の関数に対応するかなどデバッグに必要な情報)が一式整ったものだ。OS のバージョンごとに存在するため、Lion の場合 kernel_debug_kit_10.7.3_11d50.dmg を手に入れる。入手先は http://developer.apple.com/sdk だ。

ダウンロード後、ダブルクリックしてイメージをマウントしておく。

必要に応じてカーネルのソースコードも手に入れておいた方がいいだろう。

http://opensource.apple.com から適切なバージョンを選んで、xnu-<xnuのバージョン> を選択、ダウンロードする。Lion (10.7.3) の場合は「xnu-1699.24.23」がそれだ。tar.gz アーカイブで手に入るので適当なところに展開しておく。カーネルソースがあれば、デバッガでソースコードを参照できる。


次に、ゲストで行ったのと同じ ARP テーブルの設定をホスト側でも行う。ゲスト側のNIC(en0)のIPアドレスと MAC アドレスを割り出した後
sudo arp -s <IPアドレス> <MACアドレス>
を実行する。Develop Machine側 vmnet8 のIPアドレスは常に一定だが、ゲスト( Target Machine )側の en0 のIPアドレスは、デフォルトではDHCPのため変わることがありえるので注意だ。冒頭にも書いたように、変わるのが面倒な場合は固定IPアドレスにしてしまうといい。

ここで準備は終了だ。

● ターゲットとなる KEXT を準備する

カーネルデバッグを行う最大の理由は、KEXT のデバッグであろう。

Xcode で開発を行い、KEXTをビルドする。ビルドすると KEXT と同じところに .sym のついたそのKEXTのシンボルファイルが生成されるのでこれも取得しておく。

開発した KEXT を  Target Machine にコピーする。
コピー後には 「所有者とグループを root:wheel に」「グループとその他の書き込み権限を削除」を忘れないように。セキュリティ上の都合から権限が甘い KEXT は読み込まれないようになっている。

KEXT が正しくロードできるかについては、kextutil というコマンドで確認できる。
sudo kextutil Foo.kext
なお、私はこの kextutil でチェックしてる時にクラッシュしたことがある。
出来の悪い KEXT だとそういう可能性もあるので注意してほしい。


● カーネルデバッグを行う

Develop Machine 側で GDB を立ち上げる
gdb /Volumes/KernelDebugKit/mach_kernel
Kernel Debug Kit をマウントしていると、/Volumes 以下にマウントされているはずだ。
以下コマンドを入力、準備を行う
gdb$ target remote-kdp
以下のコマンドを入力だけ行い、リターンを押さずに置いておく

gdb$ attach <Target Machine のIPアドレス>

 Target Machine  側にうつって以下コマンドを実行、PseudoNMI が存在するのを確認する
sysctl debug.pseudo_nmi
正常ならば「debug.pseudo_nmi: 0」と返ってくるはずだ。
存在していれば以下を実行する
sudo sysctl -w debug.pseudo_nmi=1
すると、実行した瞬間にゲストOS上の Mac OS X の実行が停止される。
すかさず Develop Machine 側で入力だけしておいた attach コマンドを実行する。

ARP テーブルが固定化されており、ちゃんと通信が出来るなら即座に「Connected.」と表示されプロンプトが表示される。もしそうならない場合は、ARPテーブルの設定忘れなので改めて設定をおこなってほしい。

接続できたら「gdb> c」 と c(ontinue) コマンドを実行する。すると、止まっていたゲストOSの実行が再開される。

これでGDBが接続された状態になっている。あとはブレークポイントを設定するなり、クラッシュしたらスタックトレースを引っ張るなりいつものデバッグができる。


2012/04/29

Bhyve が Fusion 上で動いた




動いたので記念撮影。このあと起動し、ちゃんと root でログインできている。

細かいことはもう少し詰めてから書くが、ポイントは
  • 急がば回れ。多分今の -curent なら深く考えなくても Fusion 上で動くのでソースからビルドが結局は近道
  • http://bhyve.org にバイナリきっとあるけど、これそのままでは Fusion 上で動かない
  • 問題は現在の Bhyve のコードでは治っている
  • 要点? vhv ではVM_EXIT_SAVE_PAT と VM_EXIT_LOAD_PAT が非対応のため
というところだ。

適当に -current 引っ張ってきて手直しした vmm.ko をこちら においたので、もし試したい場合は以下の手順でいけるだろう。(要追試)

  1. (必要かはまだ絞り込めていないが)、とりあえず4GB はメモリを持った仮想マシンを作っておく
  2. FreeBSD 9.0R を普通インストールする
  3. http://bhyve.org にリンクされている bhyve-0.0.1r225757.tar をダウンロードする
  4. pkg_add <ダウンロードした bhyve-0.0.1r225757.tar> でインストールする
  5. /boot/kernel/vmm.ko を上記のパッチ済みのもので差し替える
  6. http://bhyve.org にリンクされているゲストイメージをダウンロードする。1GB/400MBどちらでもよい
  7. xz -cd <ゲストイメージ.tar.xz> | tar xf -  で展開する
  8. 出来たフォルダを # mv ./bhyve-guest-400mb /usr/bhyve-guest で /usr/ 以下に配置する(トップフォルダの名前をリネームするので要注意)
  9. /boot/loader.conf を作成、以下の情報を書き込む(2GBをホストに割り振る)
  10. hw.physmem="0x80000000"
    debug.witness.watch="0"
  11. 再起動して設定を生かす
  12. root で cd /usr/bhyve-guest から sh ./vmprep.sh でカーネルモジュールを読み込ませる
  13. sh ./vmrun.sh で仮想マシンを起動する

詳細なことはまた改めて書く。

2012/04/25

[余談] ファイルを探索後、そのファイルを検索する

ちと本日ネタになったので覚え書き代わりに書くとする。

本日みたある資料では、以下のような感じになっていた。
grep ERROR `find . -name "debug*.txt" -print`
これがいけないこと、というのを指摘したのだが分かってもらえなかったようなので何故いけないかをつらつら語りたいと思う。


ある程度 UNIXの経験がある人ならば「何だその話かよ」で終わる話だが、様々な面でこれは問題のある表現である。


一番簡単な問題は「溢れる」ということだ。コマンド行の固定長で上限ある。
このサイズは ARG_MAX という定数で定義されている。

例えば、Mac OS X 10.5.8 では以下の感じだ。
grep -R ARG_MAX /usr/include/
(中略)
/usr/include/limits.h:#define _POSIX_ARG_MAX 4096
/usr/include/sys/syslimits.h:#define ARG_MAX   (256 * 1024) /* max bytes for an exec function */
POSIX な定数だとわずか 4KB, そうでなくても 256KB 程度になる。これ以上は保証されない。

上記の find の書き方だと「カレントディレクトリ (.) とそこから下のサブディレクトリ」を再帰するので、debug.txt と書かれたファイルが下のディレクトリにあるなら容易に溢れる訳だ。溢れると、のたうち回った末にこんなエラーが表示される

/usr/bin/grep: Argument list too long.
計算機資源に優しくないのでやめろ感じる訳だ。

また、サブディレクトリを探す意図はなかったというかも知れないが、ならばシェルの補完でも十分だ。「 grep ERROR debug*.txt 」で間に合う。どうしてもバッククオートを使いたいなら「grep ERROR `ls debug*.txt`」とでもすればいい。


もちろん「溢れ」の可能性については前世紀から分かってる事実であり、このため find には頼もしい助っ人である「xargs」コマンドがついている。

上記の例を「悪い」見本で直すとこんな感じだ
find . -name "debug*.txt" -print | xargs grep ERROR
xargs は標準入力で渡されたリストを ARG_MAX を越えない程度に分割して、それを引数で渡されたコマンドの引数にして実行する。また、コマンドの実行が一々増えていいのなら

find . -name "debug*.txt" -exec grep ERROR {}\;
と書けばいい。-exec は find がマッチしたファイルパスの一つ一つに対して指定のコマンドを実行する。{} の部分がファイルパスに置換される。また、-exec の引数となるコマンド列の末尾は ; で終わるが、これがシェルに解釈されないように \ を入れる。-exec hogehoge {} \; まではイディオムであり、よく見かけると思われる。

個人的には、上記二つで普通のUNIX屋であると認識する。


で、より上位の人に「一々 -exec するな」か「マッチしたファイル名に空白がはいってたらどうする」かで突っ込まれるのもまた普通の話と思われる。

そう、xargs で引き渡された標準入力に、普通の英数字以外が混じっているとそこが「区切り」と見なされることがある。


で、だ。そんなことも、xargs を作ったような在りし日のUNIX屋にとっては想定内である。そのため、find には -print0, xargs には -0 オプションがある。正しいのは以下になるだろう。
find . -name "debug*.txt" -print0 | xargs -0 grep ERROR
find の -print0 オプションは -print とほぼ同じだが、区切り文字を '\0'、ヌル文字にしてくれる。空白や制御文字はファイル名に入れることは出来ても、ヌル文字は決してファイル名に現れない。このため、一つの検出されたファイルパスが間違って分割されることもない。

一方、ヌル文字が区切りであることを示すのに、xargs には -0 (ゼロ)オプションがある。find の -print0 での出力を xargs -0 は正しく解釈し、ARG_MAXに越えないだけにまとめてコマンド実行をしてくれる。

いつ頃から find -print0 と xargs -0 があったかは知らないが、私が駆け出しの頃にはすでにあったものだ。今日日の環境ならどこにでもあるだろう。

ファイル名に空白があるは、かつて Apple も iTunes のアップデートでミスった問題だ。
決して少ない訳じゃない。


決して新しい知識ではないのだから、ここまでは配慮して欲しいと思ったのが、本日ぐだぐだ言ってた理由だ。








2012/04/24

vExpert 2012

今年も辛うじて、vExpert 2012 を頂きました。ありがとうございます。


2012/04/14

VMware Tools のアップデート追記

昨日公開した VMware Tools のアップデート情報だが、間の悪いことにこれに関係するもう一つ新しいアドバイザリ VMSA-2012-0007 が出ていたので追記したい。

これは、Windows 向けの VMware Tools のフォルダの権限付けにミスがあり、これを突くことでゲストOS上の特権を奪えるというものだ。

上記のアドバイザリを参照して頂ければ分かるが、この脆弱性をもつ製品は非常に幅が広い。

  • VMware Workstation 8.0.1 とそれ以前
  • VMware Player 4.0.1 とそれ以前
  • VMware Fusion なら 4.1.1 とそれ以前
  • ESX/ESXi なら 3.5, 4.x, 5.0 

まぁ、要するにこの脆弱性への対応パッチやアップデートを含まれてない製品全て、ということになる。ホスト製品の場合はそれぞれ後継製品に、ESX/ESXi の場合は該当パッチを適用することで内蔵される VMware Tools に更新されるので、アップデートやパッチ適用後、Windows をゲストOSとする仮想マシン全ての VMware Tools をアップデートする必要がある。手間がかかるが必ず実施した方が良い。

なお、VMware Fusion 4.1.2 をダウンロード、その中の VMwareTools を確認したところ、バージョンは 8.8.3 (8.8.3.12575)、ビルド番号は 683185 のようだ。

2012/04/13

VMware Tools のアップデート

少々旧聞だが、VMware 製品のセキュリティアップデートを通知する Security Advisories & Certifications に掲載された VMSA-2012-0004, VMSA-2012-0005 にて 「Windows版VMwareTools に含まれるディスプレイドライバ(XPDM, WDDM双方)にてメモリ管理の脆弱性があり仮想マシン内の Windows で特権を奪われる可能性がある」旨が告知されている。

対策としてはパッチ適用(ESXi500-201112402-BG など)になるが、これは ESX/ESXi に含まれる VMwareTools のイメージをアップデートするだけだ。具体的にこのパッチでのアップデート事項は KB 2007672 を参照して欲しい。

すぐに気がつかれたかと思うが、ただパッチを当てるだけでは問題は解決しない。各仮想マシンの VMware Tools をアップデートする必要がある。
逆に言えば、パッチを当てなくても VMware Tools さえ最新版を入手、アップデートすればこの問題については回避できる。

最新版の VMware Tools (Windows版)は以下ページから入手できる。


x86(32bit)と x64(64bit)があるのでそれぞれ入手して欲しい。


また、VMSA-2012-0005 では VMware Workstation 等ホスト製品については問題がないとされているが、これはその環境で仮想マシンを動かしている場合に限られる。

VMware Workstation 7.1.5 より前、Player 3.1.5 より前、VMware Fusion 4 より前の各製品で作成、当時の VMware Tools をインストールしている仮想マシンを ESX/ESXi 環境に持って行った場合、VMware Tools のバージョンが古くてやはり問題が発生する。
もちろん、そもそも仮想マシンを ESX/ESXi 環境に転送しないなら問題はない。

対策としては、VMware Workstation なら 8へアップグレードする、7.x なら 7.1.5 にする、Player なら 3.1.5 をダウンロードしてアップデートする、VMware Fusion なら 4 を購入し、その上で VMware Tools をアップデートしておくといい。
とはいえ、仮想化製品をそうもアップデートできない、購入できない場合もあるだろう。その場合はやはり上記のページから VMware Tools をダウンロード、アップデートしておいた方が安全だ。


なお、VMSA-2012-0004 では同じ問題を記述しているが、こちらは VMware View に対するアドバイザリで、対策として「View 5.0 か 4.6.1 へアップグレード後、各仮想マシンごとの ViewAgent をアップデートする」という手順が記載されている。

脆弱性は VMware Tools 内のディスプレイドライバなので奇妙な話だが、View を使ってる場合は ViewAgent もあわせてアップデートしておいた方がいいだろう。


カスタム静止スクリプト

かつて VCB (VMware Consolidated Backup)のころ、アプリケーションレベルでの静止点を取得するためにスクリプトを走らせる機能が存在した。これがカスタム静止スクリプトだ。

これは VCB時代のドキュメントの仮想マシンバックアップガイド(PDF) の P.44 に記載がある。VCBによるバックアップ開始時に  %WINDIR%\pre-freeze-script.bat が実行され、終了時に %WINDIR%\post-thaw-script.bat が実行される。

ただ、当時試したところ動いている様子がなく気になっていたのだが、その時は急ぎ確認する理由もなかったのでそのままにしておいた。

そして、先日 カスタム静止スクリプトについて調べる機会ができたので少々確認をしてみた。

ご存じの通り、VCB のサポートは vSphere 4 までで終了し、現在では VADP (vStorage API for Data Protection) が利用されている。VCBはコマンドベースの技術でバックアップソフトからVCBのコマンド(vcbMounter.exe)を呼び出して連携をとっていたが、VADPはライブラリで提供され、バックアップソフトはこのライブラリのAPIをコールする事で連携をとっており、より密接な制御が可能となった。

さて、では VADPでカスタム静止スクリプトがあるかというと、まだ存在する。これについては、KB1006671が詳しい。

ESX/ESXi のバージョン カスタム静止スクリプトのパス
3.5U1 とそれ以前
%WINDIR%\pre-freeze-script.bat
%WINDIR%
\post-thaw-script.bat
3.5U2 とそれ以降
C:\Program Files\VMware\VMware Tools\backupScripts.d\
4.x %WINDIR$\backupScripts.d\
5.0
両方の場所を確認する
5.1, 5.5
%WINDIR%\pre-freeze-script.bat
%WINDIR%
\post-thaw-script.bat

なお、backupScripts.d フォルダはデフォルトでは作成されていないので、利用する場合は自分で作成する必要がある。backupScripts.d フォルダ以下にあるバッチファイルなどが全て実行されるが、その順序はバックアップ作成時はアルファベットの昇順(A-Z)で、終了時は降順(Z-A)となる。
Windows XP では 3.5U2 以降で実行していても旧来の pre-freez-script.bat 等が使われるようだ。

見ての通り、実は ESX/ESXi 3.5U2 以降でパスが変わっているのだ。これで当時うまく動かなかった理由が判明した。

私が VMware Infrastructure 3.5 を使い出したのは U2 の頃からで、それ以前は 3.0.3 を中心に 3.5 は様子見をしていたからだ。

なお、Linux など Windows 以外のOSの場合は、/usr/sbin/pre-freeze-script, /usr/sbin/post-thaw-script が実行されるようだ。これについては VMware DataRecovery 管理ガイドの P.8〜9 あたりに記載がある


追記: VCB サポートは vSphere 4.0 までではなく 4.1 までだったので訂正。そういえば 4.1 も VCB1.5u2 でサポートされていたのでした。
追記:20150106, 気がついたら対応表が変わってたのでこちらも更新