3

カーネルローダブルモジュールでprintkを使用して、システムコールのパラメーターをログに記録しています。システムコールごとに、いくつかのprintkを使用して、区切り文字として「\t」が付いた変数ホエーを出力します。カーネルログバッファ内のデータをシステム/var/ log / messages以外の別のファイルにリダイレクトするには、「klogd-f」を使用してsyslogインターフェイスをバイパスします。取得されるログデータは、システムコールごとに1行です。しかし、データを分析したところ、2つの問題があることがわかりました。

問題1:データが失われる可能性があります。

問題2:あるシステムコールのデータが別のシステムコールに属するデータと混合されている(おそらく途中で)。

質問1:データの損失は、バッファ内の最も古いログを上書きするカーネルログバッファオーバーフローが原因ですか?もしそうなら、それを克服する方法は?カーネルログバッファのサイズを増やす予定です。あなたはそれが適切で、どのサイズが最適だと思いますか?

質問2:システムコールは別のシステムコールをプリエンプトできますか?または、状況によっては、あるシステムコールが別のシステムコールを呼び出し、呼び出されたシステムコールが終了しない限り終了できない場合がありますか?これがデータが混ざり合う理由ですか?

質問3:printkはアトミックですか?そうでない場合、printkをアトミックにする方法は?中断できないようにロックを追加しますか?

4

1 に答える 1

2

プログラムが作成しているすべてのシステム コール (引数付き) のダンプが必要な場合は、コマンドを調べてくださいstrace

質問 1: そうですね。カーネル ログ バッファは、リング バッファとして実装されます。リング バッファが 128K で、カーネルがブート以降に合計 129K 相当のデータを書き込む場合、最初の 1K は最新のデータで上書きされます。このバッファーのサイズは、カーネル ブート引数をlog_buf_len使用して、またはコンパイル時にカーネルの .config ファイルで増やすことができます。dmesg を実行してリング バッファーのサイズを変更することもできますdmesg -s524288。これを実行すると、512KiB に設定されます。吐き出すデータの量に応じて、最適なサイズを決定する必要があります。

質問 2: 1 つのシステム コールが別のシステム コールをプリエンプトする可能性があります。また、カーネルにはプリエンプションのケースが他にもたくさんあります。割り込みサービス ルーチンがその代表的な例です。また、マルチコア システムを使用している場合は、アクティブなカーネル スレッドが複数存在する可能性があります。

質問 3: printk がカーネルのリング バッファをロックしようとしていると思います。ただし、パニック状態から printk を呼び出すことができるため、少し複雑です。

于 2012-10-03T20:28:55.060 に答える