VIVER CORE計画 案1

分散ファイルシステムの件が進みそうにないので、できそうなところから埋めていくのが良いと思った。そもそも分散ファイルシステムの件もVIVER COREも、最終的な目標は同じわけで。分散メタネームサーバーはRinda/RingServerで実装できそうな。(既に実装されていそうな)


と言うわけで、VIVER COREの計画を進める。WikiFormeはちょっと置いておく。(うーむ。またしても…)


VIVER COREでやること

  • PCIの自動検出
  • カーネルモジュールのロード
    • カーネルに依存しない
    • 現存のカーネルを使用可能にする
    • でもバージョンいくつ以上は制限されるかも…
  • ネットワークの起動
    • ブートパラメータを解析してDHCPと静的IPをサポート
  • /にtmpfsをマウント
    • ブートパラメータから指定を受け付ける。指定がなければ総RAM容量から適当な割合で
  • HTTP/FTP/tftpでルートファイルシステムgzip圧縮されたcpioアーカイブ?)をダウンロードし、/に展開
  • switch_rootして/sbin/initを起動


ネットワークブートマネージャとでも言うのだろうか。
debootstrapなど、ハードウェアに依存せずにルートファイルシステムだけを作るプログラムが増えてくるだろうと勝手に予想している。コンテナ系仮想化の影響。そうすると、VIVER COREの旨味が増す。仮想化用システムを作るのと同じ手順で、VIVER CORE用システム(=ネットワークブートできる)が作れる。



VIVER COREでやらないこと

  • ルートファイルシステムの作成支援はしない
    • しなくて良いようにする。どのように作ってもブート可能なようにVIVER COREを作る
    • VIVERの方針。カスタマイズしまくればネットワークブートできるのは当然
  • DHCPサーバーの自動設定はしない
    • DHCPサーバーは既存のネットワークと競合してしまう
      • 競合しない方法があれば採用
      • 無いかなぁ
    • ブログでHowToを書いた方が実用的だと思う
      • PXEの設定は難解で、ブログの情報もイマイチ少ない。古い情報がほとんど(DSAS開発者の部屋で書いていただけると嬉しい!)
    • ネットワークブート以外はレイヤーが違う仕事
      • 次期RUNESで
  • Copy-on-Writeには立ち入らない(全部tmpfs)
  • USBデバイスの判別はたぶんしない。決め打ちでusb-storage
  • ファイルシステム判別はたぶんしない(するかも)
  • ストレージドライバは決め打ちでロードする
  • ドライバのロード以上のハードウェア認識はしない


VIVERと比べてやらないことが多い!割り切りが重要。できないことはできない!

またしてもVIVER CORE単体では役に立たない。私が作っているものってそんなモンばっかりっすなぁ。うへ。



実装の方針

initramfsはuClibc環境。busyboxrubyインタプリタを内蔵する。
プラガブル/拡張可能性は目指さない。initramfs自体はall-in-one。

ハードウェア認識

ハードウェア検出は2段階に分ける。1つはinitramfsの中。もう1つはswitch_root後。initramfsの中に入れるカーネルモジュールは最小限にし、サイズを抑える。
initramfsに入れるカーネルモジュールは以下(Linux 2.6.22の場合)

drivers/hid  # usbkbdが無いといろいろ困る
drivers/pcmcia  # 要らない?
drivers/block/loop.ko # ルートファイルシステムのダウンロード用で必要かも
drivers/block/nbd.ko  # ルートファイルシステムのダウンロード用で必要かも
drivers/net
net/packet
fs/squashfs  # ルートファイルシステムのダウンロード用で必要かも
fs/nfs
fs/nfs_common
fs/smbfs  # smbfsでネットワークブートをサポートか?

これで約8MB(非圧縮)


USBのNICは使えないことにする。それから無線LANではブートできないことにする。無線LAN…うーむ。まだ要らないと思う。
それからinfinibantなんて要らないよね…iSCSIは欲しいかも?(でもNBDでいいような)
IPv6はまだ必要ないと思う。IPv4カーネル組み込みになっていることを期待。(要調査)


起動したら/procと/sysをマウントし、最初にPCIバイスの自動検出を行う。そしてカーネルモジュールをロード。ここでロードするモジュールは以下。

  • PCIバイスの自動検出で発見されたモジュール
  • usbhid, usbkbdとその依存関係
  • af_packet
ネットワークの起動

ブートパラメータの解析+コマンドの実行で。ブートパラメータの書式は以下。

# これは自動で行われる
ifconfig lo 127.0.0.1 netmask 255.0.0.0

# 静的IPの場合
ifconfig eth0 192.168.0.2
route add default gw 192.168.0.1
dns 192.168.0.1

# DHCPの場合
dhcp eth0

これをサーバー側でDeflate+Base64にしてブートパラメータに渡す。(こうしないとパラメータが長くなりすぎる。どうも制限が256文字らしい。include/asm-i386/setup.h #define COMMAND_LINE_SIZE 256)

str = ARGF.read.split("\n").join(";")
str = ";" + str
str.gsub!(/  */, " ")
str.gsub!(/; +/, ";")
str.gsub!(";ifconfig", ";i")
str.gsub!(";dns", ";d")
str.gsub!(";route add default", ";rf")
str.gsub!(";route add", ";r")
str.gsub!(";route", ";o")

zdata = Zlib::Deflate.deflate(str, Zlib::BEST_COMPRESSION)
bootarg = Base64.encode64(zdata)


initramfs側では、これを解釈して、逐次実行していく。指定がなければdhcp eth0と判断。


ルートファイルシステムのダウンロード

まず/sysrootにtmpfsをマウントする。サイズは、ブートパラメータで指定があればそれを使う。指定がなければ、できる限りたくさん。後でremountして減らす。(tmpfsって減らせたっけ?)


ダウンロード元は、ブートパラメータで指定する。これは必須のパラメータ。指定がなければエラー。
指定方法はURL。ダウンロードにはbusybox内蔵のwget、またはtftpを使う。2つ以上指定されていたらランダムで選択する。負荷分散用。サポートするプロトコルは以下。

  • HTTP
  • FTP
  • TFTP
  • V-FIELD (?)
  • NBD (?)
  • NFS (?)
  • SMBFS (?)


ファイルのフォーマットは、デフォルトはgzipされたcpioアーカイブwget|gzip|cpioとパイプでつないで、/sysrootに展開する。ブートパラメータで変更可能。Buxyboxでlzmaがサポートされているらしいので、ネットワークに負荷をかけたくない場合はlzmaが良いかも。

サポートするフォーマットは以下。

switch_root

/sysrootにダウンロードが完了したら、サブインタプリタをforkしてchrootし、2回目のハードウェア認識と、初期設定を行う。

  1. /procと/sysをマウント
  2. PCI検出
  3. モジュールをロード
  4. /etc/fstabと/etc/mtabの記述をHack
  5. /procと/sysをアンマウント


これが終わったら、switch_rootして/sbin/initを起動する。その後は/usrをNFSでマウントするなり(fstabに書いておく)、V-FIELD+squashfs+aufsで/usrをマウントする!なり、好きにしていただく。ネットワークが落ちても大丈夫なので、何をやっても可。/のファイルシステムがtmpfsなのと、/etc/fstabと/etc/mtabがhackされている以外は、通常の環境と同じ。




ツール

VIVER COREを作るツールが必要。カーネルモジュールをinitramfsに組み込み、gzip+cpioで圧縮する。たぶん簡単なシェルスクリプトで済む。

$ sudo mkinitvcore  [path to kernel module /lib/modules/`uname -r`]  <output file name>


それから、debootstrapなどで作ったルートファイルシステムを、gzip+cpioで圧縮するツール。これも簡単なシェルスクリプト

$ sudo mkvcoreroot  <path to root filesystem>  <output file name>  [-f gzip+cpio|lzma+cpio]  [-e exclude path]  [-e exclude path]


先のブートパラメータをDeflate+Base64するツール。
thttpd、tftpd、pxelinux、dhcpdを含む簡易ブートサーバーパッケージ。コレ1本でブートサーバになります的な。chrootして使用。uClibc環境。(glibcでいいかな)