BitVisorの改造って大変じゃないですか?
BitVisorを改造して何か機能を付け加えたいというとき、問題になるのがテスト用環境です。
まずいコードを書くとBitVisorがクラッシュするということも珍しくないので、BitVisorのビルド用環境とテスト用環境のPCは別々にしたいと思うはずです。
(一緒のPCでやっているという人を見かけますが、突然のクラッシュでファイルシステムが飛ぶ可能性があるので怖いです…)
ネットワークブートを使いたいけど
BitVisorのビルド用環境のPCとテスト用環境のPCを一緒のネットワークに置いて、ネットワークブートでbitvisor.elf
を持ってきて起動すれば解決するじゃない、って思う人が居ると思います。
しかしこれには問題があって、ネットワークブートに使われるPXEはDHCPサーバの設定を変更したり、TFTPサーバを構築したりする(これがLinuxだと割と面倒)必要があり、手間がかかります。
そこで iPXE!
iPXEはOSSのPXE実装の一つで、以下の機能をサポートしています。
- DHCPによるIPアドレスの取得
- DNSによる名前解決
- HTTPを使用したブートイメージの取得
- 対話型インターフェース
- スクリプトによる自動化
など
iPXEを使ってBitVisorのネットワークブート環境を作る
ここではGRUB 2からチェーンロードする形をとります。
/boot
は専用のパーティションがあるとします。/
と共用の場合は適宜変更してください。
テスト用環境の準備
iPXEにはいくつかのタイプがあり、GRUB 2で使用できるのはLinuxカーネル形式版のバイナリ(ipxe.lkrn
)です。
ipxe.lkrn
はArch Linuxのネットワークブートのページから拾えたりします。
参考に、Gentoo Linuxにおいてのipxe.lkrn
のemergeコマンドを書いておきます。
# USE=lkrn emerge sys-firmware/ipxe
(/usr/share/ipxe/ipxe.lkrn にできるようです)
ipxe.lkrn
を準備できたら、テスト用環境の/boot
に配置します。
次に、iPXEに読み込ませるスクリプトを用意します。
initrdとしてiPXEに読み込ませることで、自動化が可能です。
以下の内容をbitvisor.cfg
として保存し、テスト用環境の/boot
に配置します。
#!ipxe
dhcp && kernel http://(ビルド用環境のIPアドレス):8080/bitvisor.elf && boot
最後に、テスト用環境のgrub.cfg
にiPXEのmenuentryを追加します。
menuentry 'BitVisor (iPXE)' {
set root='(/bootパーティションへのパス)'
linux16 /ipxe.lkrn
initrd16 /bitvisor.cfg
}
ビルド用環境の準備
わざわざHTTPサーバを準備するのは面倒なので、ここではシェルスクリプトとnetcatを組み合わせたHTTPサーバもどきで対応します。
(netcatは別途導入しておいてください)
以下の内容をdeploy.sh
としてbitvisor.elf
があるディレクトリへ配置します。
#!/bin/sh
trap exit INT
while true
do
( echo "HTTP/1.0 200 OK"
echo -n "Content-Length: "
wc -c bitvisor.elf | while read a b
do
echo $a
done
echo
cat bitvisor.elf
echo OK > /dev/stderr
) | nc -l -p 8080
done
動作としては、どんなHTTPリクエストに対しても
-
wc
コマンドでbitvisor.elf
のサイズを取得し出力 - その後
bitvisor.elf
の中身を出力
の動作を行うようなスクリプトをパイプでnetcatに流しこんで8080/tcp
としてlistenしているだけです。
これだとbitvisor.elf
のサイズが変わるたびに再度実行する必要があるので、もっとモダンな仕組みを使って書いても良いかもしれません(RubyのWEBrickとか)
完了!
ここまでできれば、BitVisorのiPXEを使ったネットワークブートの環境が整います。
ビルド用環境でdeploy.sh
を実行し、テスト用環境でBitVisor (iPXE)の項目を選ぶことでDHCPサーバ経由で自動でIPv4アドレスを取得し、指定されたHTTPサーバからbitvisor.elf
をダウンロードしてブートしてくれます。