システムログをユーザースペースに印刷できるLinuxキャラクタードライバーを書いています。コマンド「dmesg」と同じように。'printk'で出力するすべてのログは、リングバッファという名前のスペースに送信されることを学びました。だから私は質問があります:
- リングバッファはカーネルスペース内にありますか?
- もしそうなら、どうすればカーネル空間内のリングバッファを読み取ることができますか?(dmesg.cのソースコードを読み込もうとしましたが、役に立ちませんでした。)
システムログをユーザースペースに印刷できるLinuxキャラクタードライバーを書いています。コマンド「dmesg」と同じように。'printk'で出力するすべてのログは、リングバッファという名前のスペースに送信されることを学びました。だから私は質問があります:
あなたが探しているのは です/proc/kmsg
。これがカーネル リング バッファです。
はい、これはカーネル空間内です。それを読み取ろうとするプロセスには、それを読み取るためのスーパーユーザー権限が必要です!
リングバッファの読み方は?これは、IBM Developerworks の美しいイラストです。
dmesg
あなたの最初のリゾートになります!dmesgはどのようにそのタスクを達成しますか? への呼び出しによってsyslog()
! syslogはどのように機能しますか? 次に呼び出すシステムコールインターフェースを介してdo_syslog()
。do_syslog()
仕上げはこのように行います。
/proc/kmsg
一般的なカーネルログに関する詳細情報を取得するためのリソースをいくつか次に示します。
これは、Pavan の非常に優れた回答 (私に多くのことを教えてくれました) へのさらなるものです。
異なるディストリビューションでは、/proc/kmsg の出力を任意の物理ログ ファイルまたは仮想デバイス (/dev/xxx) にリダイレクトできます。ただし、「/proc/kmsg」はカーネル ログの元のソースです。これは、カーネルが fs/proc/kmsg.c 内でリング バッファー操作を実装しているためです。
static const struct file_operations proc_kmsg_operations = {
.read = kmsg_read,
.poll = kmsg_poll,
.open = kmsg_open,
.release = kmsg_release,
.llseek = generic_file_llseek,
};
したがって、出力は次のようになります。
sudo テール -f /proc/kmsg
ただし、このコマンドを発行した後に生成されたすべてのメッセージのみを表示できます。リング バッファー内の以前のメッセージはすべて出力されません。したがって、物理ファイルの出力を表示するには、「/proc/kmsg」のユーザーを検索できます。
sudo lsof |grep proc.kmsg
そして、私のマシンはこれを示しました:
rsyslogd 1743 syslog 3r REG 0,3 0 4026532041 /proc/kmsg
in:imuxso 1743 1755 syslog 3r REG 0,3 0 4026532041 /proc/kmsg
in:imklog 1743 1756 syslog 3r REG 0,3 0 4026532041 /proc/kmsg
rs:main 1743 1757 syslog 3r REG 0,3 0 4026532041 /proc/kmsg
これで pid 1743 になりました。1743 によって開かれたファイル fd を見てみましょう。
sudo ls -al /proc/1743/fd
lrwx------ 1 root root 64 Dec 11 08:36 0 -> socket:[14472]
l-wx------ 1 root root 64 Dec 11 08:36 1 -> /var/log/syslog
l-wx------ 1 root root 64 Dec 11 08:36 2 -> /var/log/kern.log
lr-x------ 1 root root 64 Dec 11 08:36 3 -> /proc/kmsg
l-wx------ 1 root root 64 Dec 11 08:36 4 -> /var/log/auth.log
pid 1743 は rsyslogd であり、/proc/kmsg の出力を /var/log/syslog や /var/log/kern.log などのファイルにリダイレクトします。