Gentoo Linux Prelink Guide
1. 紹介
prelinkとは何ですか? それは何の役に立つのですか?
ほとんどの一般的なアプリケーションは共有ライブラリを使用します。
これらの共有ライブラリは起動時にメモリーに読み込まれる必要があります。
また各種シンボルの参照が解決される必要があります。
多くの小さなプログラムにとってこのダイナミックリンクはとても素早く行われます。
しかしC++で書かれたプログラムやたくさんのライブラリに依存するプログラムにとってダイナミックリンクはかなりの時間がかかります。
大部分のシステムでは、ライブラリはそんなに変更されることがありません。そしてプログラムが起動されるときにリンクされるプログラムは毎回同じです。prelinkはlink情報を取り出し、それを実行ファイルに格納することによって要するにprelinkを行ないます。リンカーのために、glibc内のld-linux.soが必要です。またprelinkを見分けるためにglibc>=2.3を必要とします。
prelinkはアプリケーションの起動時間を短縮できます。例えば、典型的なKDEプログラムの起動時間は50%も短縮することができます。prelinkの唯一必要なメンテナンスは、ライブラリをアップグレードしたときに毎回prelinkしている実行ファイルを再度prelinkすることです。
概要
-
驚いたことにはprelinkはprelinkと呼ばれるプログラムによって行なわれます。
それはバイナリプログラムの起動時間を早くします。
- prelinkを行なった後で、アプリケーションが依存しているライブラリが変更した場合、アプリケーションのprelinkをし直す必要があります。それをしないとスピードアップの効果を得ることができません。
- prelinkによるバイナリの変更は完全な可逆性を持っています。つまりprelinkには元に戻す機能があるのです。
- portageの新しいバージョンは、prelinkを通じてのバイナリのMD5sum、mtimeの変更を処理することができます。
- binutils-2.13.90.0.xxによってコンパイルされたglibc-2.3以降が必要です。
2. prelinkの設定
プログラムのインストール
Note:
Gentoo-1.4システムがすでにインストールされていて、それがgcc-3.2以降とbinutils-2.13.90.0.xxによってbuildされていると想定します。この環境はバイナリのprelinkを行なうために必要です。 |
Warning: glibc 2.3.1以降が必要です。そうでないとprelinkによってすべてのバイナリを壊してしまうことがあります。 |
prelinkに必要とされる多くのアプリケーションが最新でbugfixされたものが確実にインストールされるために、最初にportageツリーを更新します。
Code listing 2.1: portageツリーの更新 |
# emerge sync
|
次にportage-2.0.46以降がインストールされているか確認します。これはportageがprelinkされたバイナリを認識し、正しくアンインストールするために必要となります。なぜならprelinkはバイナリのMD5sumを変更してしまうからです。
Code listing 2.2: Portage Versionnのチェック |
# emerge ">=portage-2.0.46"
|
これで、prelinkツールをインストールすることができます。emergeは、システムがprelinkを安全にできるか自動的に確認します。
Code listing 2.3: prelinkインストール |
# emerge prelink
|
多くの人がprelinkのemergeで確認テストエラーがでます。そのテストはいくつかの安全性のために行われています。prelinkの動作はそれらを無効にすると、定義されません。そのemergeエラーは通常binutils,gcc,glibcといったcoreパッケージに依存しています。それらのパッケージをその順番で再度emergeしてみてください。
Note: Tip: もしエラーが出たら、あなた自身でprelinkのコンパイル、テスト(./configure ; make ; make check)を行ってみてください。するとエラー時に、testsuiteディレクトリに*.logファイルが作成されます。そのファイルにはいくつかの役立つ手掛りが載っています。 |
他のシステム(マシン)で再びエラーがおきる場合には、Stefan Jonesまでメールしてください。
設定
portageは自動的に"/etc/prelink.conf"ファイルを作成します。このファイルはどのファイルをprelinkするかを記述します。
残念ながら古いバージョンのbinutilsをよってコンパイルされていたファイルはprelinkできません。これらのアプリケーションの大部分は/optにインストールされているバイナリのみのパッケージです。次のファイルを記述することによってそれらをprelinkしないようにします。
Code listing 2.4: /etc/env.d/99prelink |
PRELINK_PATH_MASK="/opt"
|
Note: コロンで区切って複数のディレクトリを記述することができます。 |
3. prelink
prelinkの使い方
/etc/prelink.confによって与えられたディレクトリのバイナリすべてをprelinkするために以下のコマンドが使えます。
Code listing 3.1: listされたファイルのprelink |
# prelink -afmR
|
Warning: ディスクの残りスペースが少ないときには、バイナリの一部分が切り捨てられてしまう場合があります。この結果システムが壊れてしまいます。"file"や"readelf"コマンドを使ってバイナリファイルの状態をチェックしてください。 |
オプションの説明
-a
all すべてのバイナリをprelinkする。
-f
force すでにprelinkされているバイナリも再度prelinkを行なう。これは以前prelinkしたファイルが存在し、依存しているライブラリが変更された場合にprelinkを上書きするために必要です。
-m
memory 仮想メモリ空間を保持します。prelinkするライブラリが多い場合に必要です。
-R
random アドレスの順序をランダムにします。これはbuffer overflowに対してのセキュリティが増大します。
他のオプションや詳細はman prelinkを見てください。
4. 既知の問題と解決策
"non-PIC共有ライブラリがprelinkできない"
この問題の原因は、-fPIC gccオプションなしですべてのobjectファイルをコンパイルした共有ライブラリにあります。
次のリストは問題のあるライブラリです。もし上記のエラーが起きたらそのパッケージを再度mergeしてください。
Code listing 4.1: 解決方法 |
emerge ">=sys-apps/tcp-wrappers-7.6-r4" ORBit
emerge ">=sys-libs/zlib-1.1.4"
emerge ">=media-libs/svgalib-1.9.16"
emerge ">=x11-base/xfree-4.2.1-r2"
emerge ">=net-libs/libpcap-0.7.1-r2"
emerge ">=media-libs/lcms-1.09"
|
Note: 多くのライブラリは静的にzlibやtcp-wrappersにlinkしています。だから最初にそれらをemergeしてから、問題のライブラリを再度emergeしてみてください。 |
QT/KDEでprelinkに問題が発生したら、まず始めに>=x11-base/xfree-4.2.1-r2 と >=x11-libs/qt-3.1.0-r1にアップグレードしてください。それでもQTが失敗するならば、xineramaサポートをmyconf="-no-xinerama ${myconf}"とqtのebuildに記述することによって無効にしてからコンパイルしてみてください。
以下は、まだ修正が終わっていないか修正できないライブラリです。
- winexを含むwineパッケージのライブラリ。MS Windows実行ファイルはスピードアップしません。
- media-video/mjpegtoolsの/usr/lib/liblavfile-1.6.so.0ライブラリ
このリストに載っていない問題のあるライブラリがある場合には、できれば-fPICを適切なCFLAGSに追加したパッチと一緒に連絡してください。
"1631 Aborted ...." のような表示が出てprelinkが中断する
-fオプションをprelinkで使用する必要があります。0から再度システム全体のprelinkをするには、prelink -afを試してください。
"<file>: error while loading shared libraries: unexpected reloc type..."
これは2002/11/18のsys-libs/glibc-2.3.1-r2で解決されています。それより古い場合には再度glibcをemergeしてください。
prelink -u -a -m ; prelink -a -mをすることによって再度役にたつ情報を知ることができます。他のすべてが失敗する場合、単にprelink -u <file>を実行します。
Nvidia openGLライブラリで問題が発生します
nvidia-glxパッケージ内のaccelerated openGLライブラリは一般的ではない方法でコンパイルされます。だからprelinkはwarningを発生します。これについて気にする必要はありませんし、nvidiaでないとこれを直すことはできません。いつでも3Dアクセラレーションが必要なくなったら、libGL.soのxfreeバージョンを戻すことができます。そういは言うもののnvidia xfreeドライバーは無事に動きます。
システムをprelinkしたらいくつかのスタティックバイナリが動か なくなりました。
glibcが関係しているところでは、100% スタティックバイナリのことはありません。glibcと静的にコンパイルした場合には、他のシステムに依存していることになります。以下はDick Howellによる説明です。
"ダウンロードしたバイナリパッケージはすべてを自分自身に含んでいるため、ターゲットシステムのローカルライブラリに依存しないと考えます。しかしあいにくLinux、また他のGLIBCを使用したシステムで、これは完全に真ではありません。さまざまなデータベースへの認証、ネットワーク情報などの機能を提供する"libnss"(ネームサービススイッチライブラリ。
ネットワークセキュリティシステムと呼ばれることもある)があります。これはそのマシンの実際のネットワークに依存しないアプリケーションプログラムを作ることができます。良い考えですが、GLIBCを変更するとロードするときに問題が置こる場合があります。"libnss"をスタティックリンクすることはできません。なぜならそれぞれのマシン個々で設定されているからです。その問題は主に他のGLIBCライブラリと静的にリンクれている場合に起こると考えます。特に"libnss"から個々に呼ばれる"libpthread"、"libm"、"libc"で起こります。"
Prelinkが"prelink: dso.c:306: fdopen_dso: Assertion `j == k' failed." のメッセージを出して異常終了しました。
これは良く知られた問題です。ここで、親切に解説されています。
prelinkはUPX圧縮された実行形式を処理することができません。
prelink-20021213の時点で、prelinkの最中にそのファイルを隠しておくことしか、解決する方法はありません。ファイルを隠す簡単な方法がprelinkの設定にあるので見てください。
5. 最後に
prelinkは多くの巨大なアプリケーションの起動時間を短縮することができます。そしてPortageでサポートされています。prelinkはまたもし問題に直面した場合には安全にいつでもどのバイナリでも元に戻すことができます。つまり、がんばってね!
|