123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- /* 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);
- }
- }
- }
|