KLOGD(8) | Linux System Administration | KLOGD(8) |
klogd - カーネルログデーモン
klogd [ -c n ] [ -d ] [ -f fname ] [ -iI ] [ -n ] [ -o ] [ -p ] [ -s ] [ -k fname ] [ -v ] [ -x ] [ -2 ]
klogd は Linux のカーネルメッセージを捕え記録するシステムデーモンである。
klogd の機能はよく他の版の syslogd に編入されてしまいがちであるが、そ れはあまり良い方法とは思われない。最近の Linux カーネルにおいては、情 報源の特定、順位付け、カーネルアドレスの解決など多くのメッセージに関す る問題を扱わなければならない。カーネルロギングを個別のプロセスとするこ とは、各種サービスの分割を明確なものにする。
Linux ではカーネルログ情報の情報源として二つの可能性がある。 /proc ファイルシステムと syscall (sys_syslog) インターフェースであるが、 突き詰めていけばこれらは同じ一つのものである。 klogd は最もふさわしい情報としてどちらかを選択するように設計されている。 最初に、実際にマウントされている /proc ファイルシステムを確認する。もしそこに /proc/kmsg ファイルがあれば、それをカーネルログ情報の情報源として利用する。もし proc ファイルシステムがマウントされていなければ、 klogd はカーネルメッセージの取得にシステムコールを利用する。コマンドラインス イッチの (-s) は klogd にその情報源としてシステムコールの利用を強行させる。
もしカーネルメッセージが syslogd デーモンに振り向けられたとしても、 version 1.1 の klogd デーモンはその優先順位を適切に判定することが可能である。 カーネルメッセージの優先順位付けは version 0.99pl13 あたり のカーネルで実装された。生のカーネルメッセージの形式は次の通り:
カーネルメッセージの優先順位は <> 括弧に閉じられた一桁の数字に変換される。 この数値はカーネルの include ファイル kernel.h で定義されている。 カーネルからメッセージを受けると klogd デーモンはこの優先順位を読み取り、 適切な syslog のメッセージレベルに割り付ける。 (-f) によってファイルへの出力が指示されている場合には、カーネルメッセージに 優先順位番号が残される。
klogd デーモンはカーネルメッセージの出力先をシステムコンソールへ変更す ることもできる。カーネルによって優先順位が付けられる結果として、 メッセージはそれぞれデフォルトの既定のカーネルへのメッセージレベルが 割り当てられている。 手を加えていないカーネルのデフォルトのコンソールへのメッセージレベルは 7 に設定されている。7 よりも小さい(つまり高い)優先順位レベルを持つメッ セージはコンソールに出力される。
レベル 7 の優先順位を持つメッセージは `debug' メッセージとみなされ、 コンソールには出力されない。特にマルチユーザ環境における、多くのシ ステム管理者は全てのカーネルメッセージを klogd により管理させ、 ファイルか syslogd デーモンに渡したいと思うだろう。そうすれば、 プリンタの用紙切れとかディスクの交換検出のような`わずらわしい'メッセージ のコンソールへの出力を避けることができる。
-c オプションが指定されると、 klogd デーモンはコンソールに表示される全てのカーネルメッセージを抑制する システムコールを実行する。 以前のバージョンでは常にこのシステムコールが実行され、 そのデフォルトは panic を除くすべてのカーネルメッセージであった。 最近のバージョンでは少し違う扱いをしており、 もはやこのオプション値を設定する必要はない。 -c オプションの引数にはコンソールへ出力すべきメッ セージの優先順位レベルを指定する。指示される数字「よりも小さい」優先順 位値を持つメッセージがコンソールへ出力される、という点に注意すること。
klogd -c 4
カーネルメッセージの(優先順位の)数値は、カーネルのソースコードが インストールされているのであれば、 /usr/include/linux にある kernel.h ファイルで定義されている。これらの数値は /usr/include/sys サブディレクトリにある syslog.h ファイルでの優先順位値の定義に対応している。
klogd デーモンはカーネルメッセージを読み出す 'ワンショット' モードも利 用可能である。ワンショットモードはコマンドラインの -o オプション で指示される。その出力は syslogd デーモンに渡されるか -f スイッ チが指定されていれば代りのファイルに書き出される。
klogd -o -f ./krnl.msg
カーネルが内部エラー状態を検出すると、 一般保護違反 (General Protection Fault) が発生する。 GPF 処理手続きの一部として、カーネルは違反が発生した時点での プロセッサの状態を示すステータス報告を表示する。 この表示にはプロセッサのレジスタの内容、カーネルスタックの内容、 違反が発生した時にどの関数が実行されていたかのトレースが含まれる。
この情報は内部エラー状態が発生した原因を特定するために 極めて重要 である。 カーネル開発者がこの情報を分析しようとすると、困難が生じる。 なぜならカーネルは全て同じなわけではなく、 変数の位置や関数のアドレスはカーネルごとに異なるからである。 エラーの原因を診断するためには、カーネル開発者は 特定のカーネルの、どの関数や変数位置がエラーに関係したかを知る必要がある。
カーネルコンパイル処理の一部として、 コンパイルされたカーネルにおける重要な変数と関数のアドレスを記した一覧が作成される。 この一覧は カーネルディレクトリソースツリーのトップに System.map という名前で 作成される。 この一覧を使って、カーネル開発者はエラー状態が発生した時に カーネルが何をしていたかを正確に知ることができる。
保護違反の表示から数値表現のアドレスを解決する処理は、 手動かまたはカーネルソースに含まれる ksymoops プログラムを使って行なわれる。
利便性のために、 klogd はカーネルの数値表現のアドレスを、それらのシンボル表現に変換しようとする。 ただし実行時にカーネルのシンボルテーブルが必要である。 もしシンボルの元のアドレスも必要な場合は、 -2 を使うと数値アドレスも保存される。 シンボルテーブルはコマンドラインの -k オプションを用いて指定する。 シンボルファイルが明示されない場合は、次の順番でファイルを探す:
/boot/System.map /System.map /usr/src/linux/System.map
カーネル 1.3.43 のシステムマップから、 バージョン情報も提供されるようになっている。 バージョン情報はシンボルテーブルのリストを解析検索する際に利用される。 この機能は(カーネルの)安定版と先進版の両方で提供されているので (その判別に)役に立つ。
たとえば、安定版のカーネルはそのマップファイルを /boot/System.map に持っ ている。もし先進版のカーネルが /usr/src/linux の `標準の' 配置でコンパ イルされているのであれば、システムマップは /usr/src/linux/System.map に存在する。klogd は先進版のもとで起動する時には /usr/src/linux/System.map マップファイル を優先して利用し、 /boot/System.map マップファイルは無視する。
1.3.43 以降の最近のカーネルでは klogd がきちんと理解し、変換できるように 重要なカーネルアドレスは適切に整列されている。それ以前のカーネルはカー ネルのソースコードへのパッチが必要であり、そのパッチは sysklogd のソー スコードと共に提供されている。
カーネル保護違反の分析処理は、静的カーネルに対しては非常にうまくいく。 ローダブルカーネルモジュールで発生したエラーを診断しようとすると さらなる困難に出会うことになる。 ローダブルカーネルモジュールはカーネルの機能の一部を 自由にロードしたりアンロードしたりするのに用いられる。 ローダブルモジュールはデバッグの観点から有用であり、 カーネルが必要とするメモリの量を減らすのにも有用である。
ローダブルモジュールのエラー診断が困難なのは、 カーネルモジュールが動的であるということによる。 モジュールがロードされるとカーネルはモジュールを保持するためのメモリを確保し、 モジュールがアンロードされるとこのメモリはカーネルに返される。 動的にメモリが確保されるため、カーネルローダブルモジュールの 変数や関数のアドレスの詳細を記したマップファイルを作成することは不可能である。 マップファイルなしではカーネルモジュールによる保護違反が発生した時に カーネル開発者が何が悪いのかを判断することは不可能である。
klogd はカーネルローダブルモジュールで発生した保護違反を診断する際に生じる この問題を扱えるようになっている。 プログラム開始時やシグナルを受け取った時に、klogd は 全てのロードされているモジュールと それらがロードされているメモリアドレスの一覧を問い合わせる。 これらの外部シンボルのアドレスもこの問い合わせ処理の間に決定される。
保護違反が発生すると、 静的シンボルテーブルからカーネルアドレスの解決を試みる。 これに失敗した場合、 現在ロードされているモジュールのシンボルを用いてアドレスの解決を試みる。 これにより、最小限ではあるが、 klogd は保護違反を起こしたローダブルモジュールがどれかを示すことができるようになる。 もしモジュール開発者がモジュールからシンボル情報をエクスポートするように していれば、追加の情報も得られる。
カーネルモジュールのアドレスを適切かつ正確に解決するためには、 カーネルモジュールの状態が変わる度にそれを klogd に知らせる必要がある。 -i と -I オプションは現在起動しているデーモンにシンボル情報を再読み込みするように 指示するために使われる。 ほとんどの場合、適切にモジュールシンボルを解決させるために必要なのは -i オプションである。カーネルモジュールが追加または削除される度に、 以下のコマンドを実行するべきである。
klogd -i
-p オプションもカーネルシンボル情報が最新であることを保証するために用いられる。 このオプションは、保護違反が発生する度に klogd にモジュールシンボル情報を再読み込みするように指示する。 プログラムを「パラノイア」モードで動かす前に注意してほしい。 保護違反が発生した時のカーネルと実行環境の安定性は常に疑問である。 モジュールシンボル情報を読み込むために klogd デーモンが システムコールを実行する必要があるため、 システムが不安定になって有用な情報が得られなくなる可能性がある。 モジュールがロード・アンロードされた時に klogd (の情報)が更新される ことを保証する方が遥かによい方法である。 最新のシンボル情報をあらかじめ読み込んでおくことにより、 保護違反が起きた時にそれを正しく解決する可能性が上昇する。
sysklogd のソースパッケージには modules-2.0.0 パッケージに対するパッチが含まれている。 このパッチを適用すると、 insmod, rmmod, modprobe を使ってカーネルにモジュールを追加・削除した時に 自動的に klogd にシグナルを送るようになる。
klogd は以下の 8 種類のシグナルに反応する: SIGHUP, SIGINT, SIGKILL, SIGTERM, SIGTSTP, SIGUSR1, SIGUSR2, SIGCONT 。このうち SIGINT, SIGKILL, SIGTERM, SIGHUP の各シグナルはデーモンにカーネルログの生成源を閉じさせ、適切に終了させる。
SIGTSTPと SICONT の両シグナルはカーネルロギングの開始と終了のために利用される。 SIGTSTP シグナルを受信するとデーモンはそのログの生成源を閉じ、アイドルループに 突入する。その次に SIGCONT を受信するとデーモンは初期化を実行したのち、その入力源を再度選択し実行 を再開する。 SIGSTOPと SIGCONT の組合せは無停止でカーネルログの入力源を再選択させることができる。例え ば、/proc ファイルシステムの利用を解除するには次の順番でコマンド を実行すればよい:
LOG_INFO 優先順位を持つシステムログがその停止/再開を記録する。
SIGUSR1 と SIGUSR2 はカーネルシンボル情報を(再)読み込みさせるために用いる。 SIGUSR1 はカーネルモジュールシンボルを再読み込みさせる。 SIGUSR2 は静的カーネルシンボルとカーネルモジュールシンボルの両方を再読み込みさせる。
System.map ファイルが適切な位置に置かれているなら、 最も有効なシグナルは一般に SIGUSR1 である。 このシグナルはカーネルモジュールが(再)読み込みされた時のために 用意されている。 カーネルモジュールの状態が変わった後にこのシグナルをデーモンに送れば、 カーネルモジュールが占めているアドレス空間で保護違反が起きた時に 適切にシンボルを解決できることが保証される。
多分、沢山。整理されたコンテキスト diff を送ってくれれば歓迎します。
klogd のオリジナルは Steve Lord (lord@crya.com)によって書かれ、Greg Wettstein が多くの改善を施した。
21 August, 1999 | Version 1.4 |