KLOGD(8)

名前
klogd - カーネルログデーモン

書式
klogd [ -c n ] [ -d ] [ -f fname ] [ -iI ] [ -n ] [ -o ] [ -p ] [ -s ] [ -k fname ] [ -v ] [ -x ] [ -2 ]

説明
klogd は Linux のカーネルメッセージを捕え記録するシステムデーモンである。

オプション

-c n
    コンソールに出力するログのレベルの既定値を n にする。

-d  デバッグモード。これは大量に stderr に出力する。

-f file
    syslog の facility ではなくて指定した名前のファイルにメッセージを記録 する。

-i -I
    現在実行されている klogd デーモンにシグナルを送る。 どちらのオプションもシンボル情報を(再)読み込みするように指示する。 -iオプションはカーネルモジュールシンボルを再読み込みさせる。 -Iオプションは静的カーネルシンボルとカーネルモジュールシンボルの 両方を再読み込みさせる。

-n  自動的なバックグラウンドへの移行を抑止する。これは klogd が init(8) により起動および制御される場合にのみ必要である。

-o  `ワンショット'モードで実行する。klogd はカーネルメッセー ジバッファに存在する全てのメッセージを読み出し記録する。一回の読み出 しと記録ののちデーモンは終了する。

-p  パラノイアモード。klog がいつカーネルモジュールシンボルを読み込むかを指定する。 このオプションを設定すると、カーネルメッセージストリームに "Oops" の文字列が 流れる毎にカーネルモジュールシンボルの情報を読み込む。

-s  klogd はカーネルメッセージバッファとのインターフェイスにシステム コールの使用を強行する。

-k file
    カーネルシンボル情報を指定した名前のファイルから取得する。

-v  バージョンを出力し、終了する。

-x  EIP 変換を抑制し、 System.map を読み込まない。

-2  シンボルが展開された時、 アドレスをシンボルに変換したものと生テキストの 2 回表示する。 これにより、ksymoops のような外部プログラムが変換される前の データを使って処理を行えるようになる。

概説
klogd の機能はよく他の版の syslogd に編入されてしまいがちであるが、そ れはあまり良い方法とは思われない。最近の Linux カーネルにおいては、情 報源の特定、順位付け、カーネルアドレスの解決など多くのメッセージに関す る問題を扱わなければならない。カーネルロギングを個別のプロセスとするこ とは、各種サービスの分割を明確なものにする。

Linux ではカーネルログ情報の情報源として二つの可能性がある。 /proc ファイルシステムと syscall (sys_syslog) インターフェースであるが、 突き詰めていけばこれらは同じ一つのものである。 klogd は最もふさわしい情報としてどちらかを選択するように設計されている。 最初に、実際にマウントされている /proc ファイルシステムを確認する。もしそこに /proc/kmsg ファイルがあれば、それをカーネルログ情報の情報源として利用する。もし proc ファイルシステムがマウントされていなければ、 klogd はカーネルメッセージの取得にシステムコールを利用する。コマンドラインス イッチの (-s) は klogd にその情報源としてシステムコールの利用を強行させる。

もしカーネルメッセージが syslogd デーモンに振り向けられたとしても、 version 1.1 の klogd デーモンはその優先順位を適切に判定することが可能である。 カーネルメッセージの優先順位付けは version 0.99pl13 あたり のカーネルで実装された。生のカーネルメッセージの形式は次の通り:

    <[0-7]>カーネルからの出力

カーネルメッセージの優先順位は <> 括弧に閉じられた一桁の数字に変換される。 この数値はカーネルの include ファイル kernel.h で定義されている。 カーネルからメッセージを受けると klogd デーモンはこの優先順位を読み取り、 適切な syslog のメッセージレベルに割り付ける。 (-f) によってファイルへの出力が指示されている場合には、カーネルメッセージに 優先順位番号が残される。

klogd デーモンはカーネルメッセージの出力先をシステムコンソールへ変更す ることもできる。カーネルによって優先順位が付けられる結果として、 メッセージはそれぞれデフォルトの既定のカーネルへのメッセージレベルが 割り当てられている。 手を加えていないカーネルのデフォルトのコンソールへのメッセージレベルは 7 に設定されている。7 よりも小さい(つまり高い)優先順位レベルを持つメッ セージはコンソールに出力される。

レベル 7 の優先順位を持つメッセージは `debug' メッセージとみなされ、 コンソールには出力されない。特にマルチユーザ環境における、多くのシ ステム管理者は全てのカーネルメッセージを klogd により管理させ、 ファイルか syslogd デーモンに渡したいと思うだろう。そうすれば、 プリンタの用紙切れとかディスクの交換検出のような`わずらわしい'メッセージ のコンソールへの出力を避けることができる。

-c オプションが指定されると、 klogd デーモンはコンソールに表示される全てのカーネルメッセージを抑制する システムコールを実行する。 以前のバージョンでは常にこのシステムコールが実行され、 そのデフォルトは panic を除くすべてのカーネルメッセージであった。 最近のバージョンでは少し違う扱いをしており、 もはやこのオプション値を設定する必要はない。 -c オプションの引数にはコンソールへ出力すべきメッ セージの優先順位レベルを指定する。指示される数字「よりも小さい」優先順 位値を持つメッセージがコンソールへ出力される、という点に注意すること。

    たとえば、優先順位値が 3 (KERN_ERR) かそれよりも重要なすべてのメッセージをコンソールに出力するためには、次 のコマンドを実行する:

    	klogd -c 4

カーネルメッセージの(優先順位の)数値は、カーネルのソースコードが インストールされているのであれば、 /usr/include/linux にある kernel.h ファイルで定義されている。これらの数値は /usr/include/sys サブディレクトリにある syslog.h ファイルでの優先順位値の定義に対応している。

klogd デーモンはカーネルメッセージを読み出す 'ワンショット' モードも利 用可能である。ワンショットモードはコマンドラインの -o オプション で指示される。その出力は syslogd デーモンに渡されるか -f スイッ チが指定されていれば代りのファイルに書き出される。

    たとえば、システムがブートした際のカーネルメッセージを全て読み出して、 それを krnl.msg という名前のファイルに記録するには次のコマンドを実行す る。

    	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 ファイルシステムの利用を解除するには次の順番でコマンド を実行すればよい:

# kill -TSTP pid
# umount /proc
# kill -CONT pid

LOG_INFO 優先順位を持つシステムログがその停止/再開を記録する。

SIGUSR1 と SIGUSR2 はカーネルシンボル情報を(再)読み込みさせるために用いる。 SIGUSR1 はカーネルモジュールシンボルを再読み込みさせる。 SIGUSR2 は静的カーネルシンボルとカーネルモジュールシンボルの両方を再読み込みさせる。

System.map ファイルが適切な位置に置かれているなら、 最も有効なシグナルは一般に SIGUSR1 である。 このシグナルはカーネルモジュールが(再)読み込みされた時のために 用意されている。 カーネルモジュールの状態が変わった後にこのシグナルをデーモンに送れば、 カーネルモジュールが占めているアドレス空間で保護違反が起きた時に 適切にシンボルを解決できることが保証される。

ファイル
/proc/kmsg
    klogd の記録するカーネルメッセージ源の一つ
/var/run/klogd.pid
    klogd のプロセス id が記録されているファイル
/boot/System.map, /System.map, /usr/src/linux/System.map
    カーネルシステムマップのデフォルト位置

バグ
多分、沢山。整理されたコンテキスト diff を送ってくれれば歓迎します。

著者
klogd のオリジナルは Steve Lord (lord@crya.com)によって書かれ、Greg Wettstein が多くの改善を施した。
Dr. Greg Wettstein (greg@wind.enjellic.com)
Enjellic Systems Development

Oncology Research Divsion Computing Facility
Roger Maris Cancer Center
Fargo, ND 58122