Mercurial > hg > toybox
comparison toys/pending/klogd.c @ 950:a4a6bcf32657
klogd, submitted by Ashwini Sharma.
author | Rob Landley <rob@landley.net> |
---|---|
date | Mon, 15 Jul 2013 13:12:08 -0500 |
parents | |
children | 144d5ba7d410 |
comparison
equal
deleted
inserted
replaced
949:59d4d453296b | 950:a4a6bcf32657 |
---|---|
1 /* klogd.c - Klogd, The kernel log Dameon. | |
2 * | |
3 * Copyright 2012 Sandeep Sharma <sandeep.jack2756@gmail.com> | |
4 * | |
5 * No standard | |
6 | |
7 USE_KLOGD(NEWTOY(klogd, "c#<1>8n", TOYFLAG_SBIN)) | |
8 | |
9 config KLOGD | |
10 bool "klogd" | |
11 default y | |
12 help | |
13 usage: klogd [-n] [-c N] | |
14 | |
15 -c N Print to console messages more urgent than prio N (1-8)" | |
16 -n Run in foreground. | |
17 | |
18 config KLOGD_SOURCE_RING_BUFFER | |
19 bool "enable kernel ring buffer as log source." | |
20 default n | |
21 depends on KLOGD | |
22 */ | |
23 | |
24 #define FOR_klogd | |
25 #include "toys.h" | |
26 #include <signal.h> | |
27 GLOBALS( | |
28 long level; | |
29 int fd; | |
30 ) | |
31 | |
32 #if CFG_KLOGD_SOURCE_RING_BUFFER | |
33 #include <sys/klog.h> | |
34 /* | |
35 * Open klogd with ring buffer as log source | |
36 */ | |
37 static void open_klogd(void) | |
38 { | |
39 syslog(LOG_NOTICE, "KLOGD: started with Kernel ring buffer as log source\n"); | |
40 klogctl(1, NULL, 0); | |
41 } | |
42 /* | |
43 * Read kernel ring buffer | |
44 */ | |
45 static int read_klogd(char *bufptr, int len) | |
46 { | |
47 return klogctl(2, bufptr, len); | |
48 } | |
49 /* | |
50 * Set log level to LEVEL | |
51 */ | |
52 static void set_log_level(int level) | |
53 { | |
54 klogctl(8, NULL, level); | |
55 } | |
56 /* | |
57 * Close klog | |
58 */ | |
59 static void close_klogd(void) | |
60 { | |
61 klogctl(7, NULL, 0); | |
62 klogctl(0, NULL, 0); | |
63 } | |
64 #else | |
65 #include<paths.h> | |
66 #ifndef _PATH_KLOG | |
67 #error "_PATH_KLOG is not known" | |
68 #endif | |
69 /* | |
70 * Open klog with /proc/kmsg as log source | |
71 */ | |
72 static void open_klogd(void) | |
73 { | |
74 TT.fd = xopen(_PATH_KLOG, O_RDONLY); | |
75 syslog(LOG_NOTICE, "KLOGD: started with /proc/kmsg as log source\n"); | |
76 } | |
77 /* | |
78 * Read log to local buffer | |
79 */ | |
80 static int read_klogd(char *bufptr, int len) | |
81 { | |
82 return xread(TT.fd, bufptr, len); | |
83 } | |
84 /* | |
85 * Set log level to LEVEL by writing to PATH_PRINTK | |
86 */ | |
87 static void set_log_level(int level) | |
88 { | |
89 FILE *fptr = xfopen("/proc/sys/kernel/printk", "w"); | |
90 fprintf(fptr, "%u\n", level); | |
91 fclose(fptr); | |
92 fptr = NULL; | |
93 } | |
94 /* | |
95 * set log level while exiting | |
96 */ | |
97 static void close_klogd(void) | |
98 { | |
99 set_log_level(7); | |
100 xclose(TT.fd); | |
101 } | |
102 #endif | |
103 /* | |
104 * Handle signals | |
105 */ | |
106 static void handle_signal(int sig) | |
107 { | |
108 close_klogd(); | |
109 syslog(LOG_NOTICE,"KLOGD: Daemon exiting......"); | |
110 exit(1); | |
111 } | |
112 | |
113 static int go_daemon(void) | |
114 { | |
115 int fd; | |
116 | |
117 fd = open("/dev/null", O_RDWR); | |
118 if (fd < 0) fd = open("/", O_RDONLY, 0666); | |
119 pid_t pid = fork(); | |
120 | |
121 if (pid < 0) { | |
122 error_msg("DAEMON: fail to fork"); | |
123 return -1; | |
124 } | |
125 if (pid) exit(EXIT_SUCCESS); | |
126 | |
127 setsid(); | |
128 dup2(fd, 0); | |
129 dup2(fd, 1); | |
130 dup2(fd, 2); | |
131 if (fd > 2) close(fd); | |
132 return 0; | |
133 } | |
134 | |
135 /* | |
136 * Read kernel ring buffer in local buff and keep track of | |
137 * "used" amount to track next read to start. | |
138 */ | |
139 void klogd_main(void) | |
140 { | |
141 char msg_buffer[16348]; //LOG_LINE_LENGTH - Ring buffer size | |
142 int prio, size; | |
143 int used = 0; | |
144 char *start, *line_start; | |
145 | |
146 sigatexit(handle_signal); | |
147 if(toys.optflags & FLAG_c) set_log_level(TT.level); //set log level | |
148 if(!(toys.optflags & FLAG_n)) go_daemon(); //Make it daemon | |
149 open_klogd(); | |
150 openlog("Kernel", 0, LOG_KERN); //open connection to system logger.. | |
151 | |
152 while(1) { | |
153 start = msg_buffer + used; //start updated for re-read. | |
154 size = read_klogd(start, sizeof(msg_buffer)-1-used); | |
155 if (size < 0) perror_exit("error reading file:"); | |
156 start[size] = '\0'; //Ensure last line to be NUL terminated. | |
157 if(used) start = msg_buffer; | |
158 while(1) { | |
159 if((line_start = strsep(&start, "\n")) != NULL && start != NULL) used = 0; | |
160 else { //Incomplete line, copy it to start of buff. | |
161 used = strlen(line_start); | |
162 strcpy(msg_buffer, line_start); | |
163 if(used < (sizeof(msg_buffer) - 1)) break; | |
164 used = 0; //we have buffer full, log it as it is. | |
165 } | |
166 prio = LOG_INFO; //we dont know priority, mark it INFO | |
167 if(*line_start == '<') { //we have new line to syslog | |
168 line_start++; | |
169 if(line_start) prio = (int)strtoul(line_start, &line_start, 10); | |
170 if(*line_start == '>') line_start++; | |
171 } | |
172 if(*line_start) syslog(prio, "%s", line_start); | |
173 } | |
174 } | |
175 } |