Linux の 101 試験対策: 共有ライブラリーの管理

プログラムに必要なライブラリーを発見し、ロードする

どの共有ライブラリーに Linux® の実行可能プログラムが依存しているのかを判断する方法、またそれらのライブラリーをロードする方法を学びましょう。この記事の内容は、Linux のシステム管理者として認定するための LPI 101 試験に備えるためにも、自ら活用するために学ぶ上でも役立ちます。

Ian Shields, Senior Programmer, IBM

Ian ShieldsIan Shields は、developerWorks Linux ゾーンの様々な Linux プロジェクトに関わっています。彼はノースキャロライナ州 Research Triangle Park にある IBM のシニア・プログラマーです。1973年にオーストラリアのキャンベラでシステム・エンジニアとして IBM に入社して以来、カナダのモントリオールやノースキャロライナ州 Research Triangle Park で、コミュニケーション・システムやパーベイシブ・コンピューティングに携わってきました。彼はいくつかの特許を保持しています。Australian National University にて純粋数学および哲学で学位を取得し、また North Carolina State University にてコンピューター・サイエンスで修士号と博士号を取得しています。Ian について詳しく知るには、My developerWorks で彼のプロフィールを見てください。


developerWorks 貢献著者レベル

2010年 3月 10日

この連載について

この連載は Linux システム管理タスクの学習に役立つだけでなく、LPIC-1 (Linux Professional Institute Certification レベル 1) 試験に備えるための教材にもなります。

連載の各記事についての説明とリンクについては、連載のロードマップを参照してください。現在進行中のこのロードマップは、LPIC-1 試験の最新の目標 (2009年4月) を反映しています。完成した記事はその都度ロードマップに追加されていきますが、当面は developerWorks の LPI 認定試験対策チュートリアルで同様の教材の以前のバージョンを調べてください。これらのバージョンは、2009年4月より前の LPIC-1 目標に対応しています。

概要

この記事では、Linux プログラムで必要な共有ライブラリーを発見、ロードする方法について学びます。この記事で説明する内容は以下のとおりです。

  • プログラムに必要なライブラリーを判断する方法
  • システムが共有ライブラリーを発見する方法
  • 共有ライブラリーをロードする方法

この記事は、Linux Professional Institute の Junior Level Administration (LPIC-1) 101 試験の主題 102 の 102.3 の試験対策に役立ちます。この目標の重要度は 1 です。

前提条件

この連載の記事を最大限に活用するには、Linux の基礎知識と、記事に記載されたコマンドを演習できる実際の Linux システムが必要です。プログラムのバージョンによって出力のフォーマットに違いが出てくる場合もあるため、コマンドの実行結果は必ずしもここに記載するリストや図とまったく同じであるとは限りません。特に、この記事で紹介する例の多くは 64 ビット・システムによる結果を示しています。ここでは 32 ビット・システムと 64 ビット・システムとで大きく異なる点を示すために、32 ビット・システムの例もいくつか含めてあります。


静的リンクと動的リンク

Ian とつながるには

Ian は developerWorks で人気の高いお馴染みの著者の 1 人です。Ian が書いたすべての developerWorks 記事を閲覧してみてください。また、My developerWorks では、Ian のプロフィールを調べることや、彼やその他の著者、そして他の読者とつながることができます。

Linux システムには次の 2 つのタイプの実行可能プログラムがあります。

  • 静的にリンクされた実行可能プログラム。静的にリンクされた実行可能プログラムには、それらのプログラムが実行する必要のあるライブラリー関数がすべて含まれており、すべてのライブラリー関数は、その実行可能プログラムにリンクされています。これらのライブラリー関数は完全なプログラムであり、実行のために外部のライブラリーに依存することはありません。静的にリンクされたプログラムの利点の 1 つは、何も前提となる条件をインストールしなくても動作することです。
  • 動的にリンクされた実行可能プログラム。動的にリンクされた実行可能プログラムは (静的にリンクされた実行可能プログラムよりも) はるかに小さなプログラムであり、実行には外部の共有ライブラリーの関数が必要、という意味で不完全です。小さなプログラムであることに加え、動的にリンクすることによって、必要なライブラリーを実際にパッケージに含めることなくライブラリーとして指定することができます。また動的なリンクを使用することによって、実行中の多数のプログラムがライブラリーの 1 つのコピーを共有することができ、同じコードのコピーが多数あるためにメモリーが占有されてしまうことがありません。こうした理由から、現在はほとんどのプログラムが動的リンクを使用しています。

多くの Linux システムでの興味深い例として、ファイル間のリンク (ハード・リンクあるいはソフト (またはシンボリック) リンク) を作成する ln コマンド (/bin/ln) があります。このコマンドは共有ライブラリーを使用します。共有ライブラリーには、汎用のライブラリー名と特定レベルのライブラリーとの間にシンボリック・リンクがある場合がよくあります。そのため、何らかの理由でリンクが存在しない場合、あるいはリンクが切れている場合には、ln コマンドそのものが動作不能となり、その結果他のコマンドも使えない、という問題が発生します。この問題の発生を防ぐために、一部の Linux システムには、静的リンク・バージョンの ln プログラムが sln プログラム (/sbin/sln) として含まれています。リスト 1 は、動的リンクの ln と静的リンクの sln とでサイズに大きな違いがあることを示しています。この例は Fedora 12 の 64 ビット・システムから引用したものです。

リスト 1. sln と ln のサイズの違い
[ian@echidna ~]$ ls -l /sbin/sln /bin/ln
-rwxr-xr-x. 1 root root  47384 2010-01-12 09:35 /bin/ln
-rwxr-xr-x. 1 root root 603680 2010-01-04 09:07 /sbin/sln

どのライブラリーが必要なのか?

このトピックは、現在の LPI 試験の出題範囲には含まれていませんが、現在の Linux システムの多くが 32 ビットと 64 ビット両方の実行可能プログラムをサポートするハードウェア上で実行されることを知っておく必要があります。そのため、多くのライブラリーは 32 ビットのバージョンと 64 ビットのバージョンにコンパイルされます。64 ビットのバージョンは通常、ファイルシステムの /lib64 ツリーの下に保存され、32 ビットのバージョンは従来の /lib ツリーの下に保存されます。典型的な 64 ビット Linux システムには通常、/lib/libc-2.11.1.so と /lib64/libc-2.11.1.so の両方があります。この 2 つのライブラリーがあるため、64 ビット Linux システム上で 32 ビットの C プログラムと 64 ビットの C プログラムの両方を実行させることができます。

ldd コマンド

静的にリンクされたプログラムのサイズは大きいことを認識しておくにしても、あるプログラムが静的にリンクされているかどうかを、どのようにして判断するのでしょう?また、プログラムが動的にリンクされている場合、そのプログラムに必要なライブラリーをどのようにして知るのでしょう? ldd コマンドは、この両方の質問に答えることができます。Debian や Ubuntu などのシステムを実行している場合には、おそらく sln 実行可能プログラムはないはずです。そのため、/sbin/ldconfig 実行可能プログラムがないかどうかも調べる必要があります。リスト 2 は、ln および sln 実行可能プログラム、そして ldconfig 実行可能プログラムに対して ldd コマンドを実行した場合の出力を示しています。この例は Fedora 12 の 64 ビット・システム (echidna) から引用したものです。比較のために、古い Fedora 8 の 32 ビット・システム (pinguino) の /bin/ln に ldd コマンドを実行した場合の出力を示してあります。

リスト 2. sln と ln に ldd を実行した場合の出力
[ian@echidna ~]$ #Fedora 12 64-bit
[ian@echidna ~]$ ldd /sbin/sln /sbin/ldconfig /bin/ln
/sbin/sln:
        not a dynamic executable
/sbin/ldconfig:
        not a dynamic executable
/bin/ln:
        linux-vdso.so.1 =>  (0x00007fff644af000)
        libc.so.6 => /lib64/libc.so.6 (0x00000037eb800000)
        /lib64/ld-linux-x86-64.so.2 (0x00000037eb400000)

[ian@pinguino ~]$ # Fedora 8 32-bit
[ian@pinguino ~]$ ldd /bin/ln
        linux-gate.so.1 =>  (0x00110000)
        libc.so.6 => /lib/libc.so.6 (0x00a57000)
        /lib/ld-linux.so.2 (0x00a38000)

ldd は実際には動的リンクを調べるためのものであるため、ldd を実行すると、sln と ldconfig に関してはどちらも「not a dynamic executable (動的な実行ファイルではない)」という表示がされ、このことから sln も ldconfig も静的にリンクされていることがわかります。また ldd は ln コマンドに必要な 3 つの共有ライブラリーの名前 (linux-vdso.so.1、libc.so.6、/lib64/ld-linux-x86-64.so.2) を表示します。ここで、.so は、これらが共有オブジェクトまたは動的ライブラリーであることを示すことに注意してください。またこの出力から、3 つの異なる種類の情報があることがわかります。

linux-vdso.so.1
これは Linux Virtual Dynamic Shared Object です。これについてはこのすぐ後に説明します。また Fedora 8 の場合のように、linux-gate.so.1 と表示される場合もあります。
libc.so.6
/lib64/libc.so.6 へのポインターが含まれています。
/lib64/ld-linux-x86-64.so.2
別のライブラリーへの絶対パスです。

リスト 3 では、ls -l コマンドを使うことで、2 番目と 3 番目のライブラリーがそれぞれ特定のバージョンのライブラリーへのシンボリック・リンクであることを示しています。この例は Fedora 12 の 64 ビット・システムから引用したものです。

リスト 3. ライブラリーへのシンボリック・リンク
[ian@echidna ~]$ ls -l /lib64/libc.so.6 /lib64/ld-linux-x86-64.so.2
lrwxrwxrwx. 1 root root 12 2010-01-14 14:24 /lib64/ld-linux-x86-64.so.2 -> ld-2.11.1.so
lrwxrwxrwx. 1 root root 14 2010-01-14 14:24 /lib64/libc.so.6 -> libc-2.11.1.so

Linux Virtual Dynamic Shared Objects

x86 プロセッサーの初期の頃、ユーザー・プログラムからスーパーバイザー・サービスへの通信はソフトウェア割り込みによって行われていました。プロセッサーが高速化されるにつれ、これは深刻なボトルネックになりました。Intel® では、Pentium® II プロセッサーのときから、割り込みの代わりに SYSENTER 命令と SYSEXIT 命令を使ってシステム・コールを高速化する Fast System Call 機能を導入しました。

linux-vdso.so.1 として見えるライブラリーは、仮想ライブラリー、つまり各プログラムのアドレス空間のみに常駐する Virtual Dynamic Shared Object です。古いシステムでは、これを linux-gate.so.1 と呼んでいました。この仮想ライブラリーはユーザー・プログラムがシステム関数にアクセスするために必要なロジックを提供します。アクセスの手段としては、割り込みであれ、あるいは最新のプロセッサーでの Fast System Call であれ、その特定のプロセッサーで利用可能な最も高速な手段が使われます。


動的なロード

上記の説明から、/lib/ld-linux.so.2 とその 64 ビット版である /lib64/ld-linux-x86-64.so.2 (どちらも共有ライブラリーのように見えます) が、実際にはそれ自体が実行可能プログラムであると知って驚いた人がいるかもしれません。これらのライブラリーは動的なロードを行うコードであり、実行可能プログラムのヘッダー情報を読み取ります (ヘッダー情報は Executable and Linking Format、つまりELF フォーマットです)。このヘッダー情報から、どんなライブラリーが必要か、どのライブラリーをロードする必要があるかを判断します。次に、動的なリンクを実行することで、ロードされたライブラリーと実行可能プログラムに含まれるアドレス・ポインターをすべて修正し、プログラムが実行されるようにします。

ld-linux.so の man ページには、初期の a.out バイナリー・フォーマットに対して同様の操作を行うものであった ld.so も説明されています。リスト 4 は、リスト 2 で ldd コマンドを使って表示したものと同じ情報を ln コマンドで表示するために、ld-linux.so とその 64 ビット版の --list オプションを使う方法を示しています。

リスト 4. ld-linux.so を使って必要なライブラリーを表示する
[ian@echidna ~]$ /lib64/ld-linux-x86-64.so.2 --list /bin/ln
        linux-vdso.so.1 =>  (0x00007fffc9fff000)
        libc.so.6 => /lib64/libc.so.6 (0x00000037eb800000)
        /lib64/ld-linux-x86-64.so.2 (0x00000037eb400000)

[ian@pinguino ~]$ /lib/ld-linux.so.2 --list /bin/ln
        linux-gate.so.1 =>  (0x00110000)
        libc.so.6 => /lib/libc.so.6 (0x00a57000)
        /lib/ld-linux.so.2 (0x00a38000)

2 つのリストの間で 16 進のアドレスが異なる可能性があることに注意してください。ldd を 2 度実行した場合にも 16 進のアドレスが異なる可能性があります。


動的ライブラリーの構成

では動的ローダーは、実行可能ファイルの検索場所をどのようにして知るのでしょう。Linux ではよくあることですが、/etc には構成ファイルがあります。実際には /etc/ld/so/conf と /etc/ld.so.cache という 2 つのファイルがあります。リスト 5 は 64 ビットの Fedora 12 システムの /etc/ld.so.conf の内容を示しています。/etc/ld.so.conf では、ld.so.conf.d サブディレクトリーの .conf ファイルがすべて含まれるように指定していることに注意してください。古いシステムでは、すべてのエントリーが /etc/ld/so/conf に含まれており、/etc/ld.so.conf.d ディレクトリーのエントリーが含まれていないかもしれません。/etc/ld.so.conf ディレクトリーまたは /etc/ld.so.conf.d ディレクトリーの実際の内容はシステムによって異なる可能性があります。

リスト 5. /etc/ld.so.conf の内容
[ian@echidna ~]$ cat /etc/ld.so.conf
include ld.so.conf.d/*.conf
[ian@echidna ~]$ ls /etc/ld.so.conf.d/*.conf
/etc/ld.so.conf.d/kernel-2.6.31.12-174.2.19.fc12.x86_64.conf
/etc/ld.so.conf.d/kernel-2.6.31.12-174.2.22.fc12.x86_64.conf
/etc/ld.so.conf.d/kernel-2.6.31.12-174.2.3.fc12.x86_64.conf
/etc/ld.so.conf.d/mysql-x86_64.conf
/etc/ld.so.conf.d/qt-x86_64.conf
/etc/ld.so.conf.d/tix-x86_64.conf
/etc/ld.so.conf.d/xulrunner-64.conf

プログラムのロードは高速でなければなりません。そのため、ldconfig コマンドを使用することで、ld.so.conf ファイル、ld.so.conf.d ディレクトリーに含まれるすべてのファイル、信頼できるディレクトリーと /lib、/usr/lib に含まれるライブラリー、そしてその他コマンドラインに入力されたものすべてを処理します。ldconfig コマンドによって必要なリンクが作成され、また最近使用された共有ライブラリーに対するキャッシュが /etc/ld.so.cache に作成されます。動的ローダーは ld.so.cache にキャッシュされた情報を使用して、動的なロードとリンクが必要なファイルを検索します。ld.so.conf を変更した場合には (あるいは ld.so.conf.d に新たにファイルを追加した場合には)、ldconfig コマンドを (root として) 実行して ld.so.cache ファイルを作り直す必要があります。

通常、ld.so.cache を作り直す場合には、パラメーターを付けずに ldconfig コマンドを使います。他のいくつかのパラメーターを指定すると、このデフォルト動作を変更することができます。いつものように、詳細については man ldconfig で調べてみてください。リスト 6 は -p パラメーターを使って ld.so.cache の内容を表示する方法を示しています。

リスト 6. ldconfig を使って ld.so.cache を表示する
[ian@lyrebird ian]$ /sbin/ldconfig -p | less
1602 libs found in cache `/etc/ld.so.cache'
        libzip.so.1 (libc6,x86-64) => /usr/lib64/libzip.so.1
        libz.so.1 (libc6,x86-64) => /lib64/libz.so.1
        libz.so (libc6,x86-64) => /usr/lib64/libz.so
        libx86.so.1 (libc6,x86-64) => /usr/lib64/libx86.so.1
        libx11globalcomm.so.1 (libc6,x86-64) => /usr/lib64/libx11globalcomm.so.1
        libxul.so (libc6,x86-64) => /usr/lib64/xulrunner-1.9.1/libxul.so
        libxtables.so.2 (libc6,x86-64) => /usr/lib64/libxtables.so.2
        libxslt.so.1 (libc6,x86-64) => /usr/lib64/libxslt.so.1
        libxslt.so (libc6,x86-64) => /usr/lib64/libxslt.so
        libxpcom.so (libc6,x86-64) => /usr/lib64/xulrunner-1.9.1/libxpcom.so
        libxml2.so.2 (libc6,x86-64) => /usr/lib64/libxml2.so.2
        libxml2.so (libc6,x86-64) => /usr/lib64/libxml2.so
       ...
        libABRTdUtils.so.0 (libc6,x86-64) => /usr/lib64/libABRTdUtils.so.0
        libABRTUtils.so.0 (libc6,x86-64) => /usr/lib64/libABRTUtils.so.0
        ld-linux.so.2 (ELF) => /lib/ld-linux.so.2
        ld-linux-x86-64.so.2 (libc6,x86-64) => /lib64/ld-linux-x86-64.so.2

特定のライブラリーをロードする

特定の古いバージョンの共有ライブラリーを必要とする古いアプリケーションを実行する場合、あるいは新しく共有ライブラリーを作成する場合や共有ライブラリーの新バージョンを作成する場合には、ローダーが使用するデフォルトの検索パスを変更する必要があるかもしれません。また、/opt ツリーにインストールされる、製品特有の共有ライブラリーを使用するスクリプトの場合にも、検索パスを変更する必要があるかもしれません。

PATH 変数を設定することで実行可能プログラムの検索パスを指定できるのと同じように、コロン区切りのディレクトリー・リストに対して LD_LIBRARY_PATH 変数を設定することができます。この設定をすると、ld.so.cache に指定されたシステム・ライブラリーを検索する前に、そのディレクトリーで共有ライブラリーが検索されます。例えば、下記のようなコマンドを使用することができます。

export LD_LIBRARY_PATH=/usr/lib/oldstuff:/opt/IBM/AgentController/lib

さらに詳しい内容や、この連載の他の記事へのリンクについては下記の「参考文献」を参照してください。

参考文献

学ぶために

  • 2009年4月時点での目標に基づく LPIC-1 認定に備えるために必要な developerWorks の記事を見つけるには、developerWorks の LPIC-1 ロードマップを利用してください。
  • LPIC Program サイトで、Linux Professional Institute の 3 つの Linux システム管理資格認定レベルについて、詳しい目標、タスクのリスト、そして出題例を調べてください。特に、2009年4月時点での LPI 101 試験および LPI 102 試験の目標は要チェックです。最新の目標については、必ず LPIC Program サイトを参照してください。
  • developerWorks の連載「LPI exam prep」をすべて読んで、Linux の基礎を学び、2009年4月以前の LPI 試験の目標に基づくシステム管理者認定試験に備えてください。
  • The Linux Documentation Project には、HOWTO 文書をはじめ、各種の有益な文書が豊富に揃っています。
  • developerWorks Linux ゾーンには Linux 開発者や Linux 管理者のための技術記事、チュートリアル、ディスカッション・フォーラム、その他さまざまなリソースが豊富に用意されています。
  • さまざまな IBM 製品、そして IT 業界の話題に焦点を絞った developerWorks の Technical events and webcasts で最新情報を入手してください。
  • 無料の developerWorks Live! ブリーフィングに出席し、IBM の製品やツール、また IT 業界のトレンドに関する最新情報を入手してください。
  • developerWorks On demand demos をご覧ください。初心者を対象とした、製品のインストール方法やセットアップ方法の説明から、経験豊富な開発者のための高度な機能の説明に至るまで、多様な内容が網羅されています。
  • Twitter で developerWorks をフォローしてください。

製品や技術を入手するために

  • ご自分に最適な方法で IBM 製品を評価してください。評価の方法としては、製品の試用版をダウンロードすることも、オンラインで製品を試してみることも、クラウド環境で製品を使用することもできます。また、SOA Sandbox では、数時間でサービス指向アーキテクチャーの実装方法を効率的に学ぶことができます。

議論するために

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Linux
ArticleID=480430
ArticleTitle=Linux の 101 試験対策: 共有ライブラリーの管理
publish-date=03102010