Browse Source

Add ./tarball_archive/symon-2.83.tar.gz

Wictor Lund 3 years ago
parent
commit
5c0c6e87b4

+ 13 - 2
symon/CHANGELOG

@@ -1,3 +1,14 @@
+01/05/2011 - 2.83
+
+   - Added flukso probe
+
+   - platform/OpenBSD/sm_io.c updated to support uids (Stuart Henderson)
+
+   - platform/Linux/sm_df.c checks if /etc/mtab could be openend (Lars Kotthoff)
+
+   - platform/Linux: Support diskname by id, label, path or uuid for smart, io
+     and df probes.
+
 15/06/2010 - 2.82
 
    - platform/OpenBSD/sm_sensor.c define MAXSENSORSDEVICES (Stuart Henderson)
@@ -14,8 +25,8 @@
    - Smart probe assumed that its ioctl cmd structure was not overwritten and
      did not check the return code correctly on NetBSD. (Tito Dal Canton)
 
-   - sm_smart.c: support for kernels 2.6.9 and friends that miss the required
-     hdio structure.
+   - platform/Linux/sm_smart.c: support for kernels 2.6.9 and friends that miss
+     the required hdio structure.
 
    - c_smrrds.sh: Allow more than 10 cpus.
 

+ 1 - 5
symon/Makefile.inc

@@ -1,12 +1,8 @@
-V=2.82
+V=2.83
 
 AR?=	ar
 CC?=	cc
-.ifdef DEBUG
-CFLAGS=-g -Wall
-.else
 CFLAGS+=-Wall
-.endif
 INSTALL?=install
 LORDER?=lorder
 TSORT?=tsort

+ 2 - 0
symon/lib/data.c

@@ -112,6 +112,7 @@ struct {
     { MT_CPUIOW, "cccccc" },
     { MT_SMART, "bbbbbbbbbbbb" },
     { MT_LOAD, "ccc" },
+    { MT_FLUKSO, "D" },
     { MT_TEST, "LLLLDDDDllllssssccccbbbb" },
     { MT_EOT, "" }
 };
@@ -137,6 +138,7 @@ struct {
     { MT_CPUIOW, LXT_CPUIOW },
     { MT_SMART, LXT_SMART },
     { MT_LOAD, LXT_LOAD },
+    { MT_FLUKSO, LXT_FLUKSO },
     { MT_EOT, LXT_BADTOKEN }
 };
 /* parallel crc32 table */

+ 6 - 2
symon/lib/data.h

@@ -163,8 +163,9 @@ SLIST_HEAD(muxlist, mux);
 #define MT_CPUIOW 14
 #define MT_SMART  15
 #define MT_LOAD   16
-#define MT_TEST   17
-#define MT_EOT    18
+#define MT_FLUKSO 17
+#define MT_TEST   18
+#define MT_EOT    19
 
 /*
  * Unpacking of incoming packets is done via a packedstream structure. This
@@ -350,6 +351,9 @@ struct packedstream {
             u_int16_t mload2;
             u_int16_t mload3;
         }      ps_load;
+        struct {
+            int64_t value;
+        }      ps_flukso;
     }     data;
 };
 

+ 1 - 0
symon/lib/lex.c

@@ -74,6 +74,7 @@ static struct {
     { "debug", LXT_DEBUG },
     { "df", LXT_DF },
     { "every", LXT_EVERY },
+    { "flukso", LXT_FLUKSO },
     { "from", LXT_FROM },
     { "if", LXT_IF },
     { "if1", LXT_IF1 },

+ 26 - 25
symon/lib/lex.h

@@ -53,31 +53,32 @@
 #define LXT_DF         9
 #define LXT_END       10
 #define LXT_EVERY     11
-#define LXT_FROM      12
-#define LXT_IF        13
-#define LXT_IF1       14
-#define LXT_IN        15
-#define LXT_IO        16
-#define LXT_IO1       17
-#define LXT_LOAD      18
-#define LXT_MBUF      19
-#define LXT_MEM       20
-#define LXT_MEM1      21
-#define LXT_MONITOR   22
-#define LXT_MUX       23
-#define LXT_OPEN      24
-#define LXT_PF        25
-#define LXT_PFQ       26
-#define LXT_PORT      27
-#define LXT_PROC      28
-#define LXT_SECOND    29
-#define LXT_SECONDS   30
-#define LXT_SENSOR    31
-#define LXT_SMART     32
-#define LXT_SOURCE    33
-#define LXT_STREAM    34
-#define LXT_TO        35
-#define LXT_WRITE     36
+#define LXT_FLUKSO    12
+#define LXT_FROM      13
+#define LXT_IF        14
+#define LXT_IF1       15
+#define LXT_IN        16
+#define LXT_IO        17
+#define LXT_IO1       18
+#define LXT_LOAD      19
+#define LXT_MBUF      20
+#define LXT_MEM       21
+#define LXT_MEM1      22
+#define LXT_MONITOR   23
+#define LXT_MUX       24
+#define LXT_OPEN      25
+#define LXT_PF        26
+#define LXT_PFQ       27
+#define LXT_PORT      28
+#define LXT_PROC      29
+#define LXT_SECOND    30
+#define LXT_SECONDS   31
+#define LXT_SENSOR    32
+#define LXT_SMART     33
+#define LXT_SOURCE    34
+#define LXT_STREAM    35
+#define LXT_TO        36
+#define LXT_WRITE     37
 
 struct lex {
     char *buffer;               /* current line(s) */

+ 2 - 0
symon/platform/Linux/Makefile.inc

@@ -8,3 +8,5 @@ BINDIR?=bin
 INSTALLUSER?=root
 INSTALLGROUPFILE?=bin
 INSTALLGROUPDIR?=bin
+
+PLATFORM_SRC=diskbyname.c

+ 120 - 0
symon/platform/Linux/diskbyname.c

@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2011 Willem Dijkstra
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    - Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    - Redistributions in binary form must reproduce the above
+ *      copyright notice, this list of conditions and the following
+ *      disclaimer in the documentation and/or other materials provided
+ *      with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <strings.h>
+
+#include "error.h"
+#include "platform.h"
+
+/*
+ * checkdisk(spath, dpath, maxlen)
+ *
+ * Determine that <spath> exists, and return the device name that was referenced
+ * (/dev/sdx) when <spath> is a link in <dpath>, observing <dpath>'s <maxlen>.
+ */
+static size_t
+checkdisk(const char *spath, char *dpath, size_t maxlen)
+{
+    char diskname[MAX_PATH_LEN];
+    char *r;
+    struct stat buffer;
+    size_t result;
+
+    bzero(diskname, MAX_PATH_LEN);
+    bzero(&buffer, sizeof(struct stat));
+
+    if (lstat(spath, &buffer)) {
+        return 0;
+    }
+
+    if (S_ISLNK(buffer.st_mode)) {
+        if ((r = realpath(spath, NULL))) {
+            strlcpy(diskname, r, sizeof(diskname));
+            free(r);
+        }
+        bzero(&buffer, sizeof(struct stat));
+        if (lstat(diskname, &buffer)) {
+            fatal("diskbyname: '%.200s' = '%.200s' cannot be examined: %.200s", spath, diskname, strerror(errno));
+        }
+    } else
+        strlcpy(diskname, spath, sizeof(diskname));
+
+    if (S_ISBLK(buffer.st_mode) && !S_ISLNK(buffer.st_mode)) {
+        result = strlcpy(dpath, diskname, maxlen);
+        return result;
+    }
+
+    return 0;
+}
+
+/*
+ * diskbyname(spath, dpath, maxlen)
+ *
+ * Resolve a logical disk name <spath> to it's block device name
+ * <dpath>. <dpath> is preallocated and can hold <maxlen> characters. <spath>
+ * can refer to a disk via 1) an absolute path or 2) a diskname relative to
+ * /dev, or 3) a diskname relative to the /dev/disk/by-* directories.
+ */
+size_t
+diskbyname(const char *spath, char *dpath, size_t maxlen)
+{
+    char diskname[MAX_PATH_LEN];
+    size_t size;
+    char *l[] = {
+        "/dev/%s",
+        "/dev/disk/by-id/%s",
+        "/dev/disk/by-label/%s",
+        "/dev/disk/by-uuid/%s",
+        "/dev/disk/by-path/%s",
+        NULL
+    };
+    int i;
+
+    if (spath == NULL)
+        return 0;
+
+    if (strchr(spath, '/'))
+        return checkdisk(spath, dpath, maxlen);
+
+    for (i = 0; l[i] != NULL; i++) {
+        bzero(diskname, sizeof(diskname));
+        snprintf(diskname, sizeof(diskname), l[i], spath);
+        if ((size = checkdisk(diskname, dpath, maxlen)))
+            return size;
+    }
+
+    return 0;
+}

+ 11 - 0
symon/platform/Linux/platform.h

@@ -5,6 +5,12 @@
 #include <stdio.h>
 #include <grp.h>
 
+/* uclibc snprintf is redefined between stdio.h and string.h */
+#include <features.h>
+#ifdef __UCLIBC_MAJOR__
+#undef __USE_BSD
+#endif
+
 #include "queue.h"
 #include "sylimits.h"
 
@@ -65,6 +71,11 @@ union stream_parg {
         char path[MAX_PATH_LEN];
     } sn;
     int smart;
+    char flukso[MAX_PATH_LEN];
+    char io[MAX_PATH_LEN];
 };
 
+extern size_t
+diskbyname(const char *spath, char *dpath, size_t maxlen);
+
 #endif

+ 19 - 11
symon/platform/Linux/sm_df.c

@@ -1,4 +1,5 @@
 /*
+ * Copyright (c) 2011 Willem Dijkstra
  * Copyright (c) 2007 Martin van der Werff
  * All rights reserved.
  *
@@ -37,6 +38,7 @@
 
 
 #include <sys/types.h>
+#include <errno.h>
 #include <stdio.h>
 #include <mntent.h>
 #include <string.h>
@@ -49,25 +51,31 @@
 void
 init_df(struct stream *st)
 {
+    char drivename[MAX_PATH_LEN];
     FILE * fp = setmntent("/etc/mtab", "r");
     struct mntent *mount;
 
+    if (fp == NULL)
+        fatal("df: cannot access /etc/mtab: %.200s", strerror(errno));
+
+    if (st->arg == NULL)
+        fatal("df: need a <disk device|name> argument");
+
+    if ((diskbyname(st->arg, drivename, sizeof(drivename)) == 0))
+        fatal("df: '%.200s' is not a disk device", st->arg);
+
     while ((mount = getmntent(fp))) {
-	if (strncmp(mount->mnt_fsname, "/dev/", 5) == 0) {
-            if (strcmp(mount->mnt_fsname + 5, st->arg) == 0) {
-                strlcpy(st->parg.df.mountpath, mount->mnt_dir, sizeof(st->parg.df.mountpath));
-                info("started module df(%.200s) --> %.200s", st->arg, st->parg.df.mountpath);
-                endmntent(fp);
-		return;
-            }
-	}
+	if (strncmp(mount->mnt_fsname, drivename, sizeof(drivename)) == 0) {
+            strlcpy(st->parg.df.mountpath, mount->mnt_dir, sizeof(st->parg.df.mountpath));
+            info("started module df(%.200s = %.200s)", st->arg, st->parg.df.mountpath);
+            endmntent(fp);
+            return;
+        }
     }
 
     endmntent(fp);
 
-    strlcpy(st->parg.df.mountpath, "/", sizeof(st->parg.df.mountpath));
-
-    info("failed to find (%.200s) - started module df for /", st->arg);
+    fatal("df(.200s): not mounted", st->arg);
 }
 
 void

+ 179 - 0
symon/platform/Linux/sm_flukso.c

@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2010 Willem Dijkstra
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *    - Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ *    - Redistributions in binary form must reproduce the above
+ *      copyright notice, this list of conditions and the following
+ *      disclaimer in the documentation and/or other materials provided
+ *      with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/*
+ * Get measurement data from a flukso (arduino) board tied to the serial port.
+ *
+ * num : value
+ *
+ */
+
+#include "conf.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <string.h>
+#include <inttypes.h>
+#include <fcntl.h>
+#include <termios.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <strings.h>
+
+#include "error.h"
+#include "symon.h"
+#include "xmalloc.h"
+
+#define FLUKSO_MAXSENSORS 3
+#define FLUKSO_IDLEN 32
+#define SCN(x) #x
+
+static int flukso_fd = -1;
+static void *flukso_buf = NULL;
+static int flukso_size = 0;
+static int flukso_maxsize = 0;
+static int flukso_nrsensors = 0;
+
+struct flukso_sensor {
+    char id[FLUKSO_IDLEN];
+    uint64_t value;
+    uint64_t n;
+};
+struct flukso_sensor flukso_sensor[FLUKSO_MAXSENSORS];
+
+void
+init_flukso(struct stream *st)
+{
+    struct termios tio;
+
+    bzero(flukso_sensor, sizeof(struct flukso_sensor) * FLUKSO_MAXSENSORS);
+
+    if (flukso_buf == NULL) {
+        flukso_maxsize = SYMON_MAX_OBJSIZE;
+        flukso_buf = xmalloc(flukso_maxsize);
+    }
+
+    if (flukso_fd == -1) {
+        bzero(&tio, sizeof(tio));
+        tio.c_iflag = tio.c_oflag = tio.c_lflag = 0;
+        tio.c_cflag = CS8 | CREAD | CLOCAL;
+        tio.c_cc[VMIN] = 1;
+        tio.c_cc[VTIME] = 5;
+        if ((flukso_fd = open("/dev/ttyS0", O_RDONLY | O_NONBLOCK)) < 0)
+            fatal("flukso: could not open '%s' for read", "/dev/ttyS0");
+        cfsetispeed(&tio, B4800);
+        tcsetattr(flukso_fd, TCSANOW, &tio);
+    }
+
+    if (flukso_size == 0)
+        gets_flukso();
+
+    if (st->arg != NULL &&
+        FLUKSO_IDLEN == strspn(st->arg, "0123456789abcdef")) {
+        bcopy(st->arg, st->parg.flukso, FLUKSO_IDLEN);
+        info("started module flukso(%.200s)", st->arg);
+    } else {
+        fatal("flukso: could not parse sensor name %.200s", st->arg);
+    }
+}
+
+void
+gets_flukso()
+{
+    int len = 0;
+    int p = 0;
+    int i;
+    void *nl;
+    uint32_t value;
+    char id[FLUKSO_IDLEN];
+
+    if ((len = read(flukso_fd, flukso_buf + flukso_size, flukso_maxsize - flukso_size)) < 0) {
+        warning("flukso: cannot read data");
+        return;
+    }
+
+    flukso_size += len;
+
+    /* We read the pwr messages rather than the pls pulse messages as we are
+     * interested in the current load only */
+    while ((p < flukso_size) &&
+           ((nl = memchr(flukso_buf + p, '\n', flukso_size - p)) != NULL)) {
+        len = nl - (flukso_buf + p) + 1;
+
+        if (2 > sscanf(flukso_buf + p, "pwr %32s:%" SCNu32 "\n", &id[0], &value)) {
+            p += len;
+            continue;
+        }
+
+        for (i = 0; i < flukso_nrsensors; i++) {
+            if (strncmp(flukso_sensor[i].id, id, FLUKSO_IDLEN) == 0) {
+                flukso_sensor[i].value += value;
+                flukso_sensor[i].n++;
+                break;
+            }
+        }
+
+        if ((i == flukso_nrsensors) && (flukso_nrsensors < FLUKSO_MAXSENSORS)) {
+            bcopy(id, flukso_sensor[i].id, FLUKSO_IDLEN);
+            flukso_sensor[i].value = value;
+            flukso_sensor[i].n = 1;
+            flukso_nrsensors++;
+        }
+
+        p += len;
+    }
+
+    if (p < flukso_size) {
+        bcopy(flukso_buf + p, flukso_buf, flukso_size - p);
+        flukso_size -= p;
+    } else {
+        flukso_size = 0;
+    }
+}
+
+int
+get_flukso(char *symon_buf, int maxlen, struct stream *st)
+{
+    int i;
+    double avgwatts;
+
+    for (i = 0; i < flukso_nrsensors; i++) {
+        if (strncmp(st->parg.flukso, flukso_sensor[i].id, FLUKSO_IDLEN) == 0) {
+            avgwatts = (double) flukso_sensor[i].value / (double) flukso_sensor[i].n;
+            flukso_sensor[i].value = 0;
+            flukso_sensor[i].n = 0;
+
+            return snpack(symon_buf, maxlen, st->arg, MT_FLUKSO, avgwatts);
+        }
+    }
+
+    return 0;
+}

+ 21 - 5
symon/platform/Linux/sm_io.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001-2006 Willem Dijkstra
+ * Copyright (c) 2001-2011 Willem Dijkstra
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -80,12 +80,28 @@ char *io_filename = "/proc/partitions";
 void
 init_io(struct stream *st)
 {
+    size_t lead;
+
     if (io_buf == NULL) {
         io_maxsize = SYMON_MAX_OBJSIZE;
         io_buf = xmalloc(io_maxsize);
     }
 
-    info("started module io(%.200s)", st->arg);
+    if (st->arg == NULL)
+        fatal("io: need a <device>|<devicename> argument");
+
+    if ((diskbyname(st->arg, &st->parg.io[0], MAX_PATH_LEN) == 0))
+        fatal("io: '%.200s' is not a <device>|<devicename>", st->arg);
+
+    /* devices are named sdX, not /dev/sdX */
+    lead = sizeof("/dev/") - 1;
+    if (strncmp(st->parg.io, "/dev/", lead) == 0)
+        memmove(&st->parg.io[0], &st->parg.io[0] + lead, sizeof(st->parg.io) - lead);
+
+    if (strcmp(st->arg, st->parg.io) == 0)
+        info("started module io(%.200s)", st->parg.io);
+    else
+        info("started module io(%.200s = %.200s)", st->arg, st->parg.io);
 }
 
 void
@@ -128,12 +144,12 @@ get_io(char *symon_buf, int maxlen, struct stream *st)
         return 0;
     }
 
-    if ((line = strstr(io_buf, st->arg)) == NULL) {
-        warning("could not find disk %s", st->arg);
+    if ((line = strstr(io_buf, st->parg.io)) == NULL) {
+        warning("could not find disk %.200s = %.200s", st->arg, st->parg.io);
         return 0;
     }
 
-    line += strlen(st->arg);
+    line += strlen(st->parg.io);
     bzero(&stats, sizeof(struct io_device_stats));
 
     if (11 > sscanf(line, " %" SCNu64 " %" SCNu64

+ 10 - 14
symon/platform/Linux/sm_smart.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2009 Willem Dijkstra
+ * Copyright (c) 2008-2011 Willem Dijkstra
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -92,16 +92,15 @@ init_smart(struct stream *st)
         fatal("smart: internal error: smart values structure is broken");
     }
 
-    if (st->arg == NULL) {
-        fatal("smart: need a <device> argument");
-    }
+    if (st->arg == NULL)
+        fatal("smart: need a <disk device|name> argument");
 
-    bzero(drivename, MAX_PATH_LEN);
-    snprintf(drivename, MAX_PATH_LEN, "/dev/%s", st->arg);
+    if ((diskbyname(st->arg, drivename, sizeof(drivename)) == 0))
+        fatal("smart: '%.200s' is not a disk device", st->arg);
 
     /* look for drive in our global table */
     for (i = 0; i < smart_cur; i++) {
-        if (strncmp(smart_devs[i].name, drivename, MAX_PATH_LEN) == 0) {
+        if (strncmp(smart_devs[i].name, drivename, sizeof(drivename)) == 0) {
             st->parg.smart = i;
             return;
         }
@@ -118,21 +117,18 @@ init_smart(struct stream *st)
     bzero(&smart_devs[smart_cur], sizeof(struct smart_device));
 
     /* store drivename in new block */
-    snprintf(smart_devs[smart_cur].name, MAX_PATH_LEN, "%s", drivename);
+    strlcpy(smart_devs[smart_cur].name, drivename, sizeof(smart_devs[0].name));
 
     /* store filedescriptor to device */
-    smart_devs[smart_cur].fd = open(drivename, O_RDONLY | O_NONBLOCK);
-
-    if (errno) {
-        fatal("smart: could not open '%s' for read", drivename);
-    }
+    if ((smart_devs[smart_cur].fd = open(drivename, O_RDONLY | O_NONBLOCK)) < 0)
+        fatal("smart: could not open '%.200s' for read: %.200s", drivename, strerror(errno));
 
     /* store smart dev entry in stream to facilitate quick get */
     st->parg.smart = smart_cur;
 
     smart_cur++;
 
-    info("started module smart(%.200s)", st->arg);
+    info("started module smart(%.200s = %.200s)", st->arg, smart_devs[st->parg.smart].name);
 }
 
 void

+ 1 - 0
symon/platform/OpenBSD/Makefile.inc

@@ -1,2 +1,3 @@
 SYMUX_LIBS?=-L/usr/X11R6/lib -lfontconfig
 MANDIR?=man
+NROFF!= (if [ -x /usr/bin/mandoc ]; then echo mandoc; else echo nroff; fi)

+ 11 - 1
symon/platform/OpenBSD/sm_io.c

@@ -51,6 +51,7 @@
 static char *io_dkstr = NULL;
 static struct diskstats *io_dkstats = NULL;
 static char **io_dknames = NULL;
+static char **io_dkuids = NULL;
 static int io_dks = 0;
 static int io_maxdks = 0;
 static size_t io_maxstr = 0;
@@ -98,6 +99,7 @@ gets_io()
 
         io_dkstats = xrealloc(io_dkstats, io_maxdks * sizeof(struct diskstats));
         io_dknames = xrealloc(io_dknames, io_maxdks * sizeof(char *));
+        io_dkuids = xrealloc(io_dkuids, io_maxdks * sizeof(char *));
         io_dkstr = xrealloc(io_dkstr, io_maxstr + 1);
     }
 
@@ -128,7 +130,13 @@ gets_io()
             *p = '\0';
             io_dks++; p++;
             io_dknames[io_dks] = p;
+            io_dkuids[io_dks] = NULL;
         }
+        if ((*p == ':') && (*p+1 != '\0')) {
+            *p = '\0';
+            p++;
+            io_dkuids[io_dks] = p;
+	}
         p++;
     }
 }
@@ -146,8 +154,10 @@ get_io(char *symon_buf, int maxlen, struct stream *st)
 
     /* look for disk */
     for (i = 0; i <= io_dks; i++) {
-        if (strncmp(io_dknames[i], st->arg,
+        if ((strncmp(io_dknames[i], st->arg,
                     (io_dkstr + io_maxstr - io_dknames[i])) == 0)
+        	    || (io_dkuids[i] && (strncmp(io_dkuids[i], st->arg,
+                    (io_dkstr + io_maxstr - io_dkuids[i])) == 0)))
 #ifdef HAS_IO2
             return snpack(symon_buf, maxlen, st->arg, MT_IO2,
                           io_dkstats[i].ds_rxfer,

+ 25 - 0
symon/platform/stub/sm_flukso.c

@@ -0,0 +1,25 @@
+#include <stdlib.h>
+
+#include "sylimits.h"
+#include "data.h"
+#include "error.h"
+
+void
+init_flukso(struct stream *st)
+{
+    fatal("flukso module not available");
+}
+
+void
+gets_flukso()
+{
+    fatal("flukso module not available");
+}
+
+int
+get_flukso(char *symon_buf, int maxlen, struct stream *st)
+{
+    fatal("flukso module not available");
+    /* NOT REACHED */
+    return 0;
+}

+ 3 - 1
symon/symon/Makefile

@@ -11,7 +11,9 @@ MODS!=	( for s in ../platform/stub/sm_*.c; do \
 		else                     echo $$s; \
 		fi; fi; \
 	  done )
-SRCS=	symon.c readconf.c symonnet.c ${MODS}
+
+EXTRA_SRC=${PLATFORM_SRC:S,^,../platform/${OS}/,g}
+SRCS=	symon.c readconf.c symonnet.c ${MODS} ${EXTRA_SRC}
 OBJS+=	${SRCS:R:S/$/.o/g}
 CFLAGS+=-I../lib -I../platform/${OS} -I.
 

+ 2 - 1
symon/symon/readconf.c

@@ -116,6 +116,7 @@ read_symon_args(struct mux * mux, struct lex * l)
         case LXT_SENSOR:
         case LXT_SMART:
         case LXT_LOAD:
+        case LXT_FLUKSO:
             st = token2type(l->op);
             strncpy(&sn[0], l->token, _POSIX2_LINE_MAX);
 
@@ -154,7 +155,7 @@ read_symon_args(struct mux * mux, struct lex * l)
         case LXT_COMMA:
             break;
         default:
-            parse_error(l, "{cpu|cpuiow|df|if|if1|io|io1|load|mem|mem1|pf|pfq|mbuf|debug|proc|sensor|smart}");
+            parse_error(l, "{cpu|cpuiow|df|if|if1|io|io1|load|mem|mem1|pf|pfq|mbuf|debug|proc|sensor|smart|load|flukso}");
             return 0;
             break;
         }

+ 42 - 14
symon/symon/symon.8

@@ -27,7 +27,7 @@
 .\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd November 23, 2009
+.Dd October 20, 2010
 .Dt SYMON 8
 .Os
 .Sh NAME
@@ -99,46 +99,74 @@ resources should be monitored and to which
 .Xr symux 8
 the information should be streamed to.
 .Pp
-Multiple monitor statements to different muxes are allowed. Whitespace,
-newlines and text behind '#' are ignored. The format in BNF:
+Multiple monitor statements are allowed. Whitespace, newlines and text
+behind '#' are ignored. The format in BNF:
 .Pp
-.nf
+.Bd -literal -offset indent -compact
 monitor-rule = "monitor" "{" resources "}" [every]
                "stream" ["from" host] ["to"] host [ port ]
 resources    = resource [ version ] ["(" argument ")"]
                [ ","|" " resources ]
-resource     = "cpu" | "cpuiow" | "debug" | "df" | "if" | "io" |
-               "load" | "mbuf" | "mem" | "pf" | "pfq" | "proc" |
-               "sensor" | "smart"
+resource     = "cpu" | "cpuiow" | "debug" | "df" | "flukso" |
+               "if" | "io" | "load" | "mbuf" | "mem" | "pf" |
+               "pfq" | "proc" | "sensor" | "smart"
 version      = number
 argument     = number | name
 every        = "every" time
 time         = "second" | number "seconds"
 host         = ip4addr | ip6addr | hostname
 port         = [ "port" | "," ] portnumber
-.fi
+.Ed
 .Pp
 Note that symux(8) data files default to receiving data every 5
-seconds. Adjusting the monitoring interval will also require adjusting every
-symux(8) datafile.
+seconds. Adjusting the monitoring interval will also require adjusting the
+associated symux(8) datafile(s).
 .Pp
 The pf probe will return data that is collected for the
 .Pa loginterface
 set in /etc/pf.conf(5).
+.Pp
+The Linux io, df, and smart probes support device names via id, label, path and uuid.
+.Pp
+The OpenBSD io probe supports device uuids.
+.Pp
 .Sh EXAMPLE
-Here is an example
+Here is an example OpenBSD
 .Ar symon.conf
 that monitors cpu, memory, pf, interfaces xl0/de0/lo0/wi0, disks
 wd[0-3]/cd[0-1], debug variables debug0 to debug19 and streams that
 information to localhost on port 2100.
 .Pp
-.nf
+.Bd -literal -offset indent -compact
 monitor { cpu(0),  mem, pf, if(xl0), if(de0),
 	  if(lo0), if(wi0), io(wd0), io(wd1),
 	  io(wd2), io(wd3), io(cd0), io(cd1),
 	  io(ccd0), df(sd0a), df(sd0d), df(sd0e),
 	  debug, proc(httpd) } stream to 127.0.0.1 2100
-.fi
+.Ed
+.Sh EXAMPLE
+Here is an example Linux
+.Ar symon.conf
+that monitors cpu including iowait, memory, load, interface eth0, io and df for
+a set of disks every 5 seconds. Smart data is to be collected every 60 seconds.
+Disks in the smart and io statements are identified using ids, filesystem
+volumes in df using labels.
+.Bd -literal -offset indent -compact
+monitor { smart(ata-Hitachi_HDS722020ALA330_JK1130ABABABAB),
+          smart(ata-Hitachi_HDS722020ALA330_JK1130ACACACAC),
+        } every 60 seconds stream to 192.168.0.2 port 2100
+
+monitor { cpuiow(0), cpuiow(1), mem, if(eth0),
+          io(ata-Hitachi_HDS722020ALA330_JK1130ABABABAB),
+          io(ata-Hitachi_HDS722020ALA330_JK1130ACACACAC),
+          df(data_1),
+          df(data_2),
+          df(data_3),
+          df(home),
+          df(var),
+          load
+        } stream to 192.168.0.2 port 2100
+.Ed
 .Sh SIGNALS
 .Bl -tag -width Ds
 .It SIGHUP
@@ -171,7 +199,7 @@ The proc module is too simple: memory shared between two instances of the same
 process is simply counted twice.
 .Pp
 .Nm
-does not check whether resources mentioned in
+does not check whether all resources mentioned in
 .Pa /etc/symon.conf
 exist.
 .Pp

+ 5 - 1
symon/symon/symon.c

@@ -67,6 +67,9 @@ int flag_hup = 0;
 int flag_testconf = 0;
 int symon_interval = 0;
 
+/* program wide time_t indicating start of measurement time */
+time_t now;
+
 /* map stream types to inits and getters */
 struct funcmap streamfunc[] = {
     {MT_IO1, 0, NULL, init_io, gets_io, get_io},
@@ -86,6 +89,7 @@ struct funcmap streamfunc[] = {
     {MT_CPUIOW, 0, NULL, init_cpuiow, gets_cpuiow, get_cpuiow},
     {MT_SMART, 0, NULL, init_smart, gets_smart, get_smart},
     {MT_LOAD, 0, NULL, init_load, gets_load, get_load},
+    {MT_FLUKSO, 0, NULL, init_flukso, gets_flukso, get_flukso},
     {MT_EOT, 0, NULL, NULL, NULL}
 };
 
@@ -198,7 +202,7 @@ main(int argc, char *argv[])
     struct muxlist mul, newmul;
     struct stream *stream;
     struct mux *mux;
-    time_t now, last_update;
+    time_t last_update;
     FILE *pidfile;
     char *cfgpath;
     int ch;

+ 6 - 0
symon/symon/symon.h

@@ -56,6 +56,7 @@ struct funcmap {
 extern struct funcmap streamfunc[];
 
 extern int symon_interval;
+extern time_t now;
 
 /* prototypes */
 __BEGIN_DECLS
@@ -130,6 +131,11 @@ extern void init_load(struct stream *);
 extern void gets_load();
 extern int get_load(char *, int, struct stream *);
 
+/* sm_flukso.c */
+void init_flukso(struct stream *);
+void gets_flukso();
+int get_flukso(char *, int, struct stream *);
+
 __END_DECLS
 
 #endif                          /* _SYMON_SYMON_H */

+ 7 - 1
symon/symux/c_smrrds.sh

@@ -317,7 +317,13 @@ load.rrd)
     create_rrd $i \
 	DS:load1:GAUGE:$INTERVAL:0:U \
 	DS:load5:GAUGE:$INTERVAL:0:U \
-	DS:load15:GAUGE:$INTERVAL:0:U \
+	DS:load15:GAUGE:$INTERVAL:0:U
+    ;;
+
+flukso_*.rrd)
+    # Build the flukso file
+    create_rrd $i \
+        DS:watts:GAUGE:$INTERVAL:0:U
     ;;
 
 "done")

+ 8 - 2
symon/symux/readconf.c

@@ -123,6 +123,10 @@ insert_filename(char *path, int maxlen, int type, char *args)
         ts = "load";
         ta = "";
         break;
+    case MT_FLUKSO:
+        ts = "flukso_";
+        ta = args;
+        break;
 
     default:
         warning("%.200s:%d: internal error: type (%d) unknown",
@@ -239,6 +243,7 @@ read_source(struct sourcelist * sol, struct lex * l, int filecheck)
                 case LXT_SENSOR:
                 case LXT_SMART:
                 case LXT_LOAD:
+                case LXT_FLUKSO:
                     st = token2type(l->op);
                     strncpy(&sn[0], l->token, _POSIX2_LINE_MAX);
 
@@ -280,7 +285,7 @@ read_source(struct sourcelist * sol, struct lex * l, int filecheck)
                 case LXT_COMMA:
                     break;
                 default:
-                    parse_error(l, "{cpu|cpuiow|df|if|if1|io|io1|mem|mem1|pf|pfq|mbuf|debug|proc|sensor|smart|load}");
+                    parse_error(l, "{cpu|cpuiow|df|if|if1|io|io1|mem|mem1|pf|pfq|mbuf|debug|proc|sensor|smart|load|flukso}");
                     return 0;
 
                     break;
@@ -384,6 +389,7 @@ read_source(struct sourcelist * sol, struct lex * l, int filecheck)
             case LXT_SENSOR:
             case LXT_SMART:
             case LXT_LOAD:
+            case LXT_FLUKSO:
                 st = token2type(l->op);
                 strncpy(&sn[0], l->token, _POSIX2_LINE_MAX);
 
@@ -445,7 +451,7 @@ read_source(struct sourcelist * sol, struct lex * l, int filecheck)
                 }
                 break;          /* LXT_resource */
             default:
-                parse_error(l, "{cpu|cpuiow|df|if|if1|io|io1|mem|mem1|pf|pfq|mbuf|debug|proc|sensor|smart|load}");
+                parse_error(l, "{cpu|cpuiow|df|if|if1|io|io1|mem|mem1|pf|pfq|mbuf|debug|proc|sensor|smart|load|flukso}");
                 return 0;
                 break;
             }

+ 15 - 11
symon/symux/symux.8

@@ -27,7 +27,7 @@
 .\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd January 20, 2010
+.Dd October 20, 2010
 .Dt SYMUX 8
 .Os
 .Sh NAME
@@ -104,7 +104,7 @@ ipv6 with mux = ipv4, a listen port of the sources' family is opened
 using the unspecified address. Whitespace, newlines and text behind '#'
 are ignored. The format in BNF:
 .Pp
-.nf
+.Bd -literal -offset indent -compact
 stmt         = mux-stmt | source-stmt
 mux-stmt     = "mux" host [ port ]
 host         = ip4addr | ip6addr | hostname
@@ -117,15 +117,15 @@ accept-stmts = accept-stmt [accept-stmts]
 accept-stmt  = "accept" "{" resources "}"
 resources    = resource [ version ] ["(" argument ")"]
                [ ","|" " resources ]
-resource     = "cpu" | "cpuiow" | "debug" | "df" | "if" | "io"
-               "load" | "mbuf" | "mem" | "pf" | "pfq" | "proc" |
-               "sensor" | "smart"
+resource     = "cpu" | "cpuiow" | "debug" | "df" | "flukso" |
+               "if" | "io" | "load" | "mbuf" | "mem" | "pf" |
+               "pfq" | "proc" | "sensor" | "smart"
 version      = number
 argument     = number | interfacename | diskname
 datadir-stmt = "datadir" dirname
 write-stmts  = write-stmt [write-stmts]
 write-stmt   = "write" resource "in" filename
-.fi
+.Ed
 .Pp
 Note that
 .Bl -tag -width Ds
@@ -158,7 +158,7 @@ on localhost.
 .Nm
 will also listen on tcp port 2100 for incoming listeners.
 .Pp
-.nf
+.Bd -literal -offset indent -compact
 mux 127.0.0.1 2100
 source 127.0.0.1 {
     accept { cpu(0), mem, pf,
@@ -170,14 +170,14 @@ source 127.0.0.1 {
 .Pp
     datadir "/var/www/symon/rrds/localhost"
 }
-.fi
+.Ed
 .Sh LISTENERS
 .Nm
 offers received
 .Xr symon 8
 data to other programs via tcp. An example of a listener session:
 .Pp
-.nf
+.Bd -literal -offset indent -compact
 nexus:~/project/symon$ telnet 10.0.0.1 2100
 Trying 10.0.0.1...
 Connected to 10.0.0.1.
@@ -190,7 +190,7 @@ Escape character is '^]'.
 0:0;pf::1077658247:700930123:535398451:0:352:1107229:706391:119833
 9:4:0:0:2:3:29:4109383:83291:83262:980325:0:1:6:0:0;mem::107765824
 7:79155200:131956736:391430144:0:536739840;cpu:0:1077658247:0.50:0
-.00:0.00:0.90:98.60;proc:httpd:1077658247:9:216:172:8:3:0.00:14999
+\.00:0.00:0.90:98.60;proc:httpd:1077658247:9:216:172:8:3:0.00:14999
 552:0;if:lo0:1077658247:147104:147104:45868177:45868177:0:0:0:0:0:
 0;if:xl0:1077658247:284267:452077:150620236:273265863:372:89478:0:
 0:0:0;if:de0:1077658247:1813721:1197722:729054136:568900227:101:2:
@@ -199,7 +199,7 @@ Escape character is '^]'.
 ^]
 telnet> close
 Connection closed.
-.fi
+.Ed
 .Lp
 The format is
 .Va symon-version
@@ -284,6 +284,10 @@ SMART attributes ( read_error_rate: reallocated_sectors: spin_retries:
 air_flow_temp: temperature: reallocations: current_pending: uncorrectables:
 soft_read_error_rate: g_sense_error_rate: temperature2: free_fall_protection
 ). Values depend on drive model and may change between models.
+.It flukso
+Average pwr sensor value offered with 7.6 precision. Value is a moving average
+and will depend on the number of measurements seen in a particular symon
+interval.
 .El
 .Sh SIGNALS
 .Bl -tag -width Ds