1 /* klogd.c - Klogd, The kernel log Dameon.
3 * Copyright 2013 Sandeep Sharma <sandeep.jack2756@gmail.com>
4 * Copyright 2013 Kyungwan Han <asura321@gmail.com>
8 USE_KLOGD(NEWTOY(klogd, "c#<1>8n", TOYFLAG_SBIN))
14 usage: klogd [-n] [-c N]
16 -c N Print to console messages more urgent than prio N (1-8)"
19 config KLOGD_SOURCE_RING_BUFFER
20 bool "enable kernel ring buffer as log source."
35 static void set_log_level(int level)
37 if (CFG_KLOGD_SOURCE_RING_BUFFER)
38 klogctl(8, NULL, level);
40 FILE *fptr = xfopen("/proc/sys/kernel/printk", "w");
41 fprintf(fptr, "%u\n", level);
47 static void handle_signal(int sig)
49 if (CFG_KLOGD_SOURCE_RING_BUFFER) {
56 syslog(LOG_NOTICE,"KLOGD: Daemon exiting......");
61 * Read kernel ring buffer in local buff and keep track of
62 * "used" amount to track next read to start.
66 int prio, size, used = 0;
67 char *start, *line_start, msg_buffer[16348]; //LOG_LINE_LENGTH - Ring buffer size
69 sigatexit(handle_signal);
70 if (toys.optflags & FLAG_c) set_log_level(TT.level); //set log level
71 if (!(toys.optflags & FLAG_n)) daemon(0, 0); //Make it daemon
73 if (CFG_KLOGD_SOURCE_RING_BUFFER) {
74 syslog(LOG_NOTICE, "KLOGD: started with Kernel ring buffer as log source\n");
77 TT.fd = xopenro("/proc/kmsg"); //_PATH_KLOG in paths.h
78 syslog(LOG_NOTICE, "KLOGD: started with /proc/kmsg as log source\n");
80 openlog("Kernel", 0, LOG_KERN); //open connection to system logger..
83 start = msg_buffer + used; //start updated for re-read.
84 if (CFG_KLOGD_SOURCE_RING_BUFFER) {
85 size = klogctl(2, start, sizeof(msg_buffer) - used - 1);
87 size = xread(TT.fd, start, sizeof(msg_buffer) - used - 1);
89 if (size < 0) perror_exit("error reading file:");
90 start[size] = '\0'; //Ensure last line to be NUL terminated.
91 if (used) start = msg_buffer;
93 if ((line_start = strsep(&start, "\n")) != NULL && start != NULL) used = 0;
94 else { //Incomplete line, copy it to start of buff.
95 used = strlen(line_start);
96 strcpy(msg_buffer, line_start);
97 if (used < (sizeof(msg_buffer) - 1)) break;
98 used = 0; //we have buffer full, log it as it is.
100 prio = LOG_INFO; //we dont know priority, mark it INFO
101 if (*line_start == '<') { //we have new line to syslog
103 if (line_start) prio = (int)strtoul(line_start, &line_start, 10);
104 if (*line_start == '>') line_start++;
106 if (*line_start) syslog(prio, "%s", line_start);