<div>Hi Rob,</div>
<div> </div>
<div>The attached KLOGD patch is an improved version of the one you have in hg.</div>
<div>This also has a fix for boundary condition crash.</div>
<div> </div>
<div>regards,</div>
<div>Ashwini</div>
<div><br><br> </div>
<div class="gmail_quote">On Mon, Jul 15, 2013 at 11:05 PM, Isaac <span dir="ltr"><<a href="mailto:idunham@lavabit.com" target="_blank">idunham@lavabit.com</a>></span> wrote:<br>
<blockquote style="BORDER-LEFT:#ccc 1px solid;MARGIN:0px 0px 0px 0.8ex;PADDING-LEFT:1ex" class="gmail_quote">
<div class="HOEnZb">
<div class="h5">On Mon, Jul 15, 2013 at 03:43:27PM +0530, Ashwini Sharma wrote:<br>>  Hi Rob,<br>><br>>     I have implemented klogd, Klogd has both the options as its source,<br>> 1. Reading from kernel ring buffer, thru KLOGCTL interface<br>
> 2. Reading from "/proc/kmsg". This is Configurable option.<br>><br>><br>> Attached is the patch for klogd.<br>><br>> Let me know for any comments you have.<br>><br>><br>> Thanks,<br>
> Ashwini<br><br></div></div>From what I've seen, you might want to change a couple things.<br><br>--- /dev/null   2013-07-15 12:17:51.251463096 +0900<br>+++ toys/other/klogd.c  2013-07-15 19:06:<a href="tel:19.188909098" value="+19188909098">19.188909098</a> +0900<br>
@@ -0,0 +1,146 @@<br>+/* klogd.c - Klogd, The kernel log Dameon.<br>+ *<br>+ * Copyright 2013 Sandeep Sharma <<a href="mailto:sandeep.jack2756@gmail.com">sandeep.jack2756@gmail.com</a>><br>+ *<br>+ * No standard<br>
+<br>+USE_KLOGD(NEWTOY(klogd, "c#<1>8n", TOYFLAG_SBIN))<br>+<br>+config KLOGD<br>+    bool "klogd"<br>+    default y<br>+    help<br>+    usage: klogd [-n] [-c N]<br>+<br>+    -c  N   Print to console messages more urgent than prio N (1-8)"<br>
+    -n    Run in foreground.<br>+<br>+config KLOGD_SOURCE_RING_BUFFER<br>+    bool "enable kernel ring buffer as log source."<br>+    default n<br>+    depends on KLOGD<br>+*/<br>+<br>+#define FOR_klogd<br>+#include "toys.h"<br>
+#include <signal.h><br>+GLOBALS(<br>+  long level;<br>+  int fd;<br>+)<br>+<br>+#if CFG_KLOGD_SOURCE_RING_BUFFER<br>Most of these functions look like they should be inlined-they're only called<br>once.<br>The approach used throughout toybox is roughly equivalent to<br>
  if (...RING_BUFFER) {<br>    //use klogctl<br>  } else {<br>    //use /proc/kmesg<br>  }<br><br>+#include <sys/klog.h><br>+static void open_klogd(void)<br>+{<br>+  syslog(LOG_NOTICE, "KLOGD: started with Kernel ring buffer as log source\n");<br>
+  klogctl(1, NULL, 0);<br>+}<br>+<br>+static int read_klogd(char *bufptr, int len)<br>+{<br>+  return klogctl(2, bufptr, len);<br>+}<br>+<br>+static void set_log_level(int level)<br>+{<br>+  klogctl(8, NULL, level);<br>+}<br>
+<br>+static void close_klogd(void)<br>+{<br>+  klogctl(7, NULL, 0);<br>+  klogctl(0, NULL, 0);<br>+}<br>+#else<br>+static void open_klogd(void)<br>+{<br>+  TT.fd = xopen("/proc/kmsg", O_RDONLY); //_PATH_KLOG in paths.h<br>
+  syslog(LOG_NOTICE, "KLOGD: started with /proc/kmsg as log source\n");<br>+}<br>+<br>+static int read_klogd(char *bufptr, int len)<br>+{<br>+  return xread(TT.fd, bufptr, len);<br>+}<br>+<br>+static void set_log_level(int level)<br>
+{<br>+    FILE *fptr = xfopen("/proc/sys/kernel/printk", "w");<br>+    fprintf(fptr, "%u\n", level);<br>+    fclose(fptr);<br>+    fptr = NULL;<br>+}<br>+<br>+static void close_klogd(void)<br>
+{<br>+  set_log_level(7);<br>+  xclose(TT.fd);<br>+}<br>+#endif<br>+<br>+static void handle_signal(int sig)<br>+{<br>+  close_klogd();<br>+  syslog(LOG_NOTICE,"KLOGD: Daemon exiting......");<br>+  exit(1);<br>+}<br>
+<br>+static int daemonize(void)<br>+{<br>+  pid_t pid;<br>+  int fd = open("/dev/null", O_RDWR);<br>+  if (fd < 0) fd = open("/", O_RDONLY, 0666);<br>+  if((pid = fork()) < 0) {<br>+    perror_msg("DAEMON: fail to fork");<br>
+    return -1;<br>Trivial, but I think perror_exit is for this purpose.<br><br>+  }<br>+  if (pid) exit(EXIT_SUCCESS);<br>+<br>+  setsid();<br>+  dup2(fd, 0);<br>+  dup2(fd, 1);<br>+  dup2(fd, 2);<br>+  if (fd > 2) close(fd);<br>
+  return 0;<br>+}<br><br>AFAIK, everything except handle_signal should be inlined.<br>And a less generic name should be given to that.<br>+<br>+/*<br>+ * Read kernel ring buffer in local buff and keep track of<br>+ * "used" amount to track next read to start.<br>
+ */<br>+void klogd_main(void)<br>+{<br>+  int prio, size, used = 0;<br>+  char *start, *line_start, msg_buffer[16348]; //LOG_LINE_LENGTH - Ring buffer size<br>+<br>+  sigatexit(handle_signal);<br>+  if (toys.optflags & FLAG_c) set_log_level(TT.level);    //set log level<br>
+  if (!(toys.optflags & FLAG_n)) daemonize();        //Make it daemon<br>+  open_klogd();<br>+  openlog("Kernel", 0, LOG_KERN);    //open connection to system logger..<br>+<br>+  while(1) {<br>+    start = msg_buffer + used; //start updated for re-read.<br>
+    size = read_klogd(start, sizeof(msg_buffer) - used - 1);<br>+    if (size < 0) perror_exit("error reading file:");<br>+    start[size] = '\0';  //Ensure last line to be NUL terminated.<br>+    if (used) start = msg_buffer;<br>
+    while(1) {<br>+      if ((line_start = strsep(&start, "\n")) != NULL && start != NULL) used = 0;<br>+      else {                            //Incomplete line, copy it to start of buff.<br>+        used = strlen(line_start);<br>
+        strcpy(msg_buffer, line_start);<br>+        if (used < (sizeof(msg_buffer) - 1)) break;<br>+        used = 0; //we have buffer full, log it as it is.<br>+      }<br>+      prio = LOG_INFO;  //we dont know priority, mark it INFO<br>
+      if (*line_start == '<') {  //we have new line to syslog<br>+        line_start++;<br>+        if (line_start) prio = (int)strtoul(line_start, &line_start, 10);<br>+        if (*line_start == '>') line_start++;<br>
+      }<br>+      if (*line_start) syslog(prio, "%s", line_start);<br>+    }<br>+  }<br>+}<br><br><br></blockquote></div><br>