1 /* klogd.c - Klogd, The kernel log Dameon.
2 *
3 * Copyright 2013 Sandeep Sharma <sandeep.jack2756@gmail.com>
4 * Copyright 2013 Kyungwan Han <asura321@gmail.com>
5 *
6 * No standard
7
8 USE_KLOGD(NEWTOY(klogd, "c#<1>8ns", TOYFLAG_SBIN))
9
10 config KLOGD
11 bool "klogd"
12 default n
13 help
14 usage: klogd [-n] [-c PRIORITY]
15
16 Forward messages from the kernel ring buffer (read by dmesg) to syslogd.
17
18 -c Print to console messages more urgent than PRIORITY (1-8)
19 -n Run in foreground
20 -s Use syscall instead of /proc
21 */
22
23 #define FOR_klogd
24 #include "toys.h"
25 #include <sys/klog.h>
26
GLOBALS(long level;int fd;)27 GLOBALS(
28 long level;
29
30 int fd;
31 )
32
33 static void set_log_level(int level)
34 {
35 if (FLAG(s)) klogctl(8, 0, level);
36 else {
37 FILE *fptr = xfopen("/proc/sys/kernel/printk", "w");
38
39 fprintf(fptr, "%u\n", level);
40 fclose(fptr);
41 }
42 }
43
handle_signal(int sig)44 static void handle_signal(int sig)
45 {
46 // TODO: level 7 hardwired? How to read old value...?
47 if (FLAG(s)) klogctl(8, 0, 7);
48 else {
49 if (FLAG(c)) set_log_level(7);
50 xclose(TT.fd);
51 }
52 syslog(LOG_NOTICE, "KLOGD: Daemon exiting......");
53
54 toys.exitval = 1;
55 xexit();
56 }
57
58 // Read kernel ring buffer in local buff and keep track of
59 // "used" amount to track next read to start.
klogd_main(void)60 void klogd_main(void)
61 {
62 int prio, size, used = 0;
63 char *start, *line_start;
64
65 if (!FLAG(n)) xvdaemon();
66 sigatexit(handle_signal);
67 if (FLAG(c)) set_log_level(TT.level); //set log level
68
69 if (!FLAG(s)) TT.fd = xopenro("/proc/kmsg"); //_PATH_KLOG in paths.h
70 syslog(LOG_NOTICE, "KLOGD: started with %s as log source\n",
71 FLAG(s) ? "Kernel ring buffer" : "/proc/kmsg");
72 openlog("Kernel", 0, LOG_KERN); //open connection to system logger..
73
74 for (;;) {
75 start = toybuf + used; //start updated for re-read.
76 size = sizeof(toybuf)-used-1;
77 if (FLAG(s)) size = klogctl(2, start, size);
78 else size = xread(TT.fd, start, size);
79 if (size < 0) perror_exit("error reading file:");
80 start[size] = 0;
81 if (used) start = toybuf;
82 while (start) {
83 if ((line_start = strsep(&start, "\n")) && start) used = 0;
84 else { //Incomplete line, copy it to start of buf
85 used = stpcpy(toybuf, line_start)-toybuf;
86 if (used < (sizeof(toybuf) - 1)) break;
87 used = 0; //we have buffer full, log it as it is.
88 }
89 prio = LOG_INFO; //we dont know priority, mark it INFO
90 if (*line_start == '<') { //we have new line to syslog
91 line_start++;
92 if (line_start) prio = strtoul(line_start, &line_start, 10);
93 if (*line_start == '>') line_start++;
94 }
95 if (*line_start) syslog(prio, "%s", line_start);
96 }
97 }
98 }
99