• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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