syslogd 详解三:klogd 剖析

文章出处:https://blog.csdn.net/shift_wwx/article/details/101714087

请转载的朋友标明出处,请支持原创~~

 

系列博文:

syslogd 详解一:syslogd 架构和源码剖析

syslogd 详解二:源码分析syslogd config

syslogd 详解三:klogd 剖析

 

 

0. 前言

前两篇博文 syslogd详解一 和 syslogd 详解二 中详细解析了syslod的流程和实现原理,本篇将分析中syslog 中的另一部分——klogd。

1. 源码分析

int klogd_main(int argc UNUSED_PARAM, char **argv)
{int i = 0;char *opt_c;int opt;int used;setup_common_bufsiz();opt = getopt32(argv, "c:n", &opt_c);if (opt & OPT_LEVEL) {/* Valid levels are between 1 and 8 */i = xatou_range(opt_c, 1, 8);}if (!(opt & OPT_FOREGROUND)) {bb_daemonize_or_rexec(DAEMON_CHDIR_ROOT, argv);}logmode = LOGMODE_SYSLOG;/* klogd_open() before openlog(), since it might use fixed fd 3,* and openlog() also may use the same fd 3 if we swap them:*/klogd_open();openlog("kernel", 0, LOG_KERN);if (i)klogd_setloglevel(i);signal(SIGHUP, SIG_IGN);/* We want klogd_read to not be restarted, thus _norestart: */bb_signals_recursive_norestart(BB_FATAL_SIGS, record_signo);syslog(LOG_NOTICE, "klogd started: %s", bb_banner);write_pidfile(CONFIG_PID_FILE_PATH "/klogd.pid");used = 0;while (!bb_got_signal) {int n;int priority;char *start;/* "2 -- Read from the log." */start = log_buffer + used;n = klogd_read(start, KLOGD_LOGBUF_SIZE-1 - used);if (n < 0) {if (errno == EINTR)continue;bb_perror_msg(READ_ERROR);break;}start[n] = '\0';/* Process each newline-terminated line in the buffer */start = log_buffer;while (1) {char *newline = strchrnul(start, '\n');if (*newline == '\0') {/* This line is incomplete *//* move it to the front of the buffer */overlapping_strcpy(log_buffer, start);used = newline - start;if (used < KLOGD_LOGBUF_SIZE-1) {/* buffer isn't full */break;}/* buffer is full, log it anyway */used = 0;newline = NULL;} else {*newline++ = '\0';}/* Extract the priority */priority = LOG_INFO;if (*start == '<') {start++;if (*start)priority = strtoul(start, &start, 10);if (*start == '>')start++;}/* Log (only non-empty lines) */if (*start)syslog(priority, "%s", start);if (!newline)break;start = newline;}}klogd_close();syslog(LOG_NOTICE, "klogd: exiting");remove_pidfile(CONFIG_PID_FILE_PATH "/klogd.pid");if (bb_got_signal)kill_myself_with_sig(bb_got_signal);return EXIT_FAILURE;
}

从代码来看klogd 通过函数klogctl() 将内核的log 从ring buffer 中取出,然后再通过syslog 接口,在syslogd中通过/dev/log 存放。

这里核心的函数是klogctl():

#include extern int klogctl (int __type, char *__bufp, int __len);

这里用到 klogctl 相关的函数有:

static void klogd_open(void)
{/* "Open the log. Currently a NOP" */klogctl(1, NULL, 0);
}static void klogd_setloglevel(int lvl)
{/* "printk() prints a message on the console only if it has a loglevel* less than console_loglevel". Here we set console_loglevel = lvl. */klogctl(8, NULL, lvl);
}static int klogd_read(char *bufp, int len)
{return klogctl(2, bufp, len);
}
# define READ_ERROR "klogctl(2) error"static void klogd_close(void)
{/* FYI: cmd 7 is equivalent to setting console_loglevel to 7* via klogctl(8, NULL, 7). */klogctl(7, NULL, 0); /* "7 -- Enable printk's to console" */klogctl(0, NULL, 0); /* "0 -- Close the log. Currently a NOP" */
}

根据不同的type 实现不同的功能:

opt = getopt32(argv, "c:n", &opt_c);
-c       有选项参数,表示log 等级1-8
-n       无选项参数,表示前台运行

参考:http://www.pianshen.com/article/3617573114/


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部