この文書の初版では、第 1 段階にひとつのシェルスクリプトを使っていました。
カスタマイズはすべて、そのスクリプトを編集する必要があったのですが、
利用者からの意見を参考にして、スクリプトのコードとデータを分離することにしました。
そのため新しいスクリプトでは、コードスクリプトを変更せずに、
複数の異なるシステムに異なる構成のデータを置くことが可能になりました。
第 1 段階のコードスクリプトは
stage_1.sh
であり、次のように 1
個の引数をつけて実行すると
設定ファイルとして
stage_1.conf.default
を読み込み、
ログファイルとして
stage_1.log.default
に書き込みます。
文末にわたしが使っている stage_1.conf.default
が添付してあります。
あなたが考える 「完璧なシステム」 に合わせて、
各設定をカスタマイズしてください。あなたが変更しそうな設定には、
詳細なコメントを追加してあります。設定スクリプトでは、
create_file_systems
,
create_etc_fstab
, copy_files
,
all_remaining_customization
という、
4 個のシェル関数を提供しなければなりません (これは、
stage_1.sh
から呼ばれる順に書いてあります)。
考慮すべき点は、以下のとおりです。
パーティションの配置
わたしは、システム全体を一つの大きな
パーティションに入れるという考え方が好きではないので、
普通は
/
、
/usr
、
/var
の
パーティションを分割し、/tmp
を
/var/tmp
のシンボリックリンクにしています。
また、/home
(ユーザのホームディレクトリ)、
/home/ncvs
(FreeBSD CVS リポジトリの複製),
/usr/ports
(ports ツリー),
/src
(チェックアウトした src ツリー)、
/share
(news スプールなど、バックアップする必要がない、
その他の共有データ) といったファイルシステムを、
古いシステムと新しいシステムで共有しています。
その他の項目
これは、新しいシステムの起動後にすぐに実行したいことや、
第 2 段階の前に実行したい内容のことです。
なぜ第 1 段階で単純に新しいシステムに chroot してお気に入りの
ports をインストールしないのかというと、理論的にも、
実際の手順にも卵鶏問題があるからです。第 1 段階では、
古いカーネルが動作していますが、chroot 環境には、
新しいバイナリとヘッダが使われています。もしその新しいバイナリが、
古いカーネルには存在しない新しいシステムコールを使っていたら、
SIGSYS, Bad system call
というエラーが出て停止してしまうでしょう。わたしは
lang/perl5
を構築する時にも問題が発生することを確認しています。
stage_1.sh
を実行する前に、
make installworld installkernel
を実行するために通常行なう作業を完了させておいてください。
これらは、たとえば次のようなものです。
初めて stage_1.sh
を実行した場合は、
稼働中のシステムから新しいシステムへとコピーされる設定ファイルは
/usr/src
のものと比べると古いので、
mergemaster
がどうするかを聞いてきます。
おすすめは、ここで変更点を統合しておくことです。
もし、何度も質問に答えるのが面倒であれば、
稼働中のシステムのファイルを更新しておきましょう
(ただしこれは、そうできればの話です。
-STABLE
のシステムを実行していて、
-CURRENT
を構築する、
もしくはその逆のようなケースでは、そうしてはいけません)。
次に mergemaster
を実行した時、
RCS バージョン ID が /usr/src
にあるファイルと一致しているものは、処理が飛ばされるようになります。
stage_1.sh
スクリプトは
set -e
が指定されており、
最初のコマンドが失敗 (終了コードが 0 以外) すると停止します。
そのため、エラーを見逃してしまうということはないでしょう。
これは、タイプミスなどで未定義の変数を使った場合にもエラーになります。
次に進む前に、stage_1.conf.default
にあるエラーを全部修正しておいてください。
stage_1.sh
では
mergemaster
が実行されます。
統合作業をしなければならないファイルが一つもない状態でも、
実行の終わりに次のメッセージが表示されます。
*** Comparison complete
Do you wish to delete what is left of /var/tmp/temproot.stage1? [no] no
no
と答えるか、
単に Enter を押してください。
なぜかと言うと、mergemaster
は /var/tmp/temproot.stage1
にサイズが 0 のファイルをいくつか残すからです。
これは、後で新しいシステムに (存在しなければ) コピーされます。
この後、インストールされたファイルのリストがページャ
(デフォルトでは more(1) です。less(1) を使うこともできます)
に表示されます。
*** You chose the automatic install option for files that did not
exist on your system. The following were installed for you:
/newroot/etc/defaults/rc.conf
...
/newroot/COPYRIGHT
(END)
q を入力してページャを終了します。
すると login.conf
に関して、次のように表示されます。
*** You installed a login.conf file, so make sure that you run
'/usr/bin/cap_mkdb /newroot/etc/login.conf'
to rebuild your login.conf database
Would you like to run it now? y or n [n]
これに対する答えはどちらでも構いません。
どう答えても、スクリプトから cap_mkdb(1) が実行されます。
次に示すのは、筆者の使っている stage_1.conf.default
ですが、たくさんの部分を書き換える必要がありますので注意してください。
どこを書き換えればよいのかについては、コメントを読めば十分理解できると思います。
警告:
newfs(8) コマンドには注意してください。
マウントずみのパーティションに新しいファイルシステムを作成することはできないものの、
このスクリプトはマウントされていない
/dev/da0s1a
, /dev/da0s1e
,
/dev/da2s1e
をすべて削除します。
ひとつ間違えれば、あなたの環境を破壊してしまう可能性がありますので、
デバイス名の変更は注意深く行なってください。
# このファイル: stage_1.conf.default は stage_1.sh から読み込まれます。
#
# $FreeBSD: head/ja_JP.eucJP/articles/fbsd-from-scratch/stage_1.conf.default 38826 2012-05-17 19:12:14Z hrs $
#
# Original Revision: 1.3
# 新しいシステムを作成する場所を示すルートマウントポイントを指定。
# マウントポイントとして使われるだけなので、マウントポイントのある
# ファイルシステムにファイルは置かれず、書き込みはすべてマウントした
# ファイルシステムに行なわれる。
DESTDIR="/newroot"
# src ツリーのある場所。
SRC="/usr/src"
# make buildkernel KERNCONF=... で指定するカーネルコンフィグレーションファイル名。
KERNCONF="HAL9000"
# 利用できるタイムゾーンは /usr/share/zoneinfo 以下のファイルに記載されている。
TIMEZONE="Europe/Berlin"
#
# create_file_systems 関数は、DESTDIR 下にマウントポイントを作成し、
# ファイルシステムを作成し、DESTDIR 下にマウントしなければならない。
#
create_file_systems () {
# 新しいルートファイルシステムを作成する。必須。
# DEVICE を変更すること。変更しないとシステムが壊れる危険性がある。
# grub から起動したい場合は、ルートファイルシステム作成には
# newfs -O 1 を使わなければならない。
DEVICE=/dev/da0s1a
mkdir -m 755 -p ${DESTDIR}
chown root:wheel ${DESTDIR}
newfs -U -O 1 ${DEVICE}
mount -o noatime ${DEVICE} ${DESTDIR}
# その他のファイルシステムと初期マウントポイント。オプション。
DEVICE=/dev/da0s1e
mkdir -m 755 -p ${DESTDIR}/var
chown root:wheel ${DESTDIR}/var
newfs -U ${DEVICE}
mount -o noatime ${DEVICE} ${DESTDIR}/var
DEVICE=/dev/da2s1e
mkdir -m 755 -p ${DESTDIR}/usr
chown root:wheel ${DESTDIR}/usr
newfs -U ${DEVICE}
mount -o noatime ${DEVICE} ${DESTDIR}/usr
}
#
# create_etc_fstab 関数は、create_file_systems で作成されたファイルシ
# ステムに対応する fstab を生成しなければならない。
#
create_etc_fstab () {
cat <<EOF >${DESTDIR}/etc/fstab
# Device Mountpoint FStype Options Dump Pass#
/dev/da0s1b none swap sw 0 0
/dev/da1s1b none swap sw 0 0
/dev/da2s2b none swap sw 0 0
/dev/da3s2b none swap sw 0 0
/dev/da0s1a / ufs rw,noatime 1 1
/dev/da0s1e /var ufs rw,noatime 1 1
/dev/da2s1e /usr ufs rw,noatime 1 1
/dev/vinum/Share /share ufs rw,noatime 0 2
/dev/vinum/home /home ufs rw,noatime 0 2
/dev/vinum/ncvs /home/ncvs ufs rw,noatime 0 2
/dev/vinum/ports /usr/ports ufs rw,noatime 0 2
/dev/ad1s1a /flash ufs rw,noatime 0 0
/dev/ad0s1 /2k ntfs ro,noauto 0 0
/dev/ad0s6 /linux ext2fs ro,noauto 0 0
#
/dev/cd0 /cdrom cd9660 ro,noauto 0 0
/dev/cd1 /dvd cd9660 ro,noauto 0 0
proc /proc procfs rw 0 0
linproc /compat/linux/proc linprocfs rw 0 0
EOF
chmod 644 ${DESTDIR}/etc/fstab
chown root:wheel ${DESTDIR}/etc/fstab
}
#
# copy_files 関数は、mergemaster が実行される前にファイルをコピーするのに
# 使われる。
#
copy_files () {
# 好みに応じて、このリストに追加・削除すること。ほとんどの場合は必須。
for f in \
/.profile \
/etc/group \
/etc/hosts \
/etc/inetd.conf \
/etc/ipfw.conf \
/etc/make.conf \
/etc/master.passwd \
/etc/nsswitch.conf \
/etc/ntp.conf \
/etc/printcap \
/etc/profile \
/etc/rc.conf \
/etc/resolv.conf \
/etc/start_if.xl0 \
/etc/ttys \
/etc/ppp/* \
/etc/mail/aliases \
/etc/mail/aliases.db \
/etc/mail/hal9000.mc \
/etc/mail/service.switch \
/etc/ssh/*key* \
/etc/ssh/*_config \
/etc/X11/XF86Config-4 \
/var/cron/tabs/* \
/var/files \
/root/.profile \
/boot/*.bmp \
/boot/loader.conf \
/boot/device.hints ; do
cp -p ${f} ${DESTDIR}${f}
done
}
#
# ほかに新しいシステムで調整したいことすべて。
# 注意: あまり多くのバイナリをこの時点でインストールしないこと。稼働している
# 古いシステムと、インストールした新しいバイナリ・ヘッダを組み合わせると、
# ブートストラップ問題に陥る可能性がある。ports は新しいシステムが起動した後に
# 再構築する方がよい。
#
all_remaining_customization () {
# compat シンボリックリンクがないと、linux_base のファイル群が
# ルートファイルシステムに置かれてしまう。
cd ${DESTDIR}
mkdir -m 755 usr/compat; chown root:wheel usr/compat; ln -s usr/compat
mkdir -m 755 usr/compat/linux; chown root:wheel usr/compat/linux
mkdir -m 555 usr/compat/linux/proc; chown root:wheel usr/compat/linux/proc
mkdir -m 755 boot/grub; chown root:wheel boot/grub
mkdir -m 755 linux 2k; chown root:wheel linux 2k
mkdir -m 755 src; chown root:wheel src
mkdir -m 755 share; chown root:wheel share
mkdir -m 755 dvd cdrom flash; chown root:wheel dvd cdrom flash
mkdir -m 755 home; chown root:wheel home
mkdir -m 755 usr/ports; chown root:wheel usr/ports
# 私の好みは tmp を var/tmp にシンボリックリンクすること。オプション。
cd ${DESTDIR}; rmdir tmp; ln -s var/tmp
# /etc/printcap で指定したスプールディレクトリを作成。
cd ${DESTDIR}/var/spool/output/lpd; mkdir -p as od ev te lp da
touch ${DESTDIR}/var/log/lpd-errs
# /home パーティションを共有していなければコピーした方がよいかも知れない。
# mkdir -p ${DESTDIR}/home
# cd /home; tar cf - . | (cd ${DESTDIR}/home; tar xpvf -)
case ${REVISION} in
4.*)
# 4.x には devfs がないので、ハードウェアに合わせて非標準のデバイスを作成する。
cd ${DESTDIR}/dev
./MAKEDEV all
./MAKEDEV da0 da0s1h da0s2h da0s3h da0s4h
./MAKEDEV da1 da1s1h da1s2h da1s3h da1s4h
./MAKEDEV da2 da2s1h da2s2h da2s3h da2s4h
./MAKEDEV da3 da3s1h da3s2h da3s3h da3s4h
./MAKEDEV bktr0 cd1
if test -d /dev/vinum; then
# 'vinum makedev' は /dev にしかデバイスを作成できないので、cpio を使う。
cd /dev; find vinum -print | cpio -pv ${DESTDIR}/dev
fi
# floppy に wheel グループが書き込めるようにする。
chown root:wheel ${DESTDIR}/dev/fd0*
chmod g+w ${DESTDIR}/dev/fd0*
;;
5.*)
# floppy に wheel グループが書き込めるようにする。
printf '%s\n' 'own fd0 root:wheel' >> ${DESTDIR}/etc/devfs.conf
printf '%s\n' 'perm fd0 0660' >> ${DESTDIR}/etc/devfs.conf
;;
*)
printf '%s\n' "REVISION ${REVISION} not supported"
exit 1
;;
esac
}
# vim: tabstop=2:expandtab:shiftwidth=2:syntax=sh:
# EOF $RCSfile: stage_1.conf.default,v $
ダウンロード: stage_1.conf.default
.
このスクリプトを実行すると、
起動した時に次のような状態になっているシステムがインストールされます。
他の部分に対する設定は、第 2 段階が終わるまで動作しません。
たとえば、プリンタや X11 の設定ファイルもコピーされますが、
プリンタは PostScript® ユーティリティなど、
ベースシステムに含まれないアプリケーションを使うことが多いでしょう。
X11 はサーバ、ライブラリ、プログラムをコンパイルしないと動作しません。