更新したソースをコンパイル&インストールするために、
make world を行います。
その際、必要な周辺の事項もまとめておきます。
著者は、
3.4-RELEASE から 4.4-RELEASE へのアップグレード
にチャレンジしてみましたが、make buildworld をやってすぐ引っかかって
うまく行きませんでした。
どうもこれは、一般的に見られる症状のようです。
こんなときは、一度 4.1(.1)-RELEASE へアップグレードしてから
4.4-RELEASE へアップグレードすればいいようです。
3.4R -> 4.1(.1)R -> 4.4R
なお、詳細は取得した最新の src/Makefile か、
ハンドブックの
19.4. make world の利用 をご覧下さい。
UPDATING を読む
何はなくとも、まずは /usr/src/UPDATING を読みましょう。
どのような変更がなされてきたか、
それに伴いどのような変更をすべきか、
また Update の方法などが書いてあります。
/etc/make.conf の確認
/etc/make.conf や /etc/defaults/make.conf を見ます。
これは、コンパイルするときのオプションなどを記したファイルです。
通常、 CFLAGS や NOPROFILE のコメントを外すとよいでしょう。
/etc/make.conf
CFLAGS= -O -pipe
NOPROFILE= true
|
-O は最適化オプションでコンパイラはコンパイルの
スピードアップを試みます。
-pipe はコンパイル時のステージ間のデータの受渡しに
テンポラルファイルではなくパイプを利用します。
ファイルを作らない分速いですがメモリを使います。
/etc/group の確認
/etc/group と /usr/src/etc/group の違いをみて、
新しいバージョンで使う予定の group 名や GID を
すでに使ってないかを確認します。
% diff /etc/group /usr/src/etc/group
|
としてみて、自分で作ったグループ名しかなければOKです。
/usr/obj の削除
以前に make world をして /usr/obj が残っている場合は、
これを削除します。変更不可フラグが立っているものがある可能性が
ありますので、以下のようにして削除します。
# cd /usr/obj
# chflags -R noschg *
# rm -rf *
|
/usr の空き容量の確認
次に行う make buildworld では、/usr/obj に 320 MB 程度の
ファイルを書き出しますので、 /usr (を含む)パーティションに
空き容量があるかどうかを確認します。
ちなみに、/usr/src は 320 MB 程度になります。
/usr パーティションに容量がなければ、余裕のあるパーティションに
作業領域を作って、/usr/obj にシンボリックリンクしておくとよいでしょ
う。
make buildworld
ソースを再構築します。
script コマンドで出力メッセージを取りながら行うとよいでしょう。
# script /var/tmp/mw.out
Script started, output file is /var/tmp/mw.out
# cd /usr/src
# make buildworld
... compile ...
# exit
Script done, ...
|
ここで、make に -j4 などのオプションをつけることができます。
オプション -j4 は最大4個までのプロセスを同時に実行するというもので
す。
シングル CPU では -j4 が一番良いという報告があったり、
やってはいけないという報告があったり。。。
複数の CPU を持つマシンの場合、-j6 から -j10 の間で試して見て下さい。
Pentium III/550MHz, RAM/384MB, dual CPU, make -j8 では
FreeBSD 4.1.1R の構築に1時間かかりました。
Pentium III/500MHz, RAM/128MB では、FreeBSD-CURRENT の構築に
3時間半かかるそうです。
最後に、
===> etc
===> etc/sendmail
rm -f freebsd.cf
(cd /usr/src/etc/sendmail && m4 -D_CF_DIR_=/usr/src/etc/sendmail/../../contrib/sendmail/cf/ /usr/src/etc/sendmail/../../contrib/sendmail/cf/m4/cf.m4 freebsd.mc) > freebsd.cf
chmod 444 freebsd.cf
|
となっていれば、make buildworld は成功です。
トラブルシューティング (4.1(.1)→4.4)
4.1R (もしくは 4.1.1R)から 4.4R へのアップグレードの際には、
eelf_i386.o: In function `gldelf_i386_open_dynamic_archive':
eelf_i386.o(.text+0xc7b): undefined reference to `basename'
*** Error code 1
1 error
*** Error code 2
1 error
|
というエラーを吐いてストップしてしまいます。
他の所でもそのようなエラーが出ているようです。
解決策は、次の通りです。
# cd /usr/src
# make includes
# cd /usr/src/lib/libc
# make basename.o
# ar r /usr/lib/libc.a /usr/obj/usr/src/lib/libc/basename.o
# cd /usr/obj
# chflags -R noschg *
# rm -rf *
# cd /usr/src
# make buildworld
|
手動で、basename をコンパイルして libc.a に付け加えてます。
basename.o は/usr/obj/usr/src/lib/libc/basename.o ではなく、
カレントディレクトリにある こともありました(謎)。
エラーの理由は
libc のバージョンが良くないためだとかで、
上のとは別に、
/usr/src/gnu/usr.bin/binutils/libiberty/Makefile
に
パッチ(Makefile_libiberty.patch)を当てるという方法もあるようです
# cd /usr/src/gnu/usr.bin/binutils/libiberty
# patch < Makefile_libiberty.patch
# cd /usr/obj
# chflags -R noschg *
# rm -rf *
# cd /usr/src
# make buildworld
|
が、うちではうまく行きませんでした。
カーネルの構築&インストール
make installworld をする前に、カーネルの構築&インストールをします。
これは、make installworld をしてしまった後で
「カーネルが構築できない!」という事態を避けるためです。
また、通常のカーネル再構築の手順ではなく、make {buildkernel
,installkernel} を使わないといけないようです。
ここでは、まず GENERIC カーネルを作って、
動くのを確認してから改めてコンフィギュレーションする方法
を取ります。
3.x → 4.1 へのアップグレードの場合:
# cd /usr/src
# make buildkernel
# make installkernel
(この時点で、/GENERIC というカーネルができます)
# chflags noschg /kernel
# chflags noschg /GENERIC
# mv /kernel /kernel.old
# mv /GENERIC /kernel
# chflags schg /kernel
|
なお、4.1.1 へのアップグレードの場合は、make installkernel の段階で、
新しいカーネルが /kernel としてインストールされます。
4.x → 4.4 へのアップグレードの場合:
# cd /usr/src
# make buildkernel
# make installkernel
(この時点で、/kernel が新しいカーネルになってます)
|
/usr/src/sys/i386/conf の GENERIC ファイルを編集して HOGEHOGE
という名前のファイルにしたとすると、これをコンパイル&インストールす
るには、
# cd /usr/src
# make buildkernel KERNCONF=HOGEHOGE
# make installkernel KERNCONF=HOGEHOGE
|
とします。
いくつかのもののインストール(3.x→4.1のみ)
# cd /usr/src/sbin/mknod
# make install
|
/usr/src/UPDATING には
# cd /usr/src/sys/modules
# make install
|
もしろ、と書いてあったのですが、/modules の中身の日付けを見ると
すでに入っているようなので、気にしないことにします。
/dev を作り直す(3.x→4.1のみ)
# cp /usr/src/etc/MAKEDEV /dev
# cd /dev
# ls -l | awk '{print $1,$2,$3,$4,$5,$6,$NF}' > /var/tmp/dev.out
# sh MAKEDEV all
# ls -l | awk '{print $1,$2,$3,$4,$5,$6,$NF}' > /var/tmp/dev2.out
|
3行目と5行目は、/dev のエントリーのリストを取っています。
変更の前後でリストが違わないか、チェックするのに使います。
# diff /var/tmp/dev.out /var/tmp/dev2.out
|
/etc/fstab を修正する
4.x では IDE ハードディスクのデバイス名が wd* から ad* に変更になり
ました。これに伴い、/etc/fstab の wd を ad に変更します。
ただし、ウチでは 3.4 -> 4.1.1 のアップグレード時には問題
ありませんでしたが、 4.1.1 -> 4.4 のアップグレード時には
「root file system が見つからない」というエラーがでて
ブートできませんでした。(下の項目の問題?)
ブートブロックとブートローダをアップグレード
する(未試用)
# cd /sys/boot
# make install
|
シングルユーザモードに移る
# reboot
# fsck -p
# mount -u /
# mount -a
# cd /usr/src
# adjkerntz -i # if COMS is wall time
|
このあと、ブートするときにシングルユーザモードで起動するか、
マルチユーザモードで起動してしまった後
# shutdown now
....
Enter full pathname of shell or RETURN for [/bin/sh] : (リターン)
#
|
でシングルユーザモードに移行します。
トラブルシューティング
マルチユーザモードから shutdown now でいきなり
シングルユーザモードに移行するとよろしくありません。
とりあえず一度新しいカーネルで起ち上げなくてはならないようです。
いくつかのもののインストール II(3.x→4.1のみ)
# cd /usr/src
# cd gnu/usr.bin/texinfo/install-info
# make install
|
make installworld
いよいよ、make buildworld で作ったバイナリをインストールします。
# cd /usr/src
# make installworld
|
トラブルシューティング(3.4→4.1)
CVSup でソースを新しくして、
3.4R から 4.1R へのアップグレードの際には、
この make installworld がうまく行きませんでした。
しょうがないので、ここまでの作業をした上で、
もう一度 make world したら、うまくいきました。
# cd /usr/src
# script /var/tmp/mw.out
# make world
... compile & install ...
# exit
|
トラブルシューティング(4.1→4.4)
4.1R から 4.4R へのアップグレードの際にも、
この make installworld がうまく行きませんでした。
こちらの方は、もう一度 make world したら良くなる、
というほどお気楽ではなくて、/usr/obj を削除してから
make world すると、
# cd /usr/src
# make world
... compile ...
/usr/lib/crtbegin.o: In function `_init':
/usr/lib/crtbegin.o(.init+0x0): multiple definition of `_init'
/usr/lib/crti.o(.init+0x0): first defined here
/usr/lib/crtbegin.o: In function `_fini':
/usr/lib/crtbegin.o(.fini+0x0): multiple definition of `_fini'
/usr/lib/crti.o(.fini+0x0): first defined here
*** Error code 1
|
などというエラーを吐いてしまいました。
これは次のようにすれば解決しました。
# cd /usr/src/gnu/lib/csu
# ls
Makefile
# make
# make install
# cd /usr/obj
# chflags -R noschg *
# rm -rf *
# cd /usr/src
# make world
|
CVSup でソースを新しくしたのがダメらしいのですが、
詳しくはわかりません。
トラブルシューティング(4.1.1→4.4)
こんなエラーもありました。
... install ...
install -c -s -o root -g wheel -m 555 sh /bin
Could not execute shell
*** Error code 1
1 error
|
これは make -j4 installworld とやったのがいけなかったらしく、
make installworld とやればうまくいきました。
/etc の更新
ここまでの作業では /etc は更新されていません。
/usr/src/etc の下に、新しいバージョンの /etc の
デフォルトファイル群が入っています。
これを /etc にマージするには、mergemaster というコマンドを使うのが
便利です。その前に、/etc のバックアップを取っておきましょう。
# cp -Rp /etc /etc.old
# mergemaster
|
mergemaster は、シェルスクリプトです。
起動すると、新しいファイルに変更点を見つけた場合や、
新しいファイルに対応するインストールされているファイルが
ない場合には、それを処理するための4つの選択しを示します。
- 新しいファイルをそのままインストールする
- 新しいファイルは消す
- 新旧のファイルを sdiff を使って適切にマージする
- 後で手でマージするためにファイルを仮のルート環境に残しておく
デフォルトでは、仮のルートは /var/tmp/temproot になります。
始めて mergemaster を使うならば、-v オプションをつけるのがよいでしょ
う。
mergemaster を終了したら、/var/tmp/temproot にいっぱいある
空ディレクトリを消しておきましょう。
# cd /var/tmp/temproot
# find -d . -type d | xargs rmdir 2 > /dev/null
# rm sys
|
トラブルシューティング
3.x では tcsh は /usr/local/bin/tcsh にありましたが、
4.x では /bin/tcsh に移りました。
/etc/passwd に SHELL が /usr/local/bin/tcsh となっている
ユーザのログインシェルを、/bin/tcsh に変えておきましょう。
/stand の更新(オプション)
# cd /usr/src/release/sysinstall
# make all install
|
トラブルシューティング
4.4 にアップグレードしてから、/stand を更新しようと思ったら
何やらエラーがでてうまく行きませんでした。
あとで、od-driver を入れる時にパッチを当てたあとで
/stand を更新したらうまく行きました。
CVSup でソースを新しくしたのがダメらしいのですが、
詳しくはわかりません。
qmail に関する処置
MTA に qmail を使っている場合、/usr/sbin/sendmail は
qmail が用意する /var/qmail/bin/sendmail へのシンボリックリンク
になっています(デフォルトでは)。
しかし、make world すると、/usr/sbin/sendmail は
本物の sendmail になってしまいますので、
再起動する前にシンボリックリンクを張り直します。
# chmod 0 /usr/sbin/sendmail
# mv /usr/sbin/sendmail /usr/sbin/sendmail.bak
# ln -s /var/qmail/bin/sendmail /usr/sbin/sendmail
|
再起動
カーネルコンフィギュレーション
必要ならば、カーネルのコンフィギュレーションを行います。
od-driver を使う場合には、もう一度インストール&カーネルコンフィギュ
レーションをし直さなければならなくなるでしょう。
なお、以下のトラブルシューティングは、ソースファイルを
CVSup で持って来たときに起こったことです。
正式 RELEASE 版のソースファイルを FTP で持って来た時には、
問題なくちゃんとカーネルの再構築ができました。
トラブルシューティング
make world したあとで、カーネルを通常の手続きで
コンフィギュレーションしようと思ったら、
make depend ができませんでした。
HOGE をコンフィグレーションしたカーネルの名前とします。
3.4→4.1 では、make kernel でできました。
# cd /usr/obj
# chflags -R noschg *
# rm -rf *
# cd /usr/src
# make buildkernel KERNEL=HOGE
# make installkernel KERNEL=HOGE
|
4.1→4.4 では od-driver のパッチを当ててから make depend したので
すが、
/usr/src/sys/cam/scsi/scsi_od.c:1782: sys/dkbad.h: No such file or
directory
/usr/src/sys/cam/scsi/scsi_od.c:1791: machine/cons.h: No such file or
directory
/usr/src/sys/cam/scsi/scsi_od.c:1795: vm/vm_prot.h: No such file or
directory
mkdep: compile failed
*** Error code 1
|
というエラーが出て make depend できませんでした。
これは、/usr/src で make kernel しても同じ結果でした。
しょうがないので、/usr/src を一度全部消去して、
もう一度最新のソースに入れ換えたらできるようになりました。
その際、/usr/src/sys/i386/conf にある、
自前のカーネルコンフィギュレーションファイルを
バックアップしておくとよいでしょう。
トラブルシューティング
NFS サーバを make world すると、
クライアント側で NFS に失敗していることがあります。
こんなときは慌てず騒がす、一度 umount してから
再度 nfs mount します。
参考ページ
FreeBSD の部屋
Dec. 3, 2001