You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
110 lines
3.0 KiB
110 lines
3.0 KiB
/* klogd.c - Klogd, The kernel log Dameon.
|
|
*
|
|
* Copyright 2013 Sandeep Sharma <sandeep.jack2756@gmail.com>
|
|
* Copyright 2013 Kyungwan Han <asura321@gmail.com>
|
|
*
|
|
* No standard
|
|
|
|
USE_KLOGD(NEWTOY(klogd, "c#<1>8n", TOYFLAG_SBIN))
|
|
|
|
config KLOGD
|
|
bool "klogd"
|
|
default n
|
|
help
|
|
usage: klogd [-n] [-c N]
|
|
|
|
-c N Print to console messages more urgent than prio N (1-8)"
|
|
-n Run in foreground
|
|
|
|
config KLOGD_SOURCE_RING_BUFFER
|
|
bool "enable kernel ring buffer as log source."
|
|
default n
|
|
depends on KLOGD
|
|
*/
|
|
|
|
#define FOR_klogd
|
|
#include "toys.h"
|
|
#include <signal.h>
|
|
#include <sys/klog.h>
|
|
GLOBALS(
|
|
long level;
|
|
|
|
int fd;
|
|
)
|
|
|
|
static void set_log_level(int level)
|
|
{
|
|
if (CFG_KLOGD_SOURCE_RING_BUFFER)
|
|
klogctl(8, NULL, level);
|
|
else {
|
|
FILE *fptr = xfopen("/proc/sys/kernel/printk", "w");
|
|
fprintf(fptr, "%u\n", level);
|
|
fclose(fptr);
|
|
fptr = NULL;
|
|
}
|
|
}
|
|
|
|
static void handle_signal(int sig)
|
|
{
|
|
if (CFG_KLOGD_SOURCE_RING_BUFFER) {
|
|
klogctl(7, NULL, 0);
|
|
klogctl(0, NULL, 0);
|
|
} else {
|
|
set_log_level(7);
|
|
xclose(TT.fd);
|
|
}
|
|
syslog(LOG_NOTICE,"KLOGD: Daemon exiting......");
|
|
exit(1);
|
|
}
|
|
|
|
/*
|
|
* Read kernel ring buffer in local buff and keep track of
|
|
* "used" amount to track next read to start.
|
|
*/
|
|
void klogd_main(void)
|
|
{
|
|
int prio, size, used = 0;
|
|
char *start, *line_start, msg_buffer[16348]; //LOG_LINE_LENGTH - Ring buffer size
|
|
|
|
sigatexit(handle_signal);
|
|
if (toys.optflags & FLAG_c) set_log_level(TT.level); //set log level
|
|
if (!(toys.optflags & FLAG_n)) daemon(0, 0); //Make it daemon
|
|
|
|
if (CFG_KLOGD_SOURCE_RING_BUFFER) {
|
|
syslog(LOG_NOTICE, "KLOGD: started with Kernel ring buffer as log source\n");
|
|
klogctl(1, NULL, 0);
|
|
} else {
|
|
TT.fd = xopenro("/proc/kmsg"); //_PATH_KLOG in paths.h
|
|
syslog(LOG_NOTICE, "KLOGD: started with /proc/kmsg as log source\n");
|
|
}
|
|
openlog("Kernel", 0, LOG_KERN); //open connection to system logger..
|
|
|
|
while(1) {
|
|
start = msg_buffer + used; //start updated for re-read.
|
|
if (CFG_KLOGD_SOURCE_RING_BUFFER) {
|
|
size = klogctl(2, start, sizeof(msg_buffer) - used - 1);
|
|
} else {
|
|
size = xread(TT.fd, start, sizeof(msg_buffer) - used - 1);
|
|
}
|
|
if (size < 0) perror_exit("error reading file:");
|
|
start[size] = '\0'; //Ensure last line to be NUL terminated.
|
|
if (used) start = msg_buffer;
|
|
while(start) {
|
|
if ((line_start = strsep(&start, "\n")) != NULL && start != NULL) used = 0;
|
|
else { //Incomplete line, copy it to start of buff.
|
|
used = strlen(line_start);
|
|
strcpy(msg_buffer, line_start);
|
|
if (used < (sizeof(msg_buffer) - 1)) break;
|
|
used = 0; //we have buffer full, log it as it is.
|
|
}
|
|
prio = LOG_INFO; //we dont know priority, mark it INFO
|
|
if (*line_start == '<') { //we have new line to syslog
|
|
line_start++;
|
|
if (line_start) prio = (int)strtoul(line_start, &line_start, 10);
|
|
if (*line_start == '>') line_start++;
|
|
}
|
|
if (*line_start) syslog(prio, "%s", line_start);
|
|
}
|
|
}
|
|
}
|