Use klogctl instead of /proc/kmsg master
authorChristophe Varoqui <christophe.varoqui@opensvc.com>
Thu, 13 Oct 2016 14:25:15 +0000 (16:25 +0200)
committerChristophe Varoqui <christophe.varoqui@opensvc.com>
Thu, 13 Oct 2016 14:25:15 +0000 (16:25 +0200)
Reading from /proc/kmsg races against the syslog daemon, making
unmid not reliable, and causing missing entries in the sys logs.

unmid.c
unmid.conf

diff --git a/unmid.c b/unmid.c
index 635321a..e4c8c0d 100644 (file)
--- a/unmid.c
+++ b/unmid.c
@@ -13,6 +13,7 @@
 #include <sched.h>
 #include <syslog.h>
 #include <regex.h>
+#include <sys/klog.h>
 
 #ifdef USE_SYSTEMD
 #include <systemd/sd-daemon.h>
 #define DAEMON_SHUTDOWN 2
 #define DAEMON_RECONFIGURE 3
 
+#define SYSLOG_ACTION_READ           2
+#define SYSLOG_ACTION_READ_ALL       3
+#define SYSLOG_ACTION_READ_CLEAR     4
+#define SYSLOG_ACTION_CLEAR          5
+#define SYSLOG_ACTION_CONSOLE_LEVEL  8
+#define SYSLOG_ACTION_SIZE_BUFFER   10
 
 /* Local variables */
 static volatile sig_atomic_t exit_sig;
@@ -286,10 +293,9 @@ parse_kmsg(char * kmsg)
 }
 
 static int
-work (void)
+read_kmsg (void)
 {
        char buf[BUFSIZ] = "\0";
-
        if (NULL == fgets(buf, BUFSIZ, kmesg_fp)) {
                if (exit_sig + reconfig_sig > 0) {
                        // step out to let the signal handlers do their job
@@ -298,10 +304,60 @@ work (void)
                condlog(LOG_ERR, "error reading " KMSG);
                return 1;
        }
+       condlog(LOG_DEBUG, "read kmsg");
+       condlog(LOG_DEBUG, "%s", buf);
        parse_kmsg(buf);
+       return 0;
+}
+
+static int
+get_syslog_buffer_size(void)
+{
+       int n = klogctl(SYSLOG_ACTION_SIZE_BUFFER, NULL, 0);
+       return n > 0 ? n : 0;
+}
+
+static int
+read_syslog (void)
+{
+       char *buf = NULL;
+       int len = get_syslog_buffer_size();
+       int rc = -1;
+
+       buf = malloc(len * sizeof(char));
+       if (!buf) {
+               condlog(LOG_ERR, "malloc error");
+               return -1;
+       }
+       rc = klogctl(SYSLOG_ACTION_READ_CLEAR, buf, len);
+       if (rc == 0) {
+               free(buf);
+               return 0;
+       }
+       else if (rc < 0) {
+               condlog(LOG_ERR, "error reading klog");
+               free(buf);
+               return rc;
+       }
+       condlog(LOG_DEBUG, "read klog (%d)", rc);
+       condlog(LOG_DEBUG, "%s", buf);
+       parse_kmsg(buf);
+       free(buf);
+       return rc;
+}
+
+static int
+work (void)
+{
+       int rc = 0;
+
+       rc = read_syslog();
+       if (rc == 0) {
+               usleep(50000);
+       }
        fflush(stdout);
 
-       return 0;
+       return rc;
 }
 
 static int
index b06ec60..b313823 100644 (file)
@@ -3,3 +3,5 @@
 #
 ;28 c
 ;38 c
+;29 c
+;39 c