1FD FreeBSDの世界

遠い昔に自分のwebサイトで公開していたデータが出てきたので、半ば保存目的でnoteにコピーしておきます。

1FD FreeBSDとは

1FD FreeBSDとは、フロッピーディスク1枚で起動するFreeBSDシステムのことです。たった1474560バイトの中に、いかにしてマトモに動作するFreeBSDシステムを詰め込むかという試みです。
しかし、最近は大容量のハードディスクが安価に手に入る時代です。フロッピー1枚に、FreeBSDと、例えばSambaやApacheを詰め込んでサーバにする、という手段もありますが、バージョンアップ時の面倒さや、フロッピーディスクの信頼性、その他を考えると、大容量のハードディスクに普通にシステムを構築した方が結局は楽、という結論になってしまいます。
よって、googleでネット上を検索してみても、趣味人が1FD Router等を古い(2.x系、3.x系、せいぜい4.7辺りの)バージョンのFreeBSD(やLinuxとか)を使って構築した、という記録が見つかる程度でした。

1FD FreeBSDの本領発揮!

そろそろ時代錯誤的となってしまった1FD FreeBSDの世界。コレが本領発揮する用途を考えてみました。

  • 1FD ハードディスクデュプリケータ

  • 1FD ハードディスク完全消去ユーティリティ

以下、これらのシステムの構築方法と使い方を解説したいと思います。また、ダウンロードしてフロッピーなりCDROMに焼きこめばそのまま使えるイメージも用意しましたので、興味のある方は試してみてください。(注:この部分は原文ママなので、イメージは存在しません)

1FD FreeBSD カーネル構築編

1FD FreeBSDに必要なユーティリティを詰め込む前に、まずはOS自体の構築方法について解説します。

必要なもの

  • FreeBSDが動作するパソコン一台

  • フロッピードライブ

  • マトモなフロッピーメディア(CDRメディアに、フロッピーのブートイメージとして焼いちゃっても良いかもしれません。)

まずは普通にFreeBSDのインストール

1FD FreeBSDを作るには、まず普通に(ハードディスクに)インストールしたシステムが必要になります。
このFreeBSD上で、フロッピーに収まるカーネルを構築したり、crunchされたshをはじめ各種ツールのバイナリを作成するわけです。 FreeBSD5.x以降は、カーネル周りのディレクトリレイアウトが変わったため、1FDに収めるためにどうしたら良いか良く分からんので(おい)、FreeBSD4.11-Releaseをベースにしました。
これを書いている現在(2006年9月)、4.11Rは少々古い感じはするものの、obsolereされている訳でもないし、安定性や対応ハードウェアの面においても不自由は無いので、問題は無いでしょう。
(2006/10追記:FreeBSD6.1Releaseで試してみましたが、機能を削りまくったカーネルを作成しても、圧縮後のサイズが1.5MB程になってしまったため、やはり4.11で作るのが現時点では最良のようです)

FreeBSDのインストール方法

普通にインストールすれば良いです。ソースファイルは全て展開しておいた方が良いでしょう。(ま、kernelのソースと、bin,sbin,ubin,usbin辺りだけあれば良い筈ですが)
FreeBSDのインストール方法については省略します。

1FD FreeBSD用カーネルの構築

この辺からが本番です。
FreeBSDのインストールはした事があっても、カーネルの再構築は経験が無い人も居ると思いますので、ちょっと丁寧に書いてみます。
カーネルの設定ファイルは、/usr/src/sys/i386/conf/ にあります。GENERICってのがデフォルトの設定ファイルです。
このGENERICを元にして、1FD FreeBSD用のカーネルコンフィグファイルを作成します。

# cd /usr/src/sys/i386/conf
# cp GENERIC FD
# vi FD

1FD FreeBSDには、NFSで何かをマウントする予定があるならともかく、普通はNFSは不要だと思います。また、SCSI関係やCDROM関係も要らないと思います。ISA NIC関係は要らないと思いますが、PCIなNICに関しては、稼動開始後にNICが壊れて入れ替えたりとか、あるいは1FD ディスクデュプリケータのように、稼動させるシステムが決め打ち出来ない場合を考え、全て残しておきました。
この辺は各人の状況に合わせて設定してください。参考までに、私のコンフィグを書いておきます。

machine i386
cpu I486_CPU
cpu I586_CPU
cpu I686_CPU
ident "1FD_FreeBSD"
maxusers 0
options INET
options FFS
options MFS
options MD_ROOT
options COMPAT_43
device isa
device pci
device fdc0 at isa? port IO_FD1 irq 6 drq 2
device fd0 at fdc0 drive 0
device ata
device atadisk
device atkbdc0 at isa? port IO_KBD
device atkbd0 at atkbdc? irq 1 flags 0x1
device vga0 at isa?
device sc0 at isa? flags 0x100
device npx0 at nexus? port IO_NPX irq 13
# PCI Ethernet NICs.
device de # DEC/Intel DC21x4x (``Tulip'')
device em # Intel PRO/1000 adapter Gigabit Ethernet Card (``Wiseman'')
device txp # 3Com 3cR990 (``Typhoon'')
device vx # 3Com 3c590, 3c595 (``Vortex'')
device miibus # MII bus support
device dc # DEC/Intel 21143 and various workalikes
device fxp # Intel EtherExpress PRO/100B (82557, 82558)
device pcn # AMD Am79C97x PCI 10/100 NICs
device rl # RealTek 8129/8139
device sf # Adaptec AIC-6915 (``Starfire'')
device sis # Silicon Integrated Systems SiS 900/SiS 7016
device ste # Sundance ST201 (D-Link DFE-550TX)
device tl # Texas Instruments ThunderLAN
device tx # SMC EtherPower II (83c170 ``EPIC'')
device vr # VIA Rhine, Rhine II
device wb # Winbond W89C840F
device xl # 3Com 3c90x (``Boomerang'', ``Cyclone'')
device bge # Broadcom BCM570x (``Tigon III'')
pseudo-device loop # Network loopback
pseudo-device ether # Ethernet support
pseudo-device md # Memory "disks"
options ATKBD_DFLT_KEYMAP # specify the built-in keymap
makeoptions ATKBD_DFLT_KEYMAP="jp.106"

さて、コンフィグが出来たらカーネルの構築です。

# config 1FD_FreeBSD
Don't forget to do a ``make depend''
Kernel build directory is ../../compile/1FD_FreeBSD
# cd ../../compile/1FD_FreeBSD/
# make cleam
# make depend
# make

make installしてしまうと、今稼動しているシステムのカーネルを置き換えてしまうので注意してください。もし万が一make installしてkernelが書き換わってしまった場合は、

# cd /
# chflags noschg kernel
# cp kernel.GENERIC kernel
# chflags schg kernel

で元に戻ります。kernelは大変重要なファイルなので、誤って消去できないよう、削除不可フラグが立っています。何かしらの事情で消去なりする必要が生じた場合は、chflagsでフラグを変更してから操作します。
以上の操作で、新しいカーネルが /usr/src/sys/compile/1FD_FreeBSD/kernel に出来ました。
次は、crunchされた各種プログラムを作成します。

Crunched Binary作成編

Crunched Binaryとは

1FD FreeBSDのカーネルを作成したら、次はcrunchされたバイナリを作成します。crunched binaryとは、引数の取り方によって挙動を変える、実体としては単一のバイナリファイルです。
例えば、"prog"という単一のバイナリに、cat,ls,cd,dd,pingという複数の機能を持たせて、

# prog cat /etc/services ←"cat /etc/services" と同じ動作をする
# prog ls /usr/local/ ←"ls /usr/local/" と同じ動作をする
# prog cd /etc/ ←"cd /etc/" と同じ動作をする
# prog dd if=/dev/ad0 of=/dev/ad4 ←"dd if=/dev/ad0 of=/dev/ad4" と同じ動作をする
# prog ping 192.168.0.5 ←"ping 192.168.0.5" と同じ動作をする

…と言った具合です。たくさんの機能を詰め込めばそれだけサイズは大きくなりますが、コマンドを厳選してやれば、十分にフロッピー1枚に詰め込むことができます。
それでは、crunched binaryの作り方を説明します。

必要なコマンドを挙げる

まず最初に、どのコマンドを詰め込むか取捨選択します。とりあえず私が選んだものは以下の通りです。

bzip2
cat
dd
gzip
ifconfig
init
ls
mount
ping
sh
shutdown
umount

ここまでが、FreeBSDのシステムで標準で用意されているコマンドです。

tcpclient
tcpserver

この二つは、ネットワーク経由でのHDイメージ送出・受取に用います。
tcpserverは、DJBのucspi-tcpに入っているものを使いました。入手元は、

http://cr.yp.to/ucspi-tcp/install.html

です。DJBは好き嫌いが分かれるとは思いますが(笑)。
システムに標準で用意されていない外部プログラムをcrunched binaryに取り込むテクニックはこの後で示します。

作業ディレクトリの作成

どのコマンドを取り込むかを決めたら、作業ディレクトリを作ります。私は、/root/fd/ に1FD FreeBSD作業用ディレクトリを作ったので、更にその下にcrunchディレクトリを作成し、そこで作業することにしました。フルパスは/root/fd/crunch/ になります。

実行バイナリ名の決定

crunche binaryの名前を決めます。これは別に何でもいいのですが、私は"execimg"にしてみました。

crunchgen設定ファイルの作成

いよいよ、crunched binaryの作成に入ります。まずは設定ファイルを作ります。
私は"execimg"というバイナリ名にしたので、/root/fd/crunch/execimg.conf という設定ファイルになります。
このファイルの内容は以下の通りです。

srcdirs /usr/src/bin
srcdirs /usr/src/sbin
srcdirs /usr/src/gnu/usr.bin
srcdirs /root/fd
srcdirs /usr/src/usr.bin
libs -lcrypt -ll -lm -lutil -lbz2 -lipx -ledit -ltermcap -lgnuregex

#/bin
progs cat dd ls sh
#/sbin
progs ifconfig init mount shutdown umount
#/usr/bin
progs bzip2 gzip
#others
progs tcpclient tcpserver

この内容で設定ファイルを保存しました。
さて、この段階で早速crunchgenを実行すると、

# crunchgen -f execimg.conf
crunchgen: warning: could not find source directory: execimg.conf: tcpclient
crunchgen: execimg.conf: tcpclient: warning: could not find any .o files
crunchgen: warning: could not find source directory: execimg.conf: tcpserver
crunchgen: execimg.conf: tcpserver: warning: could not find any .o files
crunchgen: execimg.conf: tcpclient: ignoring program because of errors
crunchgen: execimg.conf: tcpserver: ignoring program because of errors
Run "make -f execimg.mk" to build crunched binary.

と言われてしまいます。
要するに、標準でシステム内に用意されているプログラム以外は、ソースファイルのある場所が分からん!と言われてるわけです。
そこで、まずはそのソースディレクトリを用意します。

tcpclientとtcpserverの展開、コンパイル、ソースディレクトリの準備

ucspi-tcp-0.88.tar.gzを、/tmpで展開しました。

# tar xvfz ucspi-tcp-0.88.tar.gz

すると、/tmp/ucspi-tcp-0.88/ にソースが展開されます。ここに移動してmake。

# cd ucspi-tcp-0.88
# make

これでオブジェクトが作成されます。次に、crunchgenの要求により、コマンド名に対応するディレクトリを作成し、そこに必要なファイルをコピーしてやります。

# mkdir /root/fd/tcpclient
# mkdir /root/fd/tcpserver
# cp * /root/fd/tcpclient/
# cp * /root/fd/tcpserver/

これでやっとcrunchgenが通・・・りません。試しにやってみると、

# crunchgen -f execimg.conf
crunchgen: execimg.conf: tcpclient: warning: could not find any .o files
crunchgen: execimg.conf: tcpserver: warning: could not find any .o files
Run "make -f execimg.mk" to build crunched binary.

と言われるはずです。
FreeBSD日本語マニュアルによると、

crunchgen ユーティリティは特殊な要件をパッケージの Makefile に課しており、このことが原因で Makefile が非 BSD ソース用に使えなくなっています。特に、 Makefile はターゲット depend を含むことが必要であり、全オブジェクトファイルを変数 OBJS で定義することが必要です。場合によっては、偽のMakefile を使えるでしょう。 crunchgen は、ソースディレクトリ foo 中のMakefile を見る前に、現在のディレクトリ中の Makefile.foo を見ます。

とあります。そこで、tcpclientとtcpserver用に、それぞれのディレクトリのMakefileを書き換えます。
/root/fd/tcpclient にあるMakefileは、

PROG = tcpserver
OBJS = tcpserver.o rules.o remoteinfo.o timeoutconn.o cdb.a dns.a time.a unix.a byte.a

と書き換えます。同様に、/root/tcpserver/Makefile は、

PROG = tcpclient
OBJS = tcpclient.o remoteinfo.o timeoutconn.o dns.a time.a unix.a byte.a

と書き換えました。これで、crunchgenを実行してみます。

# cd /root/fd/crunch/
# crunchgen -f execimg.conf

エラーが出なければOKです。さて、この段階でmakeを実行しても、まだエラーとなるはずです。
原因は、execimg.mkの中で、tcpserverとtcpclientの部分で、"make depend;make~"の部分に対応するMakefileの記述が、それぞれのビルドディレクトリにあるMakefileに記述されていないためです。
しかし、tcpserverやtcpclientを作成するのに必要なオブジェクトファイルは既にあるので、execimg.mkの該当部分を単に削除してやるだけでmakeが通るはずです。

(この辺の実機の記述を記録し忘れたため、後日追ってこの部分記述する予定)

# make -f execimg.mk
(途中省略)
cc -static -o execimg execimg.o cat.lo dd.lo ls.lo sh.lo ifconfig.lo init.lo mount.lo shutdown.lo umount.lo bzip2.lo gzip.lo tcpclient.lo tcpserver.lo -lcrypt -ll -lm -lutil -lbz2 -lipx -ledit -ltermcap -lgnuregex
strip execimg

エラーが出なければ、無事crunched binary作成完了です。
エラーが出る場合のチェックポイントは、

  • execimg.confの中で、必要とするライブラリの列挙に漏れが無いか

  • システム標準で用意されているツール以外のものを取り込んだ場合、Makefileが要求仕様通りか

といった辺りをチェックしてみてください。
Makefileを書き換えたりと、少々敷居が高いですが、この方法で実際に問題なくコンパイルできていますので、大丈夫だと思います。
カーネル、クランチバイナリが作成できれば、次はいよいよフロッピーの作成です。

1FDディスクイメージ作成

わざわざ1FDイメージファイルを作成する理由

1FD用のカーネルを作成し、shをはじめとしたcrunchされたツールを準備したら、次は1FDのディスクイメージの作成です。
これは何故かと言うと、実体としてのフロッピーディスク上には、圧縮されたカーネルと1FDのイメージを用意し、ブートローダからカーネルをメモリに展開、そして圧縮された1FDのイメージをメモリ上に展開し、そのイメージをマウントして動作させるという動きになるからです。
勿論、カーネルやツールを圧縮することなく1FDに収められればそんな面倒なことは必要ないのですが、機能を削ったカーネルだけでも1.8MBほどあるため、こういった面倒な手法を使わざるを得ないのです。
さて、メモリ上に展開する1FDのイメージを作成します。

# cd /root/fd/
# dd if=/dev/zero of=mfsroot.img count=1440 bs=1024

これでひとまず1.44MBの空のファイルが出来ました。

# vnconfig -s labels -c /dev/rvn0 mfsroot.img

これで、作成したファイルを仮想的にマウントできるようになります。そして、ファイルシステムとしてマウント可能にするため、ディスクラベルを書き込みます。これは、「俺は1.44MBのフロッピーだよ?」と宣言するためのもので、これが無いと正常にマウントできないという具合。

# disklabel -w -B vn0 fd1440

そして、ファイルシステムを作成。

# newfs -i 4000 -o space -m 0 /dev/rvn0c

これでマウントして読み書きできるようになります。

# mount /dev/vn0c /mnt

以降、展開後のフロッピーイメージを/mntに対して構築していきます。その実体は/root/fd/mfsroot.imgにあり、作業終了後は/mntをアンマウント、そしてmfsroot.imgを圧縮してフロッピーにコピーしてやるわけです。

1FD ディスクイメージ上にディレクトリを作成

1FDイメージ上にディレクトリを作成します。

# cd /mnt
# mkdir dev etc fd

この中でfdというのは、圧縮されたFDイメージが展開された後、元の物理的なフロッピーは切り離されてしまう(マウントされない)ため、改めて物理的なフロッピーディスクをマウントし直すために作ってあります。
起動シーケンスの中で元のフロッピーディスクをマウントし、そこに記述した起動スクリプトを実行することで、設定を柔軟に変更することが出来るわけです。
(1FDイメージファイルの構成を変えるためには、一旦vnデバイスに結び付けてマウントし、マウントした上で作業して、それを再度圧縮してフロッピーに書き戻すという非常に面倒な作業になるので、1FDイメージファイルは、一旦出来上がってしまえば、あとは極力いじりたくないわけです)
それから、/binと/sbinを作成します。といっても、/に対するシンボリックリンクですが。

# ln -s . bin
# ln -s . sbin

デバイスファイル作成

# cd /mnt/dev
# cp /dev/MAKEDEV .
# sh MAKEDEV std fd0 ad0

これで必要なデバイスファイルが作成されました。後はMAKEDEVは用済みなので消してしまって構いません。

# rm MAKEDEV

crunched binaryをコピー

既に作成済みのcrunched binaryを仮想FDイメージ上にコピーします。そして、中に織り込んだコマンドの数だけ、ハードリンクを作成します。

# cd /mnt
# cp /root/fd/crunch/execimg .
# ln execimg cat
# ln execimg dd
# ln execimg ls
# ln execimg sh
# ln execimg ifconfig
# ln execimg init
# ln execimg mount
# ln execimg shutdown
# ln execimg umount
# ln execimg bzip2
# ln execimg gzip
# ln execimg tcpclient
# ln execimg tcpserver

/etc/rcを作成

1FDイメージが展開された後実行される/etc/rcを作ります。
といっても、ネットワークの設定その他は、1FDイメージからマウントした物理フロッピーの中に書くので、ここでは単に物理フロッピーのマウントを行うだけでOKです。
以下、/mnt/etc/rcの内容です。

#!/bin/sh
/sbin/mount -r /dev/fd0c /fd
/bin/sh -c '/fd/rc' &
/bin/sh

というわけで、物理フロッピーをマウントし、そこに書いたrcを実行し、shを立ち上げるだけです。

無駄領域をゼロパッド

作成した1FDイメージを圧縮する際、圧縮率を上げるために空き領域をゼロで埋めると良いらしいのですが、実際に処理前と処理後でサイズを比較したところ、むしろ処理前の方が圧縮率が良かったりしました。多分たまたまだと思いますが、それほど劇的な効果がある訳でもなさそうです。(場合にもよるでしょうが)
ギリギリまでコマンドを詰め込んだ場合などは、空き領域をゼロパッドするよりも、一旦dumpして新しく作成したイメージにrestoreしてやると良いみたいです。私はそこまでするほど容量がカツカツでもないので、その効果がどれほどかは良く分かりません。
一応、ゼロパッドの方法は、

# dd if=/dev/zero of=/mnt/a
# rm /mnt/a

といった具合です。
余談ですが、Windowsのシステムディスクなどは、defragした後空き容量をゼロパッドすることにより、物理ディスクイメージファイルの圧縮後サイズが劇的に小さくなったりします。

アンマウント

最後はアンマウントして終わりです。

# cd /root/fd
# umount /mnt

これで、編集作業が反映したmfsroot.imgファイルが出来上がりました。

起動フロッピーディスク作成

物理メディア作成

いよいよ、物理的な起動フロッピーディスクを準備します。ここに、ブートローダと、圧縮したカーネルと、圧縮した1FDイメージファイルを書き込んで終わりです。
下手なメディアを使うと、一見正常に見えて起動時に読み込みエラーになるとか、とかくトラブルの元になるので、絶対に信頼のおけるメーカーの新品のメディアを用意してください。

# fdformat /dev/fd0.1440
# disklabel -wB fd0 fd1440
# newfs -c 1 -i 131072 -o space -m 0 /dev/rfd0.1440 fd1440
# mount /dev/fd0c /mnt
# mkdir /mnt/boot

これで物理フロッピーを/mntにマウントして、bootディレクトリを作成しました。

bzip2対応ローダの作成とコピー

物理フロッピー上に/boot/loaderを作るわけですが、圧縮率向上のため、bzip2したカーネルを展開できるようにします。
loaderのソースは、/usr/src/sys/boot/i386/loader にあります。
forth無効、gzip無効、bzip2有効のloaderを作るには、

# cd /usr/src/sys/boot/i386/loader
# make -DNOFORTH -DLOADER_NO_GZIP_SUPPORT -DLOADER_BZIP2_SUPPORT

とやって作ります。ファイルが足りん!と言われてmakeが途中で終了した場合は、/usr/srcに移動し、makeを実行することにより、必要なオブジェクトファイルが作成され、今度はちゃんとloaderのコンパイルが出来るはずです。
ちなみに、手元で実験してみた結果、

  • デフォルトのローダ(forth・gzip有効):155648バイト

  • forth無効・gzip有効:114688バイト

  • forth無効・gzip有効・bzip2有効:135168バイト

  • forth無効・gzip無効・bzip2有効:114688バイト

と言った感じでした。出来上がったloaderをkgzipしてフロッピーにコピーします。

# mkdir /mnt/boot
# kgzip -o /mnt/boot/loader loader

loaderは、/boot/loader.rcを読み込むので、これを作成します。
/mnt/boot/loader.rcの内容は、以下のとおり。

load /kernel
load -t mfs_root /mfsroot
autoboot 1

カーネルと1FDイメージファイルの圧縮とコピー

あとは、作成したカーネルと、メモリ上に展開される1FDイメージファイルを圧縮してフロッピーに入れるだけです。
ところで、bzip2対応のloaderを作ったわけですが、これが圧縮率の高いbz2ファイルは展開できないようです。
bzip2 -1で圧縮すれば展開できるので、これで圧縮してコピーします。

# bzip2 -1c /usr/src/sys/compile/1FD_FreeBSD/kernel >/mnt/kernel.bz2
# bzip2 -1c /root/fd/mfsroot.img >/mnt/mfsroot.bz2

設定ファイルの作成

柔軟な設定を可能にするため、物理フロッピーディスク上に作成したrcファイルを実行する設定にしました。必要に応じて、これを設定します。
以下、/mnt/rcの設定例です。

#!/bin/sh
/bin/ifconfig de0 inet 10.123.234.1 netmask 255.255.255.0
/bin/ifconfig em0 inet 10.123.234.1 netmask 255.255.255.0
/bin/ifconfig txp0 inet 10.123.234.1 netmask 255.255.255.0
/bin/ifconfig vx0 inet 10.123.234.1 netmask 255.255.255.0
/bin/ifconfig dc0 inet 10.123.234.1 netmask 255.255.255.0
/bin/ifconfig fxp0 inet 10.123.234.1 netmask 255.255.255.0
/bin/ifconfig pcn0 inet 10.123.234.1 netmask 255.255.255.0
/bin/ifconfig rl0 inet 10.123.234.1 netmask 255.255.255.0
/bin/ifconfig sf0 inet 10.123.234.1 netmask 255.255.255.0
/bin/ifconfig sis0 inet 10.123.234.1 netmask 255.255.255.0
/bin/ifconfig ste0 inet 10.123.234.1 netmask 255.255.255.0
/bin/ifconfig tl0 inet 10.123.234.1 netmask 255.255.255.0
/bin/ifconfig tx0 inet 10.123.234.1 netmask 255.255.255.0
/bin/ifconfig vr0 inet 10.123.234.1 netmask 255.255.255.0
/bin/ifconfig wb0 inet 10.123.234.1 netmask 255.255.255.0
/bin/ifconfig xl0 inet 10.123.234.1 netmask 255.255.255.0
/bin/ifconfig bge0 inet 10.123.234.1 netmask 255.255.255.0
/bin/ifconfig ed0 inet 10.123.234.1 netmask 255.255.255.0

tcpserver -RHl0 -c250 0 10000 sh -c "dd if=/dev/ad0 bs=16384|bzip2 -1vvc" &
#tcpclient -RHl0 10.123.234.1 10000 sh -c "/bin/cat<&6"|bzip2 -dvvvc|dd of=/dev/ad0 &

見れば分かると思いますが、まずifconfigでインターフェースの設定をします。もし、複数のNICが刺さっていて、しかも同一のアドレス空間に接続されている場合は問題が起きますが、普通はそんなことは無いでしょうから…。
一番下の二行は、今回の1FDディスクデュプリケータのメイン部分です。

tcpserverの行は、コピー元となるマシンの場合有効にしてください。
tcpclientの行は、コピー先となるマシンの場合有効にしてください。

これを間違えると死にますので御注意を。
なお、サーバ側の同時接続数は -cオプションで設定します。とりあえず250台にしてありますので、同時に250台まで並列処理できます。もっとも、ネットワーク的/サーバのディスク読み取り速度的に、どれだけ時間が掛かるか分かりませんが…笑。
例として、コピー先マシンの設定例を挙げておきます。

#!/bin/sh
/bin/ifconfig de0 inet 10.123.234.2 netmask 255.255.255.0
/bin/ifconfig em0 inet 10.123.234.2 netmask 255.255.255.0
/bin/ifconfig txp0 inet 10.123.234.2 netmask 255.255.255.0
/bin/ifconfig vx0 inet 10.123.234.2 netmask 255.255.255.0
/bin/ifconfig dc0 inet 10.123.234.2 netmask 255.255.255.0
/bin/ifconfig fxp0 inet 10.123.234.2 netmask 255.255.255.0
/bin/ifconfig pcn0 inet 10.123.234.2 netmask 255.255.255.0
/bin/ifconfig rl0 inet 10.123.234.2 netmask 255.255.255.0
/bin/ifconfig sf0 inet 10.123.234.2 netmask 255.255.255.0
/bin/ifconfig sis0 inet 10.123.234.2 netmask 255.255.255.0
/bin/ifconfig ste0 inet 10.123.234.2 netmask 255.255.255.0
/bin/ifconfig tl0 inet 10.123.234.2 netmask 255.255.255.0
/bin/ifconfig tx0 inet 10.123.234.2 netmask 255.255.255.0
/bin/ifconfig vr0 inet 10.123.234.2 netmask 255.255.255.0
/bin/ifconfig wb0 inet 10.123.234.2 netmask 255.255.255.0
/bin/ifconfig xl0 inet 10.123.234.2 netmask 255.255.255.0
/bin/ifconfig bge0 inet 10.123.234.2 netmask 255.255.255.0
/bin/ifconfig ed0 inet 10.123.234.2 netmask 255.255.255.0

#tcpserver -RHl0 -c250 0 10000 sh -c "dd if=/dev/ad0 bs=16384|bzip2 -1vvc" &
tcpclient -RHl0 10.123.234.1 10000 sh -c "/bin/cat<&6"|bzip2 -dvvvc|dd of=/dev/ad0 &

IPアドレスは、コピー元と同じアドレス空間で適当に設定します。
設定後は、xビットを立てておきましょう。

# chmod +x /mnt/rc

後は、フロッピーをアンマウントすればおしまい。
試しに、フロッピーから起動させてみましょう。ちゃんと起動しましたか?送出元/送出先のメディアを突っ込んだ二台のPC間で、データ転送が行われましたか?くれぐれも、ディスクが消えては困るパソコンで、間違えてデータ書き込みをしないように。その辺は自己責任でどうぞ。

応用、など

今回、フロッピーから起動させた二台のPC間でのディスクコピーツールを作成しましたが、別に集中的なデータサーバを置いておき、正常起動時のディスクイメージをネットワーク経由で保存しておき、障害時にそこからデータを取得して書き戻す、なんてシステムもちょっと工夫すれば簡単に出来上がります。
「瞬快」等の専門ツールに比べれば手間も時間も掛かりますが、なんと言っても原材料費無料で作れるのが嬉しいところ。
専門学校などで、学生にLinuxなどの実習をさせる場合、学生に自由に使わせた後、予め作成しておいた標準環境に書き戻す、なんて場合が一番威力を発揮しそうな気がします(ライセンス的にも。) Windowsの場合、基本的にはこのような方法で複製を作るのはまずいですが、ディスクのスナップショットを保存する集中サーバを用意し、個別に書き戻すのであれば問題ない気がします。
復元に一晩掛かるのが欠点ですが、学校などの場合、一日の終わりや一週間の終わり等のタイミングで環境を元に戻す、なんて場合には有効かもしれません。

この記事が気に入ったらサポートをしてみませんか?