3

Linuxの質問なので、OpenSUSE12.1を使用していることに注意してください。

私はカーネルモジュールを実行しています。基本的にはCANバスシミュレーターでありprintk()、「バス」でアクティビティが発生するたびにメッセージを出力します。

現在、でメッセージをトレースしていますsudo cat /proc/kmsgが、他の「デバイス」を「バス」に配置し始めると、kmsgトラフィックが大幅に増加し、メッセージを見つけるのが困難になります。

「printk」メッセージを1つの特定のプロセスからファイルにパイプする方法はありますか?

編集 デバッグメッセージに特定のタグを追加すると可能性があることがわかりましたが、他の方法はありますか?

4

2 に答える 2

6

はい、できます。すべてのカーネルメッセージはsyslog-ngデーモンを保持できます。このデーモンでは、カスタムルールを記述し、モジュールからのすべてのメッセージを特定のファイルに配置できます。/etc/syslog-ng/syslog-ng.confを最初に見てください

アップデート

デフォルトでは、すべてのカーネルprintおよびprintk関数は、メッセージをカーネルリングバッファに配置します。ユーザースペースプログラムは、このリングバッファthought / proc/kmsgファイルにアクセスできます。

Syslog-ngは/proc/ kmsgからデータを読み取り、次にfilter(フィルターは単なる特殊パターン)grep出力を介して、データを別の出力(この例では単なるテキストファイル)に配置します。出力バッファにカーネルモジュール「hello」からの出力が見つかった場合、syslog-ngはメッセージを/ var / log / helloに配置し、他のすべてのメッセージは/ var / log/messagesに移動します

モジュールソース

#include <linux/module.h>       
#include <linux/kernel.h>       

#define MODNAME "[hello]"

int init_module(void)
{
        printk(KERN_WARNING MODNAME "Hello world 1.\n");    
        return 1;
}

void cleanup_module(void)
{
        printk(KERN_ALERT "Goodbye world 1.\n");
}

insmod後

insmod hello-1.ko

/ var / log / messagesには、次のものがあります。

9月20日17:46:20ns1カーネル:[96643.968650] [hello] Helloworld1。

OK、grepログメッセージをキャッチするようにsyslog-ngを設定しましょう(パターン[hello]を使用)

$ cat /etc/syslog-ng/syslog-ng.conf

@version: 3.2
# $Header: /var/cvsroot/gentoo-x86/app-admin/syslog-ng/files/syslog-ng.conf.gentoo.3.2,v 1.1 2011/01/18 17:44:14 mr_bones_ Exp $
#
# Syslog-ng default configuration file for Gentoo Linux

options {
        chain_hostnames(no);    
        stats_freq(43200);
        mark_freq(3600);
};

source src {
    unix-stream("/dev/log" max-connections(256));
    internal();
    file("/proc/kmsg");
};

destination messages { file("/var/log/messages"); };
# output file for ower module
destination hello_messages { file("/var/log/hello"); };   

# grep patterns for ower module
filter f_hello { match("hello" value("MESSAGE")); };
filter f_kernel { facility(kern); };

log { source(src); destination(messages); };
log { source(src); destination(console_all); };

# target for logging    
log { source(src); filter(f_hello); filter(f_kernel); destination(hello_messages); };
于 2012-09-19T18:01:08.860 に答える
2

これを実現する別の方法があります。最近のカーネルの組み込みの「ftrace」サポートを使用することです。

a)非常に大量のprintkトラフィックの場合、printkはシステムのボトルネックまたはクラッシュを引き起こす可能性があります。その後、trace_printk()の使用に切り替える必要があります。オーバーヘッドはほとんど重要ではありません(特にprintkと比較して)b)ftraceには、特定のプロセスのftraceリングバッファをフィルタリングする機能があります。

ここで詳細を読んでください(最近のカーネルソースツリー内): Documentation / trace / ftrace.txt

追加リソース:「Ftraceを使用したカーネルのデバッグ-パート1」 http://lwn.net/Articles/365835/ (パート2も参照)。

于 2012-09-21T04:04:23.130 に答える