共有ライブラリをアップグレードしたらrpmが動かなくなった

12/28の日記で書いたrpmがSegmentation Faultを起こすの原因が判明。gcc-3を入れるのにglibcも一緒にアップグレードしたのだが、このときバイナリパッケージ、それも他のディストリビューション用のものを使ったのが問題だったらしい。以下、原因解明から復旧までの流れ。

最初はRPMのDBが壊れたことを疑った。しかしrebuilddbしてもエラーも出ずに終了、それでも直らない。再インストールしかない…という考えが頭をよぎったが、ふとあることに気づいた。それはオプション指定によってSegmentation Faultが起こる場合と起こらない場合があるということ。-qa,-qiは○。-Uvhは×。--rebuildbも○。何も指定しないと×。さらにaptは正常に動く。この時点でDBは関係ないことが分かった。じゃあglibcを元のバージョンに戻せば直るんじゃあ…あ、rpmが使えない。

ということで、rpmが使えない状態からrpmパッケージを入れ替えるにはどうしたらいいか考えた。今使っているrpmはバージョン4のパッケージを自分でリビルドしたものだから、レスキューFDで、というのは不可能。rpmパッケージからファイルを取り出して上書きする方法もあるが、そうすると後でDBとの整合性を取るのが厄介だし、postrun辺りを正確にやらないと最悪起動できなくなる恐れがあるのでそれは避けたい。さあどうしよう。ここでしばらく考えて、rpmを再コンパイルすれば良いと気が付く。しかしやってみるとgccが中途半端にインストールされていたらしくc++コンパイラがないと文句を言われる。乗りかかった船なので、gccも再コンパイル決定。

紆余曲折の末gccコンパイル&インストールに成功。喜んだのもつかの間、まずはrpmのconfigureがlibtoolのバージョン違いで失敗。→libtoolを再コンパイル。そこがうまくいったと思ったら次はbzip2関係のライブラリで"undefined reference to `__ctype_b' "というようなエラーでリンク失敗。調べてみるとglibcのバージョンによる差異のようだ。というわけでbzip2も再コンパイル。それと今入れている実行ファイルやらライブラリやらは復旧した暁には全部消すので、どのファイルをインストールしたか後で分かるようにしておく必要がある。/usr/localを消せば済むことではあるが、この機会にcheckinstallを試してみることに。…しようとしたらインストールされてなかった。これもコンパイル&インストール。

ここまで来てやっとrpmコンパイルできるようになった。コンパイルは無事成功。/usr/local/bin/rpm --rcfile=/usr/lib/rpm/rpmrcと指定したら、ちゃんと動いた。ちょっと感動。最後にいよいよこれを使ってglibcを元に戻す。1回目、途中でシステムがクラッシュしてしまったが再起動して(起動しないんじゃないかと本気で心配したが何とか無事に起動した)もう1回やったらできた。/bin/rpmも正常に動くことを確認。これにて復旧作業は完了。長かった〜。おつかれさまでした。