コンソールログレベル
Rev.1を表示中。最新版はこちら。
コンソールログレベルの設定はコンソールの出力するログレベルを設定するもので、/proc/sys/kernel/printkで設定することができます。4つの数字が表示されますが、頭から、console_loglevel/default_message_loglevel/minimum_console_loglevel/default_console_loglevelと成っていて、sys_logd()でconsole_loglevelに設定することで、console_loglevelそれそり小さいログレベルのみが表示されるように成っているだけのものです。処理内容はソースを見てもらえば・・・という内容ですが、まあ、type=8は任意のコンソールログレベルを設定できるモードですが、minimum_console_loglevel以下のレベルは設定できない。と言うぐらいです。
[kitamura@localhost root]$ cat /proc/sys/kernel/printk 4 4 1 7
#define DEFAULT_MESSAGE_LOGLEVEL 4 /* KERN_WARNING */ #define MINIMUM_CONSOLE_LOGLEVEL 1 /* Minimum loglevel we let people use */ #define DEFAULT_CONSOLE_LOGLEVEL 7 /* anything MORE serious than KERN_DEBUG */ int console_printk[4] = { DEFAULT_CONSOLE_LOGLEVEL, /* console_loglevel */ DEFAULT_MESSAGE_LOGLEVEL, /* default_message_loglevel */ MINIMUM_CONSOLE_LOGLEVEL, /* minimum_console_loglevel */ DEFAULT_CONSOLE_LOGLEVEL, /* default_console_loglevel */ }; #define console_loglevel (console_printk[0]) #define default_message_loglevel (console_printk[1]) #define minimum_console_loglevel (console_printk[2]) #define default_console_loglevel (console_printk[3]) int do_syslog(int type, char __user *buf, int len) { : : switch (type) { : : case 6: /* Disable logging to console */ console_loglevel = minimum_console_loglevel; break; case 7: /* Enable logging to console */ console_loglevel = default_console_loglevel; break; case 8: /* Set level of messages printed to console */ error = -EINVAL; if (len < 1 || len > 8) goto out; if (len < minimum_console_loglevel) len = minimum_console_loglevel; console_loglevel = len; error = 0; break; : : } out: return error; }_call_console_drivers()はprintk()から、ログをリングバッファにセットしたのち、コンソールへの出力として、本関数がコールされます。引数の msg_log_levelは、カーネルが出力したログのレベルです。それがconsole_loglevelより小さい場合のみ、表示するようにしています。
static void _call_console_drivers(unsigned start, unsigned end, int msg_log_level) { if ((msg_log_level < console_loglevel || ignore_loglevel) && console_drivers && start != end) { if ((start & LOG_BUF_MASK) > (end & LOG_BUF_MASK)) { /* wrapped write */ __call_console_drivers(start & LOG_BUF_MASK, log_buf_len); __call_console_drivers(0, end & LOG_BUF_MASK); } else { __call_console_drivers(start, end); } } }default_message_loglevelはカーネルが出力するログレベルは以下の通りで、<ログレベル>ログのフォーマットになっています。
#define KERN_EMERG "<0>" /* system is unusable */ #define KERN_ALERT "<1>" /* action must be taken immediately */ #define KERN_CRIT "<2>" /* critical conditions */ #define KERN_ERR "<3>" /* error conditions */ #define KERN_WARNING "<4>" /* warning conditions */ #define KERN_NOTICE "<5>" /* normal but significant condition */ #define KERN_INFO "<6>" /* informational */ #define KERN_DEBUG "<7>" /* debug-level messages */vprintk()はprintk()からコールされています。先頭が<数値>でないなら、そこにcurrent_log_level=default_message_loglevelが設定されるようになっています。
asmlinkage int vprintk(const char *fmt, va_list args) { int printed_len = 0; int current_log_level = default_message_loglevel; : for (p = printk_buf; *p; p++) { if (new_text_line) { /* If a token, set current_log_level and skip over */ if (p[0] == '<' && p[1] >= '0' && p[1] <= '7' && p[2] == '>') { current_log_level = p[1] - '0'; p += 3; printed_len -= 3; } emit_log_char('<'); emit_log_char(current_log_level + '0'); emit_log_char('>'); printed_len += 3; new_text_line = 0; : } } : if (acquire_console_semaphore_for_printk(this_cpu)) release_console_sem(); : }