戻る
苦情をメールする

FreeBSD の diskless メモ FreeBSD のディスクレスオペレーション netboot の PCI ELF の細工 PXE で FreeBSD のディスクレスオペレーション etherboot で FreeBSD のディスクレスオペレーション Indy を NetBSD でディスクレスオペレーション FreeBSD 4.4 の ディスクレス メモ FreeBSD 5.5 の ディスクレス メモ FreeBSD 6.1 の ディスクレス メモ
FreeBSD BOX が何台もあると、うるさい。diskless で静かに仕事をしよう。 部屋では、静に音楽でも聞きながら、優雅に物事を考えよう。 現状は netboot なマシンと、PXE なマシンと、etherboot なマシンの混成になって しまっている。もっとシンプルにしたいけれど、まあ動いているから良しとするか。 diskless への手順は何処にでも紹介されているので、ここでは応用可能なように なるべく、どうすれば出来るのか、どうして出来るのかをメモとして残すことにする。
3種類の方法が考えられる。 netboot、etherboot、PXE の3種は、どれも少しずつ仕組みが違う。 違いを並べてくれているページがあれば、有難いんだがね。 RPLも考えられるが、RPLで netbootのバイナリを取って来て netboot するくらいしか 思い付かないので、探求しないことにする。 Lanworks の Managed PC Boot Agent (MBA) も考えられるが、知らないふりをする。 1999年あたりに TCO削減」というスローガンのもと、Managed PC のために いろんな方法が提案されて、その一部が PXEや MBAということになるか。
FreeBSD 2.xなら、 1. netboot が、bootp ( と tftp )で パラメタを得て、 rpc で nfsから a.out な kernel を持ってくる。 netboot から kernel へは struct nfsdiskless で、情報を渡す。 これは、ハンドブックなどに十分なドキュメントがあるので、手順は省略。 bootp のあと、tftp でマウント情報を渡すような解説が多いが、 bootp の vender extention を十分に書けは、tftp は不要。 NICカードに netboot な ROM を刺しても良いし、DOSな FDから netboot起動も可。 NE2000 とか 3C509 の NICなら、netboot が用意されている。 netboot をつかった diskless は、どこにでも手順が紹介されているので入門用。 /etc/bootptab のサンプル .netboot:ht=ether:sm=255.255.255.0:\ :bf=/kernel:\ :T128="192.168.1.1:/swapfs":\ :vm=rfc1048 nb:ha=000102030405:ip=nb.akiba.to:\ :rp="192.168.1.1:/rootfs/nb":\ :tc=.netboot: isc-dhcp を使うなら、/usr/local/etc/dhcpd.conf option domain-name "akiba.to" ; option domain-name-servers ns.akiba.to ; option routers lulu.akiba.to ; option subnet-mask 255.255.255.0 ; subnet 192.168.1.0 netmask 255.255.255.0 { } group { filename "/kernel" ; always-reply-rfc1048 on ; option option-128 "192.168.1.1:/swapfs" ; host nb.akiba.to { hardware ethernet 00:01:02:03:04:05 ; fixed-address pv.akiba.to ; option root-path "192.168.1.1:/rootfs/nb" ; } } でも、isc-dhcp-2.0.5 では、 option option-128 "192.168.1.1:/swapfs" ; がうまく乗らない。 ( iscの dhcpは信用できない。) そのうえ、option-xxx に、netboot が理解できないようなものを付けると うまく動かない様なきがする。 サーバ 192.168.1.1 に /swapfs/swap.192.168.1.xx 大きな swap 用ファイルと /rootfs/nb/ 以下に ルートディレクトリを作っておく。 192.168.1.xx は nb.akiba.to の IP address 2. FDに kernel だけ入れときゃ良いじゃん。 kernel が bootp して動くことは出来る。 options BOOTP BOOTP_NFSROOT などを参照。 でも kernel が MACアドレスを頼る。 3. MACアドレスに頼りたくないよね。 NICなんか、取り換えるかもしれないし、違う NICから欲しい環境を起動したこともあるかも。 netbootな FDに パラメタ ( ip netmask gateway server kernel ) を 書いとけば良いじゃん。でも netboot がその様には出来ていない。 なにがしたいかというと FDか HDで起動する。 kernel は、ネットワーク越しに取って来ても FD HD に書いてあっても良い。 FD HD は起動後に止める。 あとは静か。 MACアドレスに頼ると、bootptab を書換えるのがナンセンス。 さらには、FreeBSDの release が上がるたび、diskless 専用の kernelを作るのも 面倒だ。 できれば release の GENERIC で済ませたい。 そのためには、xxboot が kernel に root と swap を、 自由に教えることができれば良いだけ(のはず)。 <machine/bootinfo.h> の struct bootinfo と <nfs/nfsdiskless.h> の struct nfsdiskless にセットして kernel に渡せば良いだけなのだが。 どなたか教えてください
FreeBSD 3.xなら簡単にできそうなんだけれども。 FreeBSD 3.x の bootstrap は3ステップある。 /usr/src/sys/boot/i386 から出来る /boot/boot{0|1,2} が ( boot0 はパーティションから select, boot1 は即boot。) ( /usr/src/sys/i386/boot/ からできる /usr/mdec/boot{1,2} ではない ) ELFである /boot/loader か /kernel を load する。 後者なら簡単。(でもどうやってパラメータ渡してるんだろう?) 前者のばあい /boot/default/loader.conf なんかを読みながら kernel を load し、パラメタを渡す。 ここで、root と swap が nfs越しだと伝えれば良いのだが。 3.x からは diskless への配慮があるが、それは余計なお世話に近いものかもしれない。 /var や /dev は mfs につくり、/etc の一部を mfs 上の /conf/etc へ移す。 /usr は readonly でマウントして、共有化を目指す。 何台もあると、管理上では楽になるかもしれない。 サーバ側のディスクスペースは十分なので、あまりありがたくもない。
PCI ELF netboot の小細工 /usr/src/sys/i386/boot/netboot に、a.out な kernel を netboot できる コードがある。でも、ISA なカード用なんだよね。 いまさら ISAなカードなんて、マザーボードに刺さらないよ。 そこで、PCIバス をスキャンして、目的のカードをさがし、BIOS がマップした I/Oを見て netboot するように改造した。 ROM化する場合は、初期化の時に、POSTが AXに PCIの ディバイス情報を 入れてくるので、自分の PCIの情報を得て、I/O を得るべきなのだが、 簡単にはいかない。 リアルモードとプロテクトモードのごちゃませコードを書く元気は無いし。 どこに POSTからの情報を隠しておくのかも難しい。 ELF をロードできれば FreeBSD 3にも使えそうで、完璧なのだが。 でも、16KByte のROMに入りきるかな? struct nfsdiskless が合ってるかな? うーんとうなって、ELFもロードできるようにした。 3.4がネットブートできたが、詰め切れていない。 でも、毎日使ってるよ。 ...なんて苦労をしたら、ports/net/etherboot なんてものが 世の中にはあるんだね。 ちょっと触って見ようか... と思っているうちに 世の中は FreeBSD 4.x になってしまう。
PXEで FreeBSD のディスクレスオペレーション そして世の中は FreeBSD 4.x になった。 せっかく作った netboot の小細工も FreeBSD 4.x では nfsdiskless の構造が 合っていない。 いまさら作り直すのも面倒だ。 ここは標準化手順でいこう。 デファクトスタンダードになりそうなのは PXEかな? と、最初は思った。 クライアント を pxe、サーバを server とする。 serverの /rootfs/pxe の下に pxeのファイル構造を / からコピー。 serverの /etc/inetd.conf を触って、tftpサーバ を動かす。 pxeの /boot/pxeboot を serverの /tftpboot/pxeboot に コピー。 pxeの etc/rc.conf に root_rw_mount="YES" swapfile="/xxxx" <- てきとうに大きなファイルを作っておく 普通は、以下の様に DHCPサーバを用意する。 serverに dhcp-2.xx を pkg_add し、/usr/local/etc/dhcpd.conf に option domain-name "akiba.to" ; option domain-name-servers ns.akiba.to ; option routers router.akiba.to ; subnet 192.168.1.0 netmask 255.255.255.0 { } host pxe { hardware ethernet 00:01:02:03:04:05 ; server-identifier server.akiba.to ; option dhcp-client-identifier "PXEClient" ; fixed-address pxe.akiba.to ; filename "pxeboot" ; option root-path "/rootfs/pxe" ; # または option root-path "192.168.1.1:/rootfs/pxe" ; # nfs するサーバが違うなら } として /usr/local/sbin/dhcpd を動かしておく。 pxe は、あっさりと動く。 まず pxe上の PXEな NIC は DHCPで、アドレスと /tftpboot/pxebootの場所を知る。 PXEな NICは TFTP で /tftpboot/pxeboot を得る。 pxeboot は、PXEな NICの力を借りて、server:/rootfs/pxe の場所を知り、 server:/rootfs/pxe/kernel を ロードして、server:/rootfs/pxe を ルートとして mount することを kernel に伝える。 やっていることは、まどろっこしくも感じるが、 pxeboot と kernel が組なところが憎いよね。 pxeboot が提供されるかぎりは、FreeBSD 5.x 以上になっても 他の OSであっても OK。 しかし、DHCPを用意するのは面倒だ。( 信用できないし ) 既に ether segment 上に、グローバルアドレスの DHCPサービスが動いていて、 イントラネット空間で FreeBSDのディスクレスをしたい。 そのためだけに、DHCPサーバを競合しないように用意しなければならない。 競合しない様に設定できる DHCPサーバが無いんだよね。 というわけで、akiba.to では、dhcps の代わりに bootpdで無理矢理しゃべる。 serverの /etc/inetd.conf を触って、bootpサーバ を動かす。 /etc/bootptab に、 pxe:ha=000102030405:ip=pxe.akiba.to:\ :dn=akiba.to:ds=dns.akiba.to:gw=gateway.akiba.to:sm=255.255.255.0:\ :bf=pxeboot:\ <- tftpファイル :rp="/rootfs/pxe":\ <- root path :T53=0x05:\ <- 無理矢理 DHCP:ACK にする :T54=0xC0A8010C:\ <- server.akiba.to のアドレスを HEX で書く :vm=auto: おお、こんなに適当な返事なのに、ちゃんと動くぞ。Intelは、えらい。 Intel 82559 の PXEでも、3COM の 3C905B の PXEでも動いた。 PXEな NICは Intel と 3COM だけかな? RTL8139 に realtek.com.tw から、RPL & PXE なROMイメージ RTSROM_M.NIC を探して 差して見たが、うまく動かない。 RSET8139.EXE で、ROM を enable にもした。 DHCP パケットが出ている気配も無い。 realtek で うまく動いた方がいらたしゃいましたら情報をください。
etherboot でやりたいな PXEじゃない NICも多いので、etherboot で diskless を やって見ようと思う。 etherboot の ROM image は簡単に手に入るので、ROMに焼くだけですむ。 etherboot は BOOTP の、bf=/xx から elf なバイナリーを tftp してくれるだけ。 しかも DHCP 形式の BOOTPなので、DHCPサーバが返事しちゃうとそのまま受ける 決まった MACアドレスに 決まった IPアドレスをふるのと、一般的な DHCPサービスを 同じセグメントで分けて管理したい事情がある。 普通の人には関係ない、これは サイト akiba.to の中での話。 そこで、etherboot の DHCPのオプションを外してコンパイルしなおす。 ELF な kernel を tftp してもらった後は、kernelの自力で なんとかしなければならない。 netboot や pxeboot は、ロードした kernel にマウント情報を渡してくれたが、 etherboot では、kernel が BOOTP かなにかを出し直して、マウント情報を 得なければならない。 ということは、専用の kernel を作んなくちゃいけないってことか。 option BOOTP BOOTP_NFSROOT BOOTP_NFSV3 BOOTP_COMPAT を付けて configure する のがめんどだが、仕方が無い。 bootptab に書くのは、etherboot の為に、 :sa=server.akiba.to:bf="/tftpboot/kernel": これで、etherboot が ELF な kernel を server から持って来てくれる。 kernel が喋る bootp のために、 :rp="192.168.1.1:/rootfs/foo":T128="192.168.1.1:/swapfs": これで、kernel は root と swap を知る。 bootptab は、一回の起動のために、2回参照されるということ。 etherboot 5.0.1 は、ELF の memory size の計算がおかしくて、 kernel をロードできないことがある。 5.0.2 は、直っている。 isc-dhcp を使うなら、/usr/local/etc/dhcpd.conf option domain-name "akiba.to" ; option domain-name-servers ns.akiba.to ; option routers lulu.akiba.to ; option subnet-mask 255.255.255.0 ; subnet 192.168.1.0 netmask 255.255.255.0 { } group { filename "/tftpboot/kernel" ; option option-128 "192.168.1.1:/swapfs" ; host eb.akiba.to { hardware ethernet 0:01:02:03:04:05 ; fixed-address eb.akiba.to ; option root-path "192.168.1.1:/rootfs/eb" ; } } bootp を使うなら、/etc/bootptab .etherboot:dn=akiba.to:ds=ns.akiba.to:gw=lulu.akiba.to:sm=255.255.255.0:\ :sa=lulu.akiba.to:bf="/tftpboot/kernel":\ :T128="192.168.1.1:/swapfs":\ :vm=auto: eb:ha=000102030405:ip=eb.akiba.to:\ :rp="192.168.1.1:/rootfs/eb":\ :tc=.etherboot:
SGI Indy を NetBSD で diskless BigEndian MIPS のクロスの組み込み開発環境がうまく作れない。 めんどうだから、Big MIPS なマシーンの上でコンパイルすれば良いじゃん? さて、NetBSD の Big MIPS は mipsco newsmips sgimips の3アーキテクチャ。 そこで sgi の Indy を掘り出す。 ところが sgimips では、NetBSD の FFSなディスクからブートできない。 つまりスタンドアローンで起動できないんだ。 しかたがないから ネットワークからブートする。 カーネルさえ起動すれば、FFSなディスクをマウントすれば良いのだが、 NetBSD は Indy の SCSIコントローラをサポートしていない。 しかたがないから、diskless で動かそう。 server サーバ側に カーネルイメージ /tftpboot/netbsd.ip22 を用意する。 bootp を使うなら、/etc/bootptab に indy:ha=080069070809:ip=indy.akiba.to:hn:\ :sm=255.255.255.0:lg=192.168.1.1:\ :bf="netbsd.ip22":\ :rp="/rootfs/indy":\ :sa=lulu.akiba.to:vm=auto: を用意する。 isc-dhcp を使うなら、dhcpd.conf に option subnet-mask 255.255.255.0 ; option domain-name "akiba.to" ; option domain-name-servers lulu.akiba.to ; subnet 192.168.1.0 netmask 255.255.255.0 { option routers adsl.akiba.to ; range 192.168.1.200 192.168.1.249 ; } group { host indy.akiba.to { hardware ethernet 08:00:69:07:c3:cd ; fixed-address indy.akiba.to ; option root-path "/rootfs/indy" ; } } こんな感じかな。 ターゲットの Indy の Command Monitor に入る。 シリアルコンソールなら、 System Maintenance Menu 1) Start System 3) Run Diagnostics 5) Enter Command Monitor Option? 5 GUIなら、起動時に ESCして、マウスで Command Monitor を選ぶ setenv diskless 1 setenv bootfile bootp()server:/xxx setenv SystemPartition bootp()server:/tftpboot setenv OSLoadPartition bootp()server:/xxx setenv OSLoader netbsd.ip22 setenv netaddr 192.168.1.17 printenv -> 念の為 boot すると、indy は bootp を出す。 set bootfile xxx は必要ないかもしれない。 setenv netaddr 192.168.1.17 と、ip=indy.akiba.to が、一致していなければならない。 ついでに、起動の音楽がうるさければ、 setenv volume 8 xxx のところは良く判らないので、試行錯誤する。 Command Monitor に setenv した値と、bootp が返す値の関係が いまひとつ理解できない。 さて、indy は bootp を聞くと、server:/tftpboot/netbsd.ip22 を tftp しにくる。 COFF でも、ELF でも受けて起動する。 server の /etc/inetd.conf に tftp dgram udp wait root /usr/libexec/tftpd tftpd -s /tftpboot のように、tftpd -s で /tftproot に chroot するようにオプションが付いているなら indy の Command Monitor で setenv SystemPartition bootp()server:/ とする。 以下は、NetBSD流の Diskless オペレーション共通だが、 起動したカーネルが BOOTP を出して、ルートディレクトリを :rp="/rootfs/indy": を見て、nfs mount しにくる。そのなかの /etc/fstab に 192.168.1.1:/swapfs/indy none swap sw,nfsmntpt=/swap としておく。 swap無しで良いなら、これは必要ない。 目的の Big MIPSの開発環境はどうなったか」って? 遅くてしようがないのと、うまく行かないのはおんなじ。
FreeBSD 4.4 RELEASE の diskless メモ kernel が nfs mount なファイルシステムから動いた時に ro でマウントされるようになった。 それが正しい ( か? )。 /etc/rc.conf で root_rw_mount="YES" を忘れずに。 でも、どうも 4.4 は panic するなー。 kernel 本体ではないような気がするが、探求する暇もない。 FreeBSD 4.5 では、panic は無く、いまのところ快調。
FreeBSD 5.5 の罠 FreeBSD 5.5 では、rpc.lockdがよろしくない。 FreeBSD 4.11 までは、lockd の調子も良かったのだが、 FreeBSD-5 FreeBSD-6 では、期待の通りには動いてくれない。残念。
FreeBSD 6.1 の罠 FreeBSD 5と 6では、lockd に問題がある。 FreeBSD 6 では、vipwが master.passwd を lock できないと言って 動いてくれない。これは致命的だ。 こういう細かいことを直さないと diskless できないのは、ちょっと困るなー。 今思えば FreeBSD 4.11 は快適だった。
戻る 苦情をメールする