2008年4月14日月曜日

自宅サーバをFreeBSD 7.0-RELEASEにアップグレードしてみた ~ 1年くらい前の6.2-STABLEから7.0-RELEASEへ…ちょっとめんどくさかった。

自宅サーバといってもたいそうなものではなく、アキバで買ってきたジャンク・パーツと、余ってたパーツのよせあつめで組み立てた、Celeron 900MHz、512MB程度なFreeBSDマシン。



普段は、ディスプレイも、キーボードも、マウスもつながず、apache、samba、imap-uw、ntp、vtundなどを動かしている程度。



土曜日、なんとなくその気になったので、思い立ったが吉日、去年の秋くらいの6.2-STABLEから、7.0-RELEASEにアップグレードしてみたました。いつもRELEASE版はインストールせずに、インストールしようと思った時点のSTABLE版をインストールしてたんですが、なぜか気まぐれで、snapshot版の7.0-STABLEにしませんでした。



会社で使ってるパソコンは、今は、3月末ころの7.0-STABLEで、自分でmake buildworldしたやつで、とくにトラブルもなく動いてますけど。





いつものように、非常に正しくないインストール方法で、アップグレード。失敗すると、起動しなくなりますけど。



  1. 今動いているFreeBSD上で、ftpサイトから、7.0-RELEASE-i386-bootonly.isoという34MBほどの小さいファイルをダウンロード。


  2. isoイメージを、mdconfigして、mount。


  3. isoイメージ内の/boot以下を、今動いているFreeBSDのハードディスクの/bootとしてコピー。一応、もともとの/bootは、mv /boot /boot- とかやって残しておくけど。


  4. おもむろにreboot。


  5. boot loaderのメニューで、loaderのプロンプトに抜けて、boot -a


  6. rootパーティションはどこですか?と聞いてくるので、ufs:md0a


  7. これで、インストーラが起動するので、あとはupgradeを実行。


まあ、ほんとに、めちゃくちゃな方法ですが、これでもけっこううまくいくし、いざとなれば、別の方法で…



というわけで、うまく行くかと思ったら、インストーラで、ファイルのコピー中、そう、GENERIC kernelをコピーしている最中に、ファイルシステム・フルでエラーに・・・



あ~、そういえば、そんな話がありました。



7.0-RELEASEでは、なぜか、acpi.ko.symbolsなど、*.symbolsというファイルが/boot/kernel/以下へコピーされるので、ルート(/)パーティションの空き容量不足になる恐れがあると…



初めてインストールしたFreeBSDは、バージョン1.1くらいでしたが、あのころって、/パーティションは64MBにしてたと思います。その後、なんとかやりくりしてたんですけど、いつのバージョンだったか、どうやっても足りない、ってことで256MBに増やしました。



今の自宅サーバはまだ256MBのままですが、ここ1~2年くらい、新規インストールするときは512MBにしてます。



ちなみに、/パーティション1つだけ、ってのは、個人的にはめったにやりません。/、/var、/usr、/usr/local、/home、きちんとわけます。バックアップをとるときに、細かく分けておいたほうが便利だから、っていう理由からです。





さて・・・、7.0-RELEASEで、またしてもディスクの空き容量不足。



  1. インストール中、Alt + F4で、端末を切り替えると、シェルが動いているので、そこで、ファイルを消しまくったり、別パーティションへ退避したり。


  2. そこそこ空いたので、Alt + F1で、インストーラの画面に戻り、なんかキーを押したら、もう一回コピーすんの?と親切に聞いてくれてるので、もう一回、kernelのコピー。


  3. 心配だったので、コピーしている最中に、Alt + F4して、*.symbolsを削除したり(コピー中は、/boot/kernelではなくて、/boot/GENERIC/だったかも?)。


とりあえず、ベース部分は、これで7.0-RELEASEにアップグレードされました。



/etc/以下のファイルとか、置き換えたり書き換えたりする必要がある場合もありますが、あとまわし。



FreeBSD6のときのバイナリをしばらくの間そのまま実行できるようにするため、/usr/ports/misc/compat6x をインストールしました。



そして、/lib、/usr/lib、/sbinなどに、古いファイルが残ったままになってるので、これを削除します。いつも、タイムスタンプを見てエイヤで消してたんですけど、なんかいい方法を見つけました。



FTPサイトから、src以下にある、sbase.*と、stools.*をダウンロードする



/usr/src/以下に展開する。



こんなファイルがありますが…



-rw-r--r--   1 root  wheel     6188  1  1 18:36 COPYRIGHT
-rw-r--r--   1 root  wheel      399  1 13  2006 LOCKS
-rw-r--r--   1 root  wheel     6918  5 24  2007 MAINTAINERS
-rw-r--r--   1 root  wheel    11597 11 22 10:33 Makefile
-rw-r--r--   1 root  wheel    37935  1 22 06:58 Makefile.inc1
-rw-r--r--   1 root  wheel   193168  1 31 03:12 ObsoleteFiles.inc
-rw-r--r--   1 root  wheel     3077  6  7  2006 README
-rw-r--r--   1 root  wheel    37842  2 24 14:17 UPDATING
drwxr-xr-x  12 root  wheel      512  2 25 00:20 tools/



この中のMakefileを見てみます。このへん。



# check-old           - List obsolete directories/files/libraries.
# check-old-dirs      - List obsolete directories.
# check-old-files     - List obsolete files.
# check-old-libs      - List obsolete libraries.
# delete-old          - Delete obsolete directories/files/libraries.
# delete-old-dirs     - Delete obsolete directories.
# delete-old-files    - Delete obsolete files.
# delete-old-libs     - Delete obsolete libraries.



いつのころからか、「make delete-old」とかで、古いファイルを削除できるんですよね。便利。すごく便利。
これをするために、全部のソースは必要ないようで、先ほどの、sbase、stoolsだけで十分なようです。



まずはmake check-oldなどで確認してから、make delete-oldで削除するのですが、削除していいか、いちいち聞かれて、yと答えてやらなければならないので、けっこう面倒です。



というわけで、「yes | make delete-old」とかやっちゃいます。意味がわかんない人は、yesというコマンドを実行してみてください。意味がわかんないことになると思いますけど(笑)。



/usr/bin/yesは、ひたすら、yと出力しつづけるコマンドです。





とりあえず、これでも、6.2-STABLEのときのバイナリはそのまま実行できるはずなんですが、なんか微妙に動かないものがいくつかあるみたいでした。



たとえばvtund。



# /usr/local/etc/rc.d/vtund start
Starting vtund.
/libexec/ld-elf.so.1: /lib/libc.so.7: Undefined symbol "environ"



なぜ6.2-STABLEのときにビルドしたvtundが、7.0-RELEASEのlibc.so.7をリンクしているのでしょうかね。なんかおかしい。



% ldd /usr/local/sbin/vtund
/usr/local/sbin/vtund:
        liblzo.so.1 => /usr/local/lib/liblzo.so.1 (0x280fb000)
        libcrypto.so.5 => /lib/libcrypto.so.5 (0x28117000)
        libc.so.7 => /lib/libc.so.7 (0x28270000)



# ldd /lib/libcrypto.so.5
/lib/libcrypto.so.5:
        libc.so.7 => /lib/libc.so.7 (0x28080000)



ふーん、libcrypto.so.5がlibc.so.7ですか・・・って、libcrypto.so.5も、FreeBSD7用みたいなんですけど。



去年の10月くらいのsnapshot版の6-STABLEのISOイメージがまだFTPサイトにあるので、中を見たら、



-r--r--r--  2 root  wheel  996688 10 13  2007 libcrypto.so.4



なぜ、うちのFreeBSDは、libcrypto.so.5になってるんですかね…



もともと/usr/local/lib/libcrypto.so.5があったのが、何かのときに削除されてしまった、とか?



今はもうportupgradeしてしまったので、何が起きたのか、もはやわかりません。
まあいいや。





FreeBSDで気に入ってるのは、OSのバージョンアップ時に、ダウンタイムを極力短くできることです。



  1. (本当はまずいのですが…)、動かしたまま、make installworldで、新しいファイルをコピーしてから、一度リブート。


  2. そのあと、新バージョンのOSでブートしても、既存のインストール済みソフトは、とりあえずそのまま動く。


  3. 動かしながら、暇をみつけながら徐々に、portupgradeで再ビルドしする。


今回も、ソースのコンパイルからはやりませんでしたが、これと同様の作戦で行こうと思ったら、なんかうまくいかなかったです。わりと、あわててportupgradeしてやららねばならぬ、ってことになりました。



FreeBSD7になって、/lib/libthr.soというスレッドライブラリが使われるようになって、これのせいで、FreeBSD6のときのバイナリが動かなくなることが多いんですけど、今回もそれですかねぇ?



以前、こんなこともありました。



(FreeBSD7) Fatal error 'Cannot allocate red zone for initial thread' at line 382 in file /usr/src/lib/libthr/thread/thr_init.c (errno = 12)



opensslをportupgradeした後、wgetが動かなくなりました。



# ldd /usr/local/bin/wget
/usr/local/bin/wget:
        libintl.so.8 => /usr/local/lib/libintl.so.8 (0x280af000)
        libssl.so.5 => /usr/local/lib/libssl.so.5 (0x280b9000)
        libcrypto.so.5 => /usr/local/lib/libcrypto.so.5 (0x280fa000)
        libc.so.6 => /usr/local/lib/compat/libc.so.6 (0x2823d000)
        libiconv.so.3 => /usr/local/lib/libiconv.so.3 (0x28324000)
        libthr.so.3 => /lib/libthr.so.3 (0x2841c000)
        libc.so.7 => /lib/libc.so.7 (0x2842f000)



libc.so.6とlibc.so.7がまじってるのも気持ち悪いですが、libthr.so.3が入ってますね。そのせいっぽいです。



そのほか・・・



% ls -l /*.core
-rw-------  1 root  wheel     28672  4 12 11:17 /httpd.core
-rw-------  1 root  wheel  18743296  4 12 11:17 /nmbd.core
-rw-------  1 root  wheel     65536  4 12 11:17 /smbd.core
-rw-------  1 root  wheel     12288  4 12 11:17 /spamass-milter.core
-rw-------  1 root  wheel  67604480  4 12 11:16 /testparm.core
-rw-------  1 root  wheel  67584000  4 12 11:17 /wget.core



もう、ボロボロですね。



OSのメジャーバージョンがあがったときなどは、portupgrade -afするのがたぶん正式な方法だと思います。…が、Celeron 900MHzでそれをやるのはつらいです。



とりあえず、サーバとして動いているソフトは先にportupgradeしてやり、できるだけ迅速にネットワークサービスを再開。



残りは、ぼちぼちとportupgradeしていくということで。





なんだか早々にエラーがでました。



--->  Skipping 'print/cups-base' (cups-base-1.3.5) because a requisite package 'gnutls-2.0.2_1' (security/gnutls) failed (specify -k to force)
--->  Skipping 'japanese/samba3' (ja-samba-3.0.28,1) because a requisite package 'gnutls-2.0.2_1' (security/gnutls) failed (specify -k to force)
** Listing the failed packages (-:ignored / *:skipped / !:failed)
        ! graphics/tiff (tiff-3.8.2_1)  (unknown build error)
        ! security/gnutls (gnutls-2.0.2_1)      (unknown build error)
        * print/cups-base (cups-base-1.3.5)
        * japanese/samba3 (ja-samba-3.0.28,1)



tiffでこけてますね。



# make
===>  Building for tiff-3.8.2_1
Making all in port
Making all in libtiff
make  all-am
/bin/sh /usr/local/bin/libtool --tag=CXX --mode=link c++   -O -pipe -march=pentiumpro  -L/usr/local/lib -o libtiffxx.la -rpath /usr/local/lib -no-undefined -version-number  4:0:0  tif_stream.lo ../libtiff/libtiff.la ../port/libport.la -ljpeg -lz -lm -lc
c++ -shared -nostdlib /usr/lib/crti.o /usr/lib/crtbeginS.o  .libs/tif_stream.o -Wl,--whole-archive ../port/.libs/libport.a -Wl,--no-whole-archive  -Wl,--rpath -Wl,/home/ports.work/usr/ports/graphics/tiff/work/tiff-3.8.2/libtiff/.libs -Wl,--rpath -Wl,/usr/local/lib -Wl,--rpath -Wl,/usr/local/lib -L/usr/local/lib ../libtiff/.libs/libtiff.so /usr/local/lib/libjpeg.so -lz -L/usr/lib -lstdc++ -lm -lgcc_pic /usr/lib/crtendS.o /usr/lib/crtn.o  -march=pentiumpro -Wl,-soname -Wl,libtiffxx.so.4 -o .libs/libtiffxx.so.4
/usr/bin/ld: cannot find -lgcc_pic
*** Error code 1



なんですか、この「-lgcc_pic」ってのは。
あれこれ調べてみたら、libtoolがくっつけてるみたいです。



# grep gcc_pic /usr/local/bin/libtool
postdeps="-lstdc++ -lm -lgcc_pic -lgcc_pic"



# ls -l /usr/local/bin/libtool
-r-xr-xr-x  1 root  wheel  228170 11 20 23:03 /usr/local/bin/libtool
# pkg_which /usr/local/bin/libtool
libtool-1.5.24



libtoolが、6.2-STABLEのときのままだったのがいけなかったみたいです。libtool、ついでにauto*などを、先にportupgradeすべきだったんですね。
gccのバージョンが、3.4.xから4.2.xに変わったんでしたっけ?



とりあえず、これで解決。





重要なソフトはportupgradeが終わったので、残りは、とりあえずportupgrade -aしてやりました。
一晩あけたら、エラーで終わってたんですが、エラーの理由は、ldconfig_compat-1.0_8がどーのこーの。
これ、baseにもう入ってるので、入れなくてもいいパッケージなんでしたよね。



pkgdb -Fしても依存関係から消してくれなかったので、pkg_delete -f ldconfig_compat-1.0_8 で無理やり削除してから、pkgdb -F



今度は



Stale dependency: xrx-1.0.1 -> ldconfig_compat-1.0_8 (misc/ldconfig_compat):
-> Deleted. (irrelevant)



とかえんえんと出続けて、依存関係を直してくれてますが・・・これがもうすごく遅い。かなり時間がかかりました。





portupgrade -aは終わりました。
でも、これは、portsでバージョンがあがってるパッケージしかビルドされません。



バージョンが変わっていないパッケージは、まだ、6.2-STABLEのときのバイナリのままです。



なので、portupgrade -fで、再ビルドしていきます。



これをするとき、いい方法ってあるんですかね? portupgrade -afだと、さきほど再ビルドしたものまで全部、また再ビルドしちゃうし。



どうやら「+DESC」というファイルのタイムスタンプが、インストールしたときのものらしいのですけど…



% cd /var/db/pkg
% ls -ltr */+DESC | head
-rw-r--r--  1 root  wheel   325 12  3  2005 p5-Sys-Hostname-Long-1.4/+DESC
-rw-r--r--  1 root  wheel   317 12  3  2005 uudeview-0.5.20/+DESC
-rw-r--r--  1 root  wheel   418 12  4  2005 texi2html-1.76_1,1/+DESC
-rw-r--r--  1 root  wheel   472 12  4  2005 nasm-0.98.39,1/+DESC
-rw-r--r--  1 root  wheel   207 12  4  2005 wakeonlan-0.41/+DESC
-rw-r--r--  1 root  wheel   176  1 27  2006 p5-gettext-1.05_1/+DESC
-rw-r--r--  1 root  wheel   187  1 28  2006 uulib-0.5.20_1/+DESC
-rw-r--r--  1 root  wheel   138  1 28  2006 tex-texmflocal-1.9/+DESC
-rw-r--r--  1 root  wheel   406  1 28  2006 libmng-1.0.9/+DESC
-rw-r--r--  1 root  wheel   225  3 25  2006 ja-gawk-3.0.6/+DESC



これを目安にしながら、portupgradeしてます。



% ls -lt */+DESC | grep '200[567] ' | grep -v ' font-'
     | grep -v 'xorg-fonts' | grep -v linux-
     | gawk '{print $9}' | sed 's:/+DESC::' | sort | less



みたいな感じでしょうか。





まだまだ終わりそうもないです。



でもまあ、これがまた楽しいんです。だからFreeBSDを使っているわけでして。



■ 関連記事





0 件のコメント:

コメントを投稿