toybox/toys/pending/klogd.c
<<
>>
Prefs
   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
   8USE_KLOGD(NEWTOY(klogd, "c#<1>8n", TOYFLAG_SBIN))
   9
  10config KLOGD
  11    bool "klogd"
  12    default n
  13    help
  14    usage: klogd [-n] [-c N]
  15
  16    -c  N   Print to console messages more urgent than prio N (1-8)"
  17    -n    Run in foreground
  18
  19config KLOGD_SOURCE_RING_BUFFER
  20    bool "enable kernel ring buffer as log source."
  21    default n
  22    depends on KLOGD
  23*/
  24
  25#define FOR_klogd
  26#include "toys.h"
  27#include <signal.h>
  28#include <sys/klog.h>
  29GLOBALS(
  30  long level;
  31
  32  int fd;
  33)
  34
  35static void set_log_level(int level)
  36{   
  37  if (CFG_KLOGD_SOURCE_RING_BUFFER)
  38    klogctl(8, NULL, level);
  39  else {
  40    FILE *fptr = xfopen("/proc/sys/kernel/printk", "w");
  41    fprintf(fptr, "%u\n", level);
  42    fclose(fptr);
  43    fptr = NULL;
  44  }
  45}
  46
  47static void handle_signal(int sig)
  48{
  49  if (CFG_KLOGD_SOURCE_RING_BUFFER) {
  50    klogctl(7, NULL, 0); 
  51    klogctl(0, NULL, 0);
  52  } else {
  53    set_log_level(7);
  54    xclose(TT.fd);
  55  }
  56  syslog(LOG_NOTICE,"KLOGD: Daemon exiting......");
  57  exit(1);
  58}
  59
  60/*
  61 * Read kernel ring buffer in local buff and keep track of
  62 * "used" amount to track next read to start.
  63 */
  64void klogd_main(void)
  65{
  66  int prio, size, used = 0;
  67  char *start, *line_start, msg_buffer[16348]; //LOG_LINE_LENGTH - Ring buffer size
  68
  69  sigatexit(handle_signal);
  70  if (toys.optflags & FLAG_c) set_log_level(TT.level);    //set log level
  71  if (!(toys.optflags & FLAG_n)) daemon(0, 0);            //Make it daemon
  72
  73  if (CFG_KLOGD_SOURCE_RING_BUFFER) {
  74    syslog(LOG_NOTICE, "KLOGD: started with Kernel ring buffer as log source\n");
  75    klogctl(1, NULL, 0);
  76  } else {
  77    TT.fd = xopenro("/proc/kmsg"); //_PATH_KLOG in paths.h
  78    syslog(LOG_NOTICE, "KLOGD: started with /proc/kmsg as log source\n");
  79  }
  80  openlog("Kernel", 0, LOG_KERN);    //open connection to system logger..
  81
  82  while(1) {
  83    start = msg_buffer + used; //start updated for re-read.
  84    if (CFG_KLOGD_SOURCE_RING_BUFFER) {
  85      size = klogctl(2, start, sizeof(msg_buffer) - used - 1);
  86    } else {
  87      size = xread(TT.fd, start, sizeof(msg_buffer) - used - 1);
  88    }
  89    if (size < 0) perror_exit("error reading file:");
  90    start[size] = '\0';  //Ensure last line to be NUL terminated.
  91    if (used) start = msg_buffer;
  92    while(start) {
  93      if ((line_start = strsep(&start, "\n")) != NULL && start != NULL) used = 0;
  94      else {                            //Incomplete line, copy it to start of buff.
  95        used = strlen(line_start);
  96        strcpy(msg_buffer, line_start);
  97        if (used < (sizeof(msg_buffer) - 1)) break;
  98        used = 0; //we have buffer full, log it as it is.
  99      }
 100      prio = LOG_INFO;  //we dont know priority, mark it INFO
 101      if (*line_start == '<') {  //we have new line to syslog
 102        line_start++;
 103        if (line_start) prio = (int)strtoul(line_start, &line_start, 10);
 104        if (*line_start == '>') line_start++;
 105      }
 106      if (*line_start) syslog(prio, "%s", line_start);
 107    }
 108  }
 109}
 110