Pārlūkot izejas kodu

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

Wictor Lund 3 gadi atpakaļ
vecāks
revīzija
7fbea403d2

+ 43 - 3
symon/CHANGELOG

@@ -1,3 +1,44 @@
+19/12/2006 - 2.73
+   - symux stops reporting rrd errors after 5 messages to counter logspam
+     (Henning Brauer)
+
+   - NetBSD compiles on 2.1 after addition of rrd.h location in
+     NetBSD/Makefile.inc
+
+   - FreeBSD/platform.h now also includes sys/socket.h and sys/dkstat.h, which
+     makes the FreeBSD probes compile on 4/5/6.
+
+   - FreeBSD/sm_pf and OpenBSD/sm_pf were broken when pf was not available
+     (Ulrich Spörlein)
+
+   - c_smrrds.sh now accepts filenames, not descriptions. Intended use is now
+     c_smrrds.sh `symux -l`.
+
+   - symux -l lists rrd files in active configuration.
+
+   - symon/symon.c now deals correctly with ntp drift and sleeps
+     longer. The previous version did not sleep long enough, which could
+     result in both the alarm and end of sleep issueing a measurement
+     where only one was due.
+
+   - Library deps now split between symon and symux. Not all libraries are
+     needed on a host if only symon/symux is compiled.
+
+   - OpenBSD/Makefile.inc now includes fontconfig library needed for
+     gd > 2.0.33. This breaks symux compilation for OpenBSD < 3.9.
+
+   - OpenBSD/sm_cpu is smp aware
+
+   - OpenBSD/sm_mbuf needs errno
+
+   - symuxnet.c now allows clients to connect in Linux
+
+   - Linux/sm_io added
+
+   - FreeBSD/sm_mem fix for swap in 6/5/4 (Clive Lin)
+
+   - FreeBSD/sm_io updated to reflect devstats api change
+
 23/10/2005 - 2.72
 23/10/2005 - 2.72
 
 
    - probes use a new "api" that allows per probe storage of
    - probes use a new "api" that allows per probe storage of
@@ -7,7 +48,7 @@
 
 
    - Harm Schotanus donated mem probe for linux that works on 2.4/2.6
    - Harm Schotanus donated mem probe for linux that works on 2.4/2.6
 
 
-   - platform/OpenBSD/sm_if.c no longer uses netns (Mitja Muzenic)
+   - OpenBSD/sm_if.c no longer uses netns (Mitja Muzenic)
 
 
    - symux/share.c now uses a ringbuffer to distribute symon packets to
    - symux/share.c now uses a ringbuffer to distribute symon packets to
      connected tcp clients. Clients that can not keep up with the datarate are
      connected tcp clients. Clients that can not keep up with the datarate are
@@ -21,7 +62,6 @@
    - sm_sensor: sensor support was detected on OpenBSD, but did not get
    - sm_sensor: sensor support was detected on OpenBSD, but did not get
      configured (Eric Dillenseger)
      configured (Eric Dillenseger)
 
 
-
 19/03/2005 - 2.71
 19/03/2005 - 2.71
 
 
    - Ulrich Spörlein updated mem probe for FreeBSD-current and removed some
    - Ulrich Spörlein updated mem probe for FreeBSD-current and removed some
@@ -420,4 +460,4 @@
 29/09/2001 - Lexer had trouble dealing with ip-addresses. Cleaned up the number
 29/09/2001 - Lexer had trouble dealing with ip-addresses. Cleaned up the number
              parsing code and removed a second comment reader.
              parsing code and removed a second comment reader.
 
 
-$Id: CHANGELOG,v 1.48 2005/10/21 14:58:41 dijkstra Exp $
+$Id: CHANGELOG,v 1.55 2006/12/19 22:31:38 dijkstra Exp $

+ 4 - 3
symon/INSTALL

@@ -70,8 +70,9 @@ Less quick, but all OSes
   configurations for both in $PREFIX/$SHRDIR.
   configurations for both in $PREFIX/$SHRDIR.
 
 
 - Create the rrd files where the incoming symon data is to be
 - Create the rrd files where the incoming symon data is to be
-  stored. $PREFIX/$SHRDIR/c_smrrds.sh is your friend. Note that syweb expects
-  an '.../machine/*.rrd' style directory structure somewhere under /var/www.
+  stored. $PREFIX/$SHRDIR/c_smrrds.sh and symux -l are your friends. Note that
+  syweb expects an '.../machine/*.rrd' style directory structure somewhere
+  under /var/www.
 
 
 - Both symon and symux will daemonize if started normally. Start them with
 - Both symon and symux will daemonize if started normally. Start them with
   debugging on initially to iron out any configuration problems:
   debugging on initially to iron out any configuration problems:
@@ -105,5 +106,5 @@ for FreeBSD, NetBSD and Linux.
 
 
 Willem Dijkstra - wpd@xs4all.nl
 Willem Dijkstra - wpd@xs4all.nl
 
 
-$Id: INSTALL,v 1.19 2005/10/21 14:58:41 dijkstra Exp $
+$Id: INSTALL,v 1.21 2006/12/19 22:37:11 dijkstra Exp $
 
 

+ 2 - 2
symon/Makefile.inc

@@ -1,6 +1,6 @@
-# $Id: Makefile.inc,v 1.32 2005/09/30 14:04:56 dijkstra Exp $
+# $Id: Makefile.inc,v 1.33 2006/06/30 08:23:42 dijkstra Exp $
 
 
-V=2.72
+V=2.73
 OS!=uname -s
 OS!=uname -s
 
 
 AR?=	ar
 AR?=	ar

+ 3 - 3
symon/lib/data.c

@@ -1,4 +1,4 @@
-/* $Id: data.c,v 1.28 2005/10/16 15:26:51 dijkstra Exp $ */
+/* $Id: data.c,v 1.29 2006/06/28 06:44:45 dijkstra Exp $ */
 
 
 /*
 /*
  * Copyright (c) 2001-2005 Willem Dijkstra
  * Copyright (c) 2001-2005 Willem Dijkstra
@@ -136,7 +136,7 @@ u_int32_t
 crc32_table[256];
 crc32_table[256];
 
 
 /* Convert lexical entities to stream entities */
 /* Convert lexical entities to stream entities */
-const int
+int
 token2type(const int token)
 token2type(const int token)
 {
 {
     int i;
     int i;
@@ -152,7 +152,7 @@ token2type(const int token)
     return 0;
     return 0;
 }
 }
 /* Convert stream entities to their ascii representation */
 /* Convert stream entities to their ascii representation */
-const char *
+char *
 type2str(const int streamtype)
 type2str(const int streamtype)
 {
 {
     int i;
     int i;

+ 3 - 3
symon/lib/data.h

@@ -1,4 +1,4 @@
-/* $Id: data.h,v 1.27 2005/10/16 15:26:51 dijkstra Exp $ */
+/* $Id: data.h,v 1.28 2006/06/28 06:44:45 dijkstra Exp $ */
 
 
 /*
 /*
  * Copyright (c) 2001-2005 Willem Dijkstra
  * Copyright (c) 2001-2005 Willem Dijkstra
@@ -301,8 +301,8 @@ struct packedstream {
 
 
 /* prototypes */
 /* prototypes */
 __BEGIN_DECLS
 __BEGIN_DECLS
-const char *type2str(const int);
-const int token2type(const int);
+char *type2str(const int);
+int token2type(const int);
 int calculate_churnbuffer(struct sourcelist *);
 int calculate_churnbuffer(struct sourcelist *);
 int getheader(char *, struct symonpacketheader *);
 int getheader(char *, struct symonpacketheader *);
 int ps2strn(struct packedstream *, char *, int, int);
 int ps2strn(struct packedstream *, char *, int, int);

+ 3 - 3
symon/lib/lex.c

@@ -1,4 +1,4 @@
-/* $Id: lex.c,v 1.26 2005/10/16 15:26:51 dijkstra Exp $ */
+/* $Id: lex.c,v 1.27 2006/06/28 06:44:45 dijkstra Exp $ */
 
 
 /*
 /*
  * Copyright (c) 2001-2005 Willem Dijkstra
  * Copyright (c) 2001-2005 Willem Dijkstra
@@ -111,14 +111,14 @@ parse_token(const char *cp)
     return LXT_BADTOKEN;
     return LXT_BADTOKEN;
 }
 }
 /* Return the ascii representation of an opcode */
 /* Return the ascii representation of an opcode */
-const char *
+char *
 parse_opcode(const int op)
 parse_opcode(const int op)
 {
 {
     u_int i;
     u_int i;
 
 
     for (i = 0; keywords[i].name; i++)
     for (i = 0; keywords[i].name; i++)
 	if (keywords[i].opcode == op)
 	if (keywords[i].opcode == op)
-	    return keywords[i].name;
+	    return (char *) keywords[i].name;
 
 
     return NULL;
     return NULL;
 }
 }

+ 2 - 2
symon/lib/lex.h

@@ -1,4 +1,4 @@
-/* $Id: lex.h,v 1.22 2005/10/16 15:26:51 dijkstra Exp $ */
+/* $Id: lex.h,v 1.23 2006/06/28 06:44:45 dijkstra Exp $ */
 
 
 /*
 /*
  * Copyright (c) 2001-2005 Willem Dijkstra
  * Copyright (c) 2001-2005 Willem Dijkstra
@@ -95,7 +95,7 @@ struct lex {
 };
 };
 
 
 __BEGIN_DECLS
 __BEGIN_DECLS
-const char *parse_opcode(int);
+char *parse_opcode(int);
 int lex_nexttoken(struct lex *);
 int lex_nexttoken(struct lex *);
 int parse_token(const char *);
 int parse_token(const char *);
 struct lex *open_lex(const char *);
 struct lex *open_lex(const char *);

+ 2 - 1
symon/lib/sylimits.h

@@ -1,4 +1,4 @@
-/* $Id: sylimits.h,v 1.3 2005/10/21 14:58:42 dijkstra Exp $ */
+/* $Id: sylimits.h,v 1.4 2006/09/10 19:51:32 dijkstra Exp $ */
 
 
 #ifndef _LIB_LIMITS_H
 #ifndef _LIB_LIMITS_H
 #define _LIB_LIMITS_H
 #define _LIB_LIMITS_H
@@ -11,6 +11,7 @@
 #define SYMON_MAX_OBJSIZE      (_POSIX2_LINE_MAX)
 #define SYMON_MAX_OBJSIZE      (_POSIX2_LINE_MAX)
 #define SYMON_SENSORMASK       0xFF     /* sensors 0-255 are allowed */
 #define SYMON_SENSORMASK       0xFF     /* sensors 0-255 are allowed */
 #define SYMON_MAXDEBUGID       20       /* = CTL_DEBUG_MAXID; depends lib/data.h */
 #define SYMON_MAXDEBUGID       20       /* = CTL_DEBUG_MAXID; depends lib/data.h */
+#define SYMON_MAXCPUID         16       /* cpu0 - cpu15 */
 #define SYMON_DFBLOCKSIZE      512
 #define SYMON_DFBLOCKSIZE      512
 #define SYMON_DFNAMESIZE       16
 #define SYMON_DFNAMESIZE       16
 
 

+ 2 - 2
symon/platform/FreeBSD/Makefile.inc

@@ -1,4 +1,4 @@
-# $Id: Makefile.inc,v 1.3 2005/03/20 16:17:22 dijkstra Exp $
-LIBS=-lkvm -ldevstat
+# $Id: Makefile.inc,v 1.4 2006/12/19 22:31:40 dijkstra Exp $
+SYMON_LIBS=-lkvm -ldevstat
 SYSCONFDIR=${PREFIX}/etc
 SYSCONFDIR=${PREFIX}/etc
 BINDIR=bin
 BINDIR=bin

+ 4 - 2
symon/platform/FreeBSD/platform.h

@@ -1,11 +1,13 @@
-/* $Id: platform.h,v 1.4 2005/10/21 14:58:43 dijkstra Exp $ */
+/* $Id: platform.h,v 1.5 2006/11/07 08:00:18 dijkstra Exp $ */
 
 
 #ifndef _CONF_FREEBSD_H
 #ifndef _CONF_FREEBSD_H
 #define _CONF_FREEBSD_H
 #define _CONF_FREEBSD_H
 
 
 #include <sys/queue.h>
 #include <sys/queue.h>
-#include <sys/socket.h>
 #include <sys/types.h>
 #include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/dkstat.h>
 #include <sys/resource.h>
 #include <sys/resource.h>
 
 
 #include <net/if.h>
 #include <net/if.h>

+ 4 - 4
symon/platform/FreeBSD/sm_io.c

@@ -1,4 +1,4 @@
-/* $Id: sm_io.c,v 1.3 2005/10/18 19:58:06 dijkstra Exp $ */
+/* $Id: sm_io.c,v 1.4 2006/06/27 18:53:58 dijkstra Exp $ */
 
 
 /*
 /*
  * Copyright (c) 2005 J. Martin Petersen
  * Copyright (c) 2005 J. Martin Petersen
@@ -80,7 +80,7 @@ init_io(struct stream *st)
 void
 void
 gets_io()
 gets_io()
 {
 {
-#if DEVSTAT_USER_API_VER == 5
+#if DEVSTAT_USER_API_VER >= 5
     io_numdevs = devstat_getnumdevs(NULL);
     io_numdevs = devstat_getnumdevs(NULL);
 #else
 #else
     io_numdevs = getnumdevs();
     io_numdevs = getnumdevs();
@@ -97,7 +97,7 @@ gets_io()
     /* clear the devinfo struct, as getdevs expects it to be all zeroes */
     /* clear the devinfo struct, as getdevs expects it to be all zeroes */
     bzero(io_stats.dinfo, sizeof(struct devinfo));
     bzero(io_stats.dinfo, sizeof(struct devinfo));
 
 
-#if DEVSTAT_USER_API_VER == 5
+#if DEVSTAT_USER_API_VER >= 5
     devstat_getdevs(NULL, &io_stats);
     devstat_getdevs(NULL, &io_stats);
 #else
 #else
     getdevs(&io_stats);
     getdevs(&io_stats);
@@ -117,7 +117,7 @@ get_io(char *symon_buf, int maxlen, struct stream *st)
 	    strlen(ds->device_name) < strlen(st->arg) &&
 	    strlen(ds->device_name) < strlen(st->arg) &&
 	    isdigit(st->arg[strlen(ds->device_name)]) &&
 	    isdigit(st->arg[strlen(ds->device_name)]) &&
 	    atoi(&st->arg[strlen(ds->device_name)]) == ds->unit_number) {
 	    atoi(&st->arg[strlen(ds->device_name)]) == ds->unit_number) {
-#if DEVSTAT_USER_API_VER == 5
+#if DEVSTAT_USER_API_VER >= 5
 	    return snpack(symon_buf, maxlen, st->arg, MT_IO2,
 	    return snpack(symon_buf, maxlen, st->arg, MT_IO2,
 			  ds->operations[DEVSTAT_READ],
 			  ds->operations[DEVSTAT_READ],
 			  ds->operations[DEVSTAT_WRITE],
 			  ds->operations[DEVSTAT_WRITE],

+ 4 - 4
symon/platform/FreeBSD/sm_mem.c

@@ -1,4 +1,4 @@
-/* $Id: sm_mem.c,v 1.8 2005/10/18 19:58:06 dijkstra Exp $ */
+/* $Id: sm_mem.c,v 1.9 2006/06/27 18:53:58 dijkstra Exp $ */
 
 
 /*
 /*
  * Copyright (c) 2004      Matthew Gream
  * Copyright (c) 2004      Matthew Gream
@@ -131,12 +131,12 @@ get_mem(char *symon_buf, int maxlen, struct stream *st)
     }
     }
     for (i = 0; i < vmnswp_dat; i++) {
     for (i = 0; i < vmnswp_dat; i++) {
 	struct xswdev vmiswp_dat;
 	struct xswdev vmiswp_dat;
-	int vmiswp_siz;
+	int vmiswp_siz = sizeof(vmiswp_dat);
 	me_vmiswp_mib_nam[me_vmiswp_mib_len] = i;
 	me_vmiswp_mib_nam[me_vmiswp_mib_len] = i;
 	if (sysctl(me_vmiswp_mib_nam, me_vmiswp_mib_len + 1, &vmiswp_dat, (void *)&vmiswp_siz, NULL, 0) < 0)
 	if (sysctl(me_vmiswp_mib_nam, me_vmiswp_mib_len + 1, &vmiswp_dat, (void *)&vmiswp_siz, NULL, 0) < 0)
 		continue;
 		continue;
-	me_stats[3] += (vmiswp_dat.xsw_used * DEV_BSIZE);
-	me_stats[4] += (vmiswp_dat.xsw_nblks * DEV_BSIZE);
+	me_stats[3] += pagetob(vmiswp_dat.xsw_used);
+	me_stats[4] += pagetob(vmiswp_dat.xsw_nblks);
     }
     }
 #endif
 #endif
 
 

+ 7 - 1
symon/platform/FreeBSD/sm_pf.c

@@ -1,4 +1,4 @@
-/* $Id: sm_pf.c,v 1.4 2005/10/18 19:58:06 dijkstra Exp $ */
+/* $Id: sm_pf.c,v 1.5 2006/11/07 08:00:18 dijkstra Exp $ */
 
 
 /*
 /*
  * Copyright (c) 2002 Daniel Hartmeier
  * Copyright (c) 2002 Daniel Hartmeier
@@ -73,6 +73,12 @@ init_pf(struct stream *st)
     fatal("pf support not available");
     fatal("pf support not available");
 }
 }
 
 
+void
+gets_pf()
+{
+    fatal("pf support not available");
+}
+
 int
 int
 get_pf(char *symon_buf, int maxlen, struct stream *st)
 get_pf(char *symon_buf, int maxlen, struct stream *st)
 {
 {

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

@@ -1,4 +1,3 @@
-# $Id: Makefile.inc,v 1.2 2005/02/25 12:31:58 dijkstra Exp $
-
+# $Id: Makefile.inc,v 1.3 2006/12/19 22:31:41 dijkstra Exp $
 LORDER=echo
 LORDER=echo
 TSORT= cat
 TSORT= cat

+ 13 - 0
symon/platform/Linux/conf.sh

@@ -0,0 +1,13 @@
+if [ -f /proc/diskstats ]; then
+    echo "#define HAS_PROC_DISKSTATS 1"
+else
+    echo "#undef HAS_PROC_DISKSTATS"
+fi
+if [ -f /proc/partitions ]; then
+    FIELDS=`head -1 /proc/partitions | wc -w`
+    if [ $FIELDS -eq 15 ]; then
+	echo "#define HAS_PROC_PARTITIONS 1"
+    else
+	echo "#undef HAS_PROC_PARTITIONS"
+    fi
+fi

+ 187 - 0
symon/platform/Linux/sm_io.c

@@ -0,0 +1,187 @@
+/* $Id: sm_io.c,v 1.1 2006/06/30 08:21:23 dijkstra Exp $ */
+
+/*
+ * Copyright (c) 2001-2006 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 current disk statistics from kernel and return them in symon_buf as
+ *
+ * total_rxfer, total_wxfer, total_seeks, total_rbytes, total_wbytes
+ *
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "conf.h"
+#include "xmalloc.h"
+#include "error.h"
+#include "symon.h"
+
+/* Globals for this module start with io_ */
+static void *io_buf = NULL;
+static int io_size = 0;
+static int io_maxsize = 0;
+struct io_device_stats
+{
+    uint64_t read_issued;
+    uint64_t read_merged;
+    uint64_t read_sectors;
+    uint64_t read_milliseconds;
+    uint64_t write_issued;
+    uint64_t write_merged;
+    uint64_t write_sectors;
+    uint64_t write_milliseconds;
+    uint64_t progress_ios;
+    uint64_t progress_milliseconds;
+    uint64_t progress_weight;
+};
+#ifdef HAS_PROC_DISKSTATS
+char *io_filename = "/proc/diskstats";
+#else
+#ifdef HAS_PROC_PARTITIONS
+char *io_filename = "/proc/partitions";
+#endif
+#endif
+
+#if defined(HAS_PROC_DISKSTATS) || defined(HAS_PROC_PARTITIONS)
+void
+init_io(struct stream *st)
+{
+    if (io_buf == NULL) {
+	io_maxsize = SYMON_MAX_OBJSIZE;
+	io_buf = xmalloc(io_maxsize);
+    }
+
+    info("started module io(%.200s)", st->arg);
+}
+
+void
+gets_io()
+{
+    int fd;
+    if ((fd = open(io_filename, O_RDONLY)) < 0) {
+	warning("cannot access %.200s: %.200s", io_filename, strerror(errno));
+	return;
+    }
+
+    bzero(io_buf, io_maxsize);
+    io_size = read(fd, io_buf, io_maxsize);
+    close(fd);
+
+    if (io_size == io_maxsize) {
+	/* buffer is too small to hold all interface data */
+	io_maxsize += SYMON_MAX_OBJSIZE;
+	if (io_maxsize > SYMON_MAX_OBJSIZE * SYMON_MAX_DOBJECTS) {
+	    fatal("%s:%d: dynamic object limit (%d) exceeded for io data",
+		  __FILE__, __LINE__, SYMON_MAX_OBJSIZE * SYMON_MAX_DOBJECTS);
+	}
+	io_buf = xrealloc(io_buf, io_maxsize);
+	gets_io();
+	return;
+    }
+
+    if (io_size == -1) {
+	warning("could not read io statistics from %.200s: %.200s", io_filename, strerror(errno));
+    }
+}
+
+int
+get_io(char *symon_buf, int maxlen, struct stream *st)
+{
+    char *line;
+    struct io_device_stats stats;
+
+    if (io_size <= 0) {
+	return 0;
+    }
+
+    if ((line = strstr(io_buf, st->arg)) == NULL) {
+	warning("could not find disk %s", st->arg);
+	return 0;
+    }
+
+    line += strlen(st->arg);
+    bzero(&stats, sizeof(struct io_device_stats));
+
+    if (11 > sscanf(line, " %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu\n",
+		    &stats.read_issued, &stats.read_merged,
+		    &stats.read_sectors, &stats.read_milliseconds,
+		    &stats.write_issued, &stats.write_merged,
+		    &stats.write_sectors, &stats.write_milliseconds,
+		    &stats.progress_ios, &stats.progress_milliseconds,
+		    &stats.progress_weight)) {
+#ifdef HAS_PROC_DISKSTATS
+	if (4 > sscanf(line, " %llu %llu %llu %llu\n",
+		       &stats.read_issued, &stats.read_sectors,
+		       &stats.write_issued, &stats.write_sectors)) {
+	    warning("could not parse disk statistics for %.200s", st->arg);
+	    return 0;
+	}
+    }
+#else
+	warning("could not parse disk statistics for %.200s", st->arg);
+	return 0;
+    }
+#endif
+
+    return snpack(symon_buf, maxlen, st->arg, MT_IO2,
+		  (stats.read_issued + stats.read_merged),
+		  (stats.write_issued + stats.write_merged),
+		  (uint64_t) 0,
+		  (uint64_t)(stats.read_sectors * DEV_BSIZE),
+		  (uint64_t)(stats.write_sectors * DEV_BSIZE));
+}
+#else
+void
+init_io(struct stream *st)
+{
+    fatal("io module not available");
+}
+void
+gets_io()
+{
+    fatal("io module not available");
+}
+int
+get_io(char *symon_buf, int maxlen, struct stream *st)
+{
+    fatal("io module not available");
+
+    /* NOT REACHED */
+    return 0;
+}
+#endif

+ 2 - 1
symon/platform/NetBSD/Makefile.inc

@@ -1 +1,2 @@
-# $Id: Makefile.inc,v 1.3 2005/10/21 14:58:45 dijkstra Exp $
+# $Id: Makefile.inc,v 1.4 2006/12/19 22:31:42 dijkstra Exp $
+RRDDIR=/usr/pkg

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

@@ -1,2 +1,3 @@
-# $Id: Makefile.inc,v 1.2 2005/03/22 07:17:43 dijkstra Exp $
+# $Id: Makefile.inc,v 1.4 2006/12/19 22:31:44 dijkstra Exp $
+SYMUX_LIBS=-L/usr/X11R6/lib -lfontconfig
 MANDIR=man
 MANDIR=man

+ 4 - 0
symon/platform/OpenBSD/conf.sh

@@ -2,6 +2,10 @@ case `grep -csq KERN_MBSTAT /usr/include/sys/sysctl.h` in
 1)	echo "#define HAS_KERN_MBSTAT	1" ;;
 1)	echo "#define HAS_KERN_MBSTAT	1" ;;
 0)	echo "#undef HAS_KERN_MBSTAT" ;;
 0)	echo "#undef HAS_KERN_MBSTAT" ;;
 esac;
 esac;
+case `grep -csq KERN_CPTIME2 /usr/include/sys/sysctl.h` in
+1)	echo "#define HAS_KERN_CPTIME2	1" ;;
+0)	echo "#undef HAS_KERN_CPTIME2" ;;
+esac;
 case `grep -csq "struct sensor" /usr/include/sys/sensors.h` in
 case `grep -csq "struct sensor" /usr/include/sys/sensors.h` in
 1)	echo "#define HAS_SENSORS_H	1" ;;
 1)	echo "#define HAS_SENSORS_H	1" ;;
 0)	echo "#undef HAS_SENSORS_H" ;;
 0)	echo "#undef HAS_SENSORS_H" ;;

+ 18 - 6
symon/platform/OpenBSD/platform.h

@@ -1,8 +1,10 @@
-/* $Id: platform.h,v 1.3 2005/10/21 14:58:46 dijkstra Exp $ */
+/* $Id: platform.h,v 1.4 2006/09/10 19:50:29 dijkstra Exp $ */
 
 
 #ifndef _CONF_OPENBSD_H
 #ifndef _CONF_OPENBSD_H
 #define _CONF_OPENBSD_H
 #define _CONF_OPENBSD_H
 
 
+#include "conf.h"
+
 #include <sys/dkstat.h>
 #include <sys/dkstat.h>
 #include <sys/queue.h>
 #include <sys/queue.h>
 #include <sys/types.h>
 #include <sys/types.h>
@@ -17,14 +19,24 @@
 #define SS_LEN(x)       ((x)->ss_len)
 #define SS_LEN(x)       ((x)->ss_len)
 
 
 union stream_parg {
 union stream_parg {
+#ifdef HAS_KERN_CPTIME2
+    struct {
+        int64_t time[CPUSTATES];
+        int64_t old[CPUSTATES];
+        int64_t diff[CPUSTATES];
+        int64_t states[CPUSTATES];
+        int mib[3];
+    } cp;
+#else
     struct {
     struct {
-	long time[CPUSTATES];
-	long old[CPUSTATES];
-	long diff[CPUSTATES];
-	int states[CPUSTATES];
+        long time[CPUSTATES];
+        long old[CPUSTATES];
+        long diff[CPUSTATES];
+        int states[CPUSTATES];
     } cp;
     } cp;
+#endif
     struct {
     struct {
-	char rawdev[SYMON_DFNAMESIZE];
+        char rawdev[SYMON_DFNAMESIZE];
     } df;
     } df;
     struct ifreq ifr;
     struct ifreq ifr;
     int sn;
     int sn;

+ 74 - 34
symon/platform/OpenBSD/sm_cpu.c

@@ -1,4 +1,4 @@
-/* $Id: sm_cpu.c,v 1.21 2005/10/18 19:58:11 dijkstra Exp $ */
+/* $Id: sm_cpu.c,v 1.22 2006/09/10 19:50:29 dijkstra Exp $ */
 
 
 /* The author of this code is Willem Dijkstra (wpd@xs4all.nl).
 /* The author of this code is Willem Dijkstra (wpd@xs4all.nl).
  *
  *
@@ -51,25 +51,27 @@
  *
  *
  * user : nice : system : interrupt : idle
  * user : nice : system : interrupt : idle
  *
  *
- * This code is not re-entrant and UP only.
- *
  * This module uses the sysctl interface and can run as any user.
  * This module uses the sysctl interface and can run as any user.
  */
  */
 
 
+#include "conf.h"
+
 #include <sys/dkstat.h>
 #include <sys/dkstat.h>
 #include <sys/param.h>
 #include <sys/param.h>
 #include <sys/sysctl.h>
 #include <sys/sysctl.h>
 
 
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+
 #include "error.h"
 #include "error.h"
 #include "symon.h"
 #include "symon.h"
 
 
-__BEGIN_DECLS
-int percentages(int, int *, long *, long *, long *);
-__END_DECLS
 
 
 /* Globals for this module all start with cp_ */
 /* Globals for this module all start with cp_ */
-static int cp_time_mib[] = {CTL_KERN, KERN_CPTIME};
 static size_t cp_size;
 static size_t cp_size;
+
 /*
 /*
  *  percentages(cnt, out, new, old, diffs) - calculate percentage change
  *  percentages(cnt, out, new, old, diffs) - calculate percentage change
  *      between array "old" and "new", putting the percentages i "out".
  *      between array "old" and "new", putting the percentages i "out".
@@ -78,40 +80,46 @@ static size_t cp_size;
  *      The routine assumes modulo arithmetic.  This function is especially
  *      The routine assumes modulo arithmetic.  This function is especially
  *      useful on BSD mchines for calculating cpu state percentages.
  *      useful on BSD mchines for calculating cpu state percentages.
  */
  */
+#ifdef HAS_KERN_CPTIME2
+int
+percentages(int cnt, int64_t *out, int64_t *new, int64_t *old, int64_t *diffs)
+{
+	int64_t change, total_change, *dp, half_total;
+#else
+static int cp_time_mib[] = {CTL_KERN, KERN_CPTIME};
 int
 int
 percentages(int cnt, int *out, register long *new, register long *old, long *diffs)
 percentages(int cnt, int *out, register long *new, register long *old, long *diffs)
 {
 {
-    register int i;
-    register long change;
-    register long total_change;
-    register long *dp;
-    long half_total;
-
-    /* initialization */
-    total_change = 0;
-    dp = diffs;
-
-    /* calculate changes for each state and the overall change */
-    for (i = 0; i < cnt; i++) {
-	if ((change = *new - *old) < 0) {
-	    /* this only happens when the counter wraps */
-	    change = ((unsigned int) *new - (unsigned int) *old);
+	long change, total_change, *dp, half_total;
+#endif
+	int i;
+
+
+	/* initialization */
+	total_change = 0;
+	dp = diffs;
+
+	/* calculate changes for each state and the overall change */
+	for (i = 0; i < cnt; i++) {
+		if ((change = *new - *old) < 0) {
+			/* this only happens when the counter wraps */
+			change = (*new - *old);
+		}
+		total_change += (*dp++ = change);
+		*old++ = *new++;
 	}
 	}
-	total_change += (*dp++ = change);
-	*old++ = *new++;
-    }
 
 
-    /* avoid divide by zero potential */
-    if (total_change == 0)
-	total_change = 1;
+	/* avoid divide by zero potential */
+	if (total_change == 0)
+		total_change = 1;
 
 
-    /* calculate percentages based on overall change, rounding up */
-    half_total = total_change / 2l;
-    for (i = 0; i < cnt; i++)
-	*out++ = ((*diffs++ * 1000 + half_total) / total_change);
+	/* calculate percentages based on overall change, rounding up */
+	half_total = total_change / 2l;
+	for (i = 0; i < cnt; i++)
+		*out++ = ((*diffs++ * 1000 + half_total) / total_change);
 
 
-    /* return the total in case the caller wants to use it */
-    return total_change;
+	/* return the total in case the caller wants to use it */
+	return (total_change);
 }
 }
 
 
 void
 void
@@ -119,6 +127,31 @@ init_cpu(struct stream *st)
 {
 {
     char buf[SYMON_MAX_OBJSIZE];
     char buf[SYMON_MAX_OBJSIZE];
 
 
+#ifdef HAS_KERN_CPTIME2
+    const char *errstr;
+    int mib[2] = {CTL_HW, HW_NCPU};
+    int ncpu;
+    long num;
+
+    size_t size = sizeof(ncpu);
+    if (sysctl(mib, 2, &ncpu, &size, NULL, 0) == -1) {
+        warning("could not determine number of cpus: %.200s", strerror(errno));
+        ncpu = 1;
+    }
+
+    num = strtonum(st->arg, 0, SYMON_MAXCPUID-1, &errstr);
+    if (errstr != NULL) {
+        fatal("cpu(%.200s) is invalid: %.200s", st->arg, errstr);
+    }
+
+    st->parg.cp.mib[0] = CTL_KERN;
+    st->parg.cp.mib[1] = KERN_CPTIME2;
+    st->parg.cp.mib[2] = num;
+    if (st->parg.cp.mib[2] >= ncpu) {
+        fatal("cpu(%d) is not present", st->parg.cp.mib[2]);
+    }
+#endif
+
     cp_size = sizeof(st->parg.cp.time);
     cp_size = sizeof(st->parg.cp.time);
     /* Call get_cpu once to fill the cp_old structure */
     /* Call get_cpu once to fill the cp_old structure */
     get_cpu(buf, sizeof(buf), st);
     get_cpu(buf, sizeof(buf), st);
@@ -136,10 +169,17 @@ get_cpu(char *symon_buf, int maxlen, struct stream *st)
 {
 {
     int total;
     int total;
 
 
+#ifdef HAS_KERN_CPTIME2
+    if (sysctl(st->parg.cp.mib, 3, &st->parg.cp.time, &cp_size, NULL, 0) < 0) {
+        warning("%s:%d: sysctl kern.cp_time2 for cpu%d failed", __FILE__, __LINE__, st->parg.cp.mib[2]);
+        return 0;
+    }
+#else
     if (sysctl(cp_time_mib, 2, &st->parg.cp.time, &cp_size, NULL, 0) < 0) {
     if (sysctl(cp_time_mib, 2, &st->parg.cp.time, &cp_size, NULL, 0) < 0) {
 	warning("%s:%d: sysctl kern.cp_time failed", __FILE__, __LINE__);
 	warning("%s:%d: sysctl kern.cp_time failed", __FILE__, __LINE__);
 	return 0;
 	return 0;
     }
     }
+#endif
 
 
     /* convert cp_time counts to percentages */
     /* convert cp_time counts to percentages */
     total = percentages(CPUSTATES, st->parg.cp.states, st->parg.cp.time, st->parg.cp.old, st->parg.cp.diff);
     total = percentages(CPUSTATES, st->parg.cp.states, st->parg.cp.time, st->parg.cp.old, st->parg.cp.diff);

+ 2 - 1
symon/platform/OpenBSD/sm_mbuf.c

@@ -1,4 +1,4 @@
-/* $Id: sm_mbuf.c,v 1.6 2005/10/18 19:58:11 dijkstra Exp $ */
+/* $Id: sm_mbuf.c,v 1.7 2006/09/10 19:50:29 dijkstra Exp $ */
 
 
 /*
 /*
  * Copyright (c) 2003 Daniel Hartmeier
  * Copyright (c) 2003 Daniel Hartmeier
@@ -35,6 +35,7 @@
 #include <sys/sysctl.h>
 #include <sys/sysctl.h>
 #include <sys/errno.h>
 #include <sys/errno.h>
 
 
+#include <errno.h>
 #include <string.h>
 #include <string.h>
 #include <unistd.h>
 #include <unistd.h>
 
 

+ 6 - 1
symon/platform/OpenBSD/sm_pf.c

@@ -1,4 +1,4 @@
-/* $Id: sm_pf.c,v 1.11 2005/10/18 19:58:11 dijkstra Exp $ */
+/* $Id: sm_pf.c,v 1.12 2006/11/07 08:00:20 dijkstra Exp $ */
 
 
 /*
 /*
  * Copyright (c) 2002 Daniel Hartmeier
  * Copyright (c) 2002 Daniel Hartmeier
@@ -77,6 +77,11 @@ get_pf(char *symon_buf, int maxlen, struct stream *st)
     fatal("pf support not available");
     fatal("pf support not available");
     return 0;
     return 0;
 }
 }
+void
+gets_pf()
+{
+    fatal("pf support not available");
+}
 
 
 #else
 #else
 
 

+ 2 - 2
symon/symon/Makefile

@@ -1,8 +1,8 @@
-# $Id: Makefile,v 1.39 2005/03/20 16:17:22 dijkstra Exp $
+# $Id: Makefile,v 1.40 2006/12/19 22:31:47 dijkstra Exp $
 .include "../Makefile.inc"
 .include "../Makefile.inc"
 .include "../platform/${OS}/Makefile.inc"
 .include "../platform/${OS}/Makefile.inc"
 
 
-LIBS+=	-L../lib -lsymon
+LIBS+=	${SYMON_LIBS} -L../lib -lsymon
 MODS!=	( for g in ../platform/stub/sm_*.c; do \
 MODS!=	( for g in ../platform/stub/sm_*.c; do \
 		f=../platform/${OS}/`basename $$g`; \
 		f=../platform/${OS}/`basename $$g`; \
 		if [ -f $$f ]; then echo $$f; \
 		if [ -f $$f ]; then echo $$f; \

+ 11 - 13
symon/symon/symon.c

@@ -1,4 +1,4 @@
-/* $Id: symon.c,v 1.43 2005/10/16 15:27:01 dijkstra Exp $ */
+/* $Id: symon.c,v 1.45 2006/09/22 07:13:19 dijkstra Exp $ */
 
 
 /*
 /*
  * Copyright (c) 2001-2005 Willem Dijkstra
  * Copyright (c) 2001-2005 Willem Dijkstra
@@ -273,7 +273,7 @@ main(int argc, char *argv[])
 
 
     last_update = time(NULL);
     last_update = time(NULL);
     for (;;) {			/* FOREVER */
     for (;;) {			/* FOREVER */
-	sleep(symon_interval);	/* alarm will interrupt sleep */
+	sleep(symon_interval * 2);	/* alarm will interrupt sleep */
 	now = time(NULL);
 	now = time(NULL);
 
 
 	if (flag_hup == 1) {
 	if (flag_hup == 1) {
@@ -304,17 +304,15 @@ main(int argc, char *argv[])
 	    }
 	    }
 	} else {
 	} else {
 	    /* check timing to catch ntp drifts */
 	    /* check timing to catch ntp drifts */
-	    if (now < (last_update + symon_interval)) {
-		if (now < (last_update + symon_interval + symon_interval)) {
-		    debug("last update is very long ago - assuming that system time changed");
-		    last_update = now;
-		} else {
-		    debug("did not sleep %d seconds - skipping a measurement", symon_interval);
-		    continue;
-		}
-	    } else {
-		last_update = now;
-	    }
+            if (now < last_update ||
+                now > last_update + symon_interval + symon_interval) {
+                info("last update seems long ago - assuming system time change");
+                last_update = now;
+            } else if (now < last_update + symon_interval) {
+                debug("did not sleep %d seconds - skipping a measurement", symon_interval);
+                continue;
+            }
+            last_update = now;
 
 
 	    /* populate for modules that get all their measurements in one go */
 	    /* populate for modules that get all their measurements in one go */
 	    for (i = 0; i < MT_EOT; i++)
 	    for (i = 0; i < MT_EOT; i++)

+ 2 - 2
symon/symux/Makefile

@@ -1,10 +1,10 @@
-# $Id: Makefile,v 1.23 2005/03/20 16:17:22 dijkstra Exp $
+# $Id: Makefile,v 1.24 2006/12/19 22:30:47 dijkstra Exp $
 .include "../Makefile.inc"
 .include "../Makefile.inc"
 .include "../platform/${OS}/Makefile.inc"
 .include "../platform/${OS}/Makefile.inc"
 
 
 SRCS=	symux.c readconf.c symuxnet.c share.c
 SRCS=	symux.c readconf.c symuxnet.c share.c
 OBJS+=	${SRCS:R:S/$/.o/g}
 OBJS+=	${SRCS:R:S/$/.o/g}
-LIBS+=  -L../lib -L$(RRDDIR)/lib -lsymon -lrrd
+LIBS+=  ${SYMUX_LIBS} -L../lib -L$(RRDDIR)/lib -lsymon -lrrd
 CFLAGS+=-I../lib -I$(RRDDIR)/include -I../platform/${OS} -I.
 CFLAGS+=-I../lib -I$(RRDDIR)/include -I../platform/${OS} -I.
 
 
 all: symux symux.cat8
 all: symux symux.cat8

+ 40 - 142
symon/symux/c_smrrds.sh

@@ -1,8 +1,8 @@
 #!/bin/sh
 #!/bin/sh
-# $Id: c_smrrds.sh,v 1.32 2005/10/18 19:58:13 dijkstra Exp $
+# $Id: c_smrrds.sh,v 1.35 2006/12/19 22:30:47 dijkstra Exp $
 
 
 #
 #
-# Copyright (c) 2001-2005 Willem Dijkstra
+# Copyright (c) 2001-2006 Willem Dijkstra
 # All rights reserved.
 # All rights reserved.
 #
 #
 # Redistribution and use in source and binary forms, with or without
 # Redistribution and use in source and binary forms, with or without
@@ -31,19 +31,25 @@
 
 
 # --- user configuration starts here
 # --- user configuration starts here
 INTERVAL=${INTERVAL:-5}
 INTERVAL=${INTERVAL:-5}
+# default RRA setup:
+# - 2   days of  5 second  samples = 34560 x 5 second samples
+# - 14  days of 30 minutes samples = 672 x 360 x 5 second samples
+# - 50  days of  2 hour    samples = 600 x 1440 x 5 second samples
+# - 600 days of  1 day     samples = 600 x 17280 x 5 second samples
+RRA_SETUP=${RRA_SETUP:-"
+	    RRA:AVERAGE:0.5:1:34560
+	    RRA:AVERAGE:0.5:360:672
+	    RRA:AVERAGE:0.5:1440:600
+	    RRA:AVERAGE:0.5:17280:600
+	    RRA:MAX:0.5:1:34560
+	    RRA:MAX:0.5:360:672
+	    RRA:MAX:0.5:1440:600
+	    RRA:MAX:0.5:17280:600
+	    RRA:MIN:0.5:1:34560
+	    RRA:MIN:0.5:360:672
+	    RRA:MIN:0.5:1440:600
+	    RRA:MIN:0.5:17280:600"}
 # --- user configuration ends here
 # --- user configuration ends here
-OS=`uname -s`
-# addsuffix adds a suffix to each entry of a list (item|item|...)
-addsuffix() {
-    list=$1'|'
-    suffix=$2
-    while [ `echo $list | grep '|'` ]; do
-	newlist=$newlist'|'`echo $list | cut -f1 -d\|`$suffix
-	list=`echo $list | cut -f2- -d\|`
-    done
-    echo $newlist | cut -b2-
-}
-
 create_rrd() {
 create_rrd() {
     file=$1
     file=$1
     shift
     shift
@@ -88,147 +94,39 @@ oneday)
 esac
 esac
 done
 done
 
 
-if [ X"$RRA_SETUP" = "X" ]; then
-# default RRA setup:
-# - 2   days of  5 second  samples = 34560 x 5 second samples
-# - 14  days of 30 minutes samples = 672 x 360 x 5 second samples
-# - 50  days of  2 hour    samples = 600 x 1440 x 5 second samples
-# - 600 days of  1 day     samples = 600 x 17280 x 5 second samples
-RRA_SETUP=" RRA:AVERAGE:0.5:1:34560
-	    RRA:AVERAGE:0.5:360:672
-	    RRA:AVERAGE:0.5:1440:600
-	    RRA:AVERAGE:0.5:17280:600
-	    RRA:MAX:0.5:1:34560
-	    RRA:MAX:0.5:360:672
-	    RRA:MAX:0.5:1440:600
-	    RRA:MAX:0.5:17280:600
-	    RRA:MIN:0.5:1:34560
-	    RRA:MIN:0.5:360:672
-	    RRA:MIN:0.5:1440:600
-	    RRA:MIN:0.5:17280:600"
-fi
-
-# All interfaces and disks
-case ${OS} in
-FreeBSD)
-	DISKS="ad|acd|afd|ast|sa|da|ar|cd|ch|md"
-	INTERFACES="an|ar|ath|aue|awi|axe|bfe|bge|cm|cnw|cs|cue|dc|de|ed|el|em|ep|ex|fe|fwe|fxp|gem|gx|hme|ie|kue|lge|lnc|my|nge|pcn|ray|re|rl|rue|sf|sis|sk|sn|snc|ste|ti|tl|tx|txp|vge|vr|vx|wb|wi|xe|xl";
-	VIRTUALINTERFACES="bridge|carp|enc|faith|gif|ppp|sl|sppp|strip|tun|vlan";
-	diskcmd="mount | sed -n '/^\/dev/ s,/dev/\([a-z]*[0-9]\).*,\1,p' | sort -u"
-	interfacecmd="ifconfig -l | sed 's/lo0//'"
-	;;
-Linux)
-	DISKS="hda|hdb|hdc|hdd|sda|sdb|sdc|sdd"
-	INTERFACES="eth"
-	VIRTUALINTERFACES="sit"
-	diskcmd="mount | sed -n '/^\/dev/ s,/dev/\([a-z]*[0-9]\).*,\1,p' | sort -u"
-	interfacecmd="ifconfig -a| egrep -e \"^(\$INTERFACES) \" | cut -f1 -d\  | sort -u"
-	;;
-OpenBSD)
-	DISKS="sd|cd|ch|rd|raid|ss|uk|vnc|wd"
-	INTERFACES="an|ath|awi|be|bge|bm|cnw|dc|de|ec|ef|eg|el|em|ep|ex|fea|fpa|fxp|gem|gm|gre|hme|ie|kue|lc|le|lge|lmc|lo|ne|nge|ray|rl|qe|sf|sis|sk|sl|sm|ste|stge|ti|tl|tr|tx|txp|vme|vr|wb|we|wi|wx|xe|xl"
-	VIRTUALINTERFACES="bridge|carp|enc|faith|gif|ppp|sppp|strip|tun|vlan";
-	diskcmd="mount | sed -n '/^\/dev/ s,/dev/\([a-z]*[0-9]\).*,\1,p' | sort -u"
-	partcmd="grep ffs /etc/fstab | sed -n '/^\/dev/ s,/dev/\([a-z]*[0-9]*[a-z]*\).*,\1,p' | sort -u"
-	interfacecmd="ifconfig -a| egrep -e \"^(\$INTERFACES):\" | cut -f1 -d\:  | sort -u"
-	;;
-NetBSD)
-	DISKS="sd|cd|ch|rd|raid|ss|uk|vnc|wd"
-	INTERFACES="ai|an|ate|ath|atw|awi|bce|bge|bicc|cnw|com|cs|depca|ec|ef|eg|el|elmc|en|ep|epic|esh|ex|fea|fmv|fpa|fxp|gsip|hme|ipw|iwi|ix|iy|lc|le|lmc|mbe|mhzc|mtd|ne|nele|ntwoc|pcn|ray|re|rtk|sf|sip|sk|skc|sm|ste|stge|ti|tl|tlp|tr|vge|vr|we|wi|wm|xi|xirc"
-	VIRTUALINTERFACES="bridge|carp|enc|faith|gif|ppp|sppp|sl|strip|tun|vlan";
-	diskcmd="mount | sed -n '/^\/dev/ s,/dev/\([a-z]*[0-9]\).*,\1,p' | sort -u"
-	interfacecmd="ifconfig -l | sed 's/lo0//'"
-	;;
-esac
-DISKS=`addsuffix $DISKS [0-9]`
-INTERFACES=`addsuffix $INTERFACES [0-9]`
-VIRTUALINTERFACES=`addsuffix $VIRTUALINTERFACES \\.\\*`
-
 this=$0
 this=$0
 if [ X"$1$2$3$4$5$6$7$8$9" = "X" ]; then
 if [ X"$1$2$3$4$5$6$7$8$9" = "X" ]; then
     cat <<EOF
     cat <<EOF
 Create rrd files for symux.
 Create rrd files for symux.
 
 
-Usage: `basename $0` [oneday] [interval <seconds>] all | cpu0 | mem |
-		   pf | pfq_<queue> | mbuf | debug | proc_<process> |
-		   <if> | <io> | sensor[0-25]
+Usage: `basename $0` [oneday] [interval <seconds>] [all] \
+		     <rrd files>
 
 
 Where:
 Where:
-oneday  = modify rrds to only contain one day of information
-seconds = modify rrds for non standard monitoring interval
-process = the name of a process as specified in sy{mon,mux}.conf
-	  e.g. proc(httpd) -> proc_httpd
-queue = the name of a queue as specified in sy{mon,mux}.conf
-	  e.g. pfq(root) -> pfq_root
-
-if=	`echo $INTERFACES|
-   awk 'BEGIN  {FS="|"}
-	   {for (i=1; i<=NF; i++) {
-	       printf("%s|",$i);
-	       if ((i%6)==0) {
-		  printf("%s","\n\t")
-	       }
-	   }
-	   print " ";}'`
-io=	`echo $DISKS|
-   awk 'BEGIN  {FS="|"}
-		{for (i=1; i<=NF; i++) {
-		    printf("%s|",$i);
-		    if ((i%6)==0) {
-			printf("%s","\n\t")
-		    }
-		}
-		print " ";}'`
-
-OpenBSD pre-3.5 disk statistics are available via the io1_<disk> argument.
+oneday       = modify rrds to only contain one day of information
+seconds      = modify rrds for non standard monitoring interval
+all          = run symux -l to determine current configured rrd
+	       files
+<rrd files>  = files ending in rrd that follow symux naming
 EOF
 EOF
     exit 1;
     exit 1;
 fi
 fi
 
 
+RRD_ARGS="--step=$INTERVAL --start=0"
+
 for i in $args
 for i in $args
 do
 do
-# add if_*.rrd if it is an interface
-if [ `echo $i | egrep -e "^($INTERFACES)$"` ]; then i=if_$i.rrd; fi
-if [ `echo $i | egrep -e "^($VIRTUALINTERFACES)$"` ]; then i=if_$i.rrd; fi
-# add io_*.rrd if it is a disk
-if [ `echo $i | egrep -e "^($DISKS)$"` ]; then i=io_$i.rrd; fi
-# add io_*.rrd if it is a disk
-if [ `echo $i | egrep -e "^($DISKS)[a-z]$"` ]; then i=df_$i.rrd; fi
-# add .rrd if it is a cpu, etc.
-if [ `echo $i | egrep -e "^(cpu[0-9]$|mem$|pf$|pfq_|mbuf$|debug$|proc_|sensor[0-9]$|sensor[0-9][0-9]$|io1_)"` ]; then i=$i.rrd; fi
 
 
 if [ -f $i ]; then
 if [ -f $i ]; then
     echo "$i exists - ignoring"
     echo "$i exists - ignoring"
     i="done"
     i="done"
 fi
 fi
 
 
-RRD_ARGS="--step=$INTERVAL --start=0"
-
-case $i in
+j=`basename $i`
+case $j in
 
 
 all)
 all)
-    echo "Creating rrd files for {cpu0|df|mem|disks|interfaces|pf|mbuf}"
-    sh $this interval $INTERVAL child $config cpu0 mem
-    sh $this interval $INTERVAL child $config interfaces
-    sh $this interval $INTERVAL child $config disks
-    sh $this interval $INTERVAL child $config pf
-    sh $this interval $INTERVAL child $config mbuf
-    sh $this interval $INTERVAL child $config df
-    ;;
-
-if|interfaces)
-    # obtain all network cards
-    sh $this child $config `eval $interfacecmd`
-    ;;
-
-io|disks)
-    # obtain all disks
-    sh $this child $config `eval $diskcmd`
-    ;;
-
-df)
-    # obtain all ffs partitions
-    sh $this child $config `eval $partcmd`
+    sh $this interval $INTERVAL child $config `symux -l`
     ;;
     ;;
 
 
 cpu[0-9].rrd)
 cpu[0-9].rrd)
@@ -324,13 +222,13 @@ pf.rrd)
     ;;
     ;;
 
 
 pfq_*.rrd)
 pfq_*.rrd)
-	# Build pfq file
-	create_rrd $i \
-	    DS:sent_bytes:COUNTER:$INTERVAL:0:U \
-	    DS:sent_packets:COUNTER:$INTERVAL:0:U \
-	    DS:drop_bytes:COUNTER:$INTERVAL:0:U \
-	    DS:drop_packets:COUNTER:$INTERVAL:0:U
-	;;
+    # Build pfq file
+    create_rrd $i \
+	DS:sent_bytes:COUNTER:$INTERVAL:0:U \
+	DS:sent_packets:COUNTER:$INTERVAL:0:U \
+	DS:drop_bytes:COUNTER:$INTERVAL:0:U \
+	DS:drop_packets:COUNTER:$INTERVAL:0:U
+    ;;
 
 
 mbuf.rrd)
 mbuf.rrd)
     # Build mbuf file
     # Build mbuf file
@@ -368,7 +266,7 @@ io1_*.rrd)
     ;;
     ;;
 *)
 *)
     # Default match
     # Default match
-    echo $i - unknown
+    echo $i - cannot determine filetype from filename
     ;;
     ;;
 esac
 esac
 done
 done

+ 54 - 45
symon/symux/readconf.c

@@ -1,4 +1,4 @@
-/* $Id: readconf.c,v 1.28 2005/10/16 15:27:03 dijkstra Exp $ */
+/* $Id: readconf.c,v 1.29 2006/12/19 22:30:48 dijkstra Exp $ */
 
 
 /*
 /*
  * Copyright (c) 2001-2005 Willem Dijkstra
  * Copyright (c) 2001-2005 Willem Dijkstra
@@ -46,7 +46,7 @@
 
 
 __BEGIN_DECLS
 __BEGIN_DECLS
 int read_mux(struct muxlist * mul, struct lex *);
 int read_mux(struct muxlist * mul, struct lex *);
-int read_source(struct sourcelist * sol, struct lex *);
+int read_source(struct sourcelist * sol, struct lex *, int);
 int insert_filename(char *, int, int, char *);
 int insert_filename(char *, int, int, char *);
 __END_DECLS
 __END_DECLS
 
 
@@ -163,12 +163,11 @@ read_mux(struct muxlist * mul, struct lex * l)
     if (rename_mux(mul, mux, muxname) == NULL)
     if (rename_mux(mul, mux, muxname) == NULL)
 	fatal("%s:%d: internal error: dual mux", __FILE__, __LINE__);
 	fatal("%s:%d: internal error: dual mux", __FILE__, __LINE__);
 
 
-
     return 1;
     return 1;
 }
 }
 /* source <host> { accept ... | write ... | datadir ... } */
 /* source <host> { accept ... | write ... | datadir ... } */
 int
 int
-read_source(struct sourcelist * sol, struct lex * l)
+read_source(struct sourcelist * sol, struct lex * l, int filecheck)
 {
 {
     struct source *source;
     struct source *source;
     struct stream *stream;
     struct stream *stream;
@@ -268,20 +267,22 @@ read_source(struct sourcelist * sol, struct lex * l)
 		return 0;
 		return 0;
 	    }
 	    }
 
 
-	    /* make sure that directory exists */
-	    bzero(&sb, sizeof(struct stat));
-
-	    if (stat(l->token, &sb) == 0) {
-		if (!(sb.st_mode & S_IFDIR)) {
-		    warning("%.200s:%d: datadir path '%.200s' is not a directory",
-			    l->filename, l->cline, l->token);
-		    return 0;
-		}
-	    } else {
-		warning("%.200s:%d: could not stat datadir path '%.200s'",
-			l->filename, l->cline, l->token);
-		return 0;
-	    }
+            if (filecheck) {
+                /* make sure that directory exists */
+                bzero(&sb, sizeof(struct stat));
+
+                if (stat(l->token, &sb) == 0) {
+                    if (!(sb.st_mode & S_IFDIR)) {
+                        warning("%.200s:%d: datadir path '%.200s' is not a directory",
+                                l->filename, l->cline, l->token);
+                        return 0;
+                    }
+                } else {
+                    warning("%.200s:%d: could not stat datadir path '%.200s'",
+                            l->filename, l->cline, l->token);
+                    return 0;
+                }
+            }
 
 
 	    strncpy(&path[0], l->token, _POSIX2_LINE_MAX);
 	    strncpy(&path[0], l->token, _POSIX2_LINE_MAX);
 	    path[_POSIX2_LINE_MAX - 1] = '\0';
 	    path[_POSIX2_LINE_MAX - 1] = '\0';
@@ -316,15 +317,19 @@ read_source(struct sourcelist * sol, struct lex * l)
 			return 0;
 			return 0;
 		    }
 		    }
 
 
-		    /* try filename */
-		    if ((fd = open(path, O_RDWR | O_NONBLOCK, 0)) == -1) {
-			/* warn, but allow */
-			warning("%.200s:%d: file '%.200s', guessed by datadir,  cannot be opened",
-				l->filename, l->cline, path);
-		    } else {
-			close(fd);
-			stream->file = xstrdup(path);
-		    }
+                    if (filecheck) {
+                        /* try filename */
+                        if ((fd = open(path, O_RDWR | O_NONBLOCK, 0)) == -1) {
+                            /* warn, but allow */
+                            warning("%.200s:%d: file '%.200s', guessed by datadir,  cannot be opened",
+                                    l->filename, l->cline, path);
+                        } else {
+                            close(fd);
+                            stream->file = xstrdup(path);
+                        }
+                    } else {
+                        stream->file = xstrdup(path);
+                    }
 		}
 		}
 	    }
 	    }
 	    break;		/* LXT_DATADIR */
 	    break;		/* LXT_DATADIR */
@@ -382,22 +387,26 @@ read_source(struct sourcelist * sol, struct lex * l)
 			return 0;
 			return 0;
 		    }
 		    }
 		} else {
 		} else {
-		    /* try filename */
-		    if ((fd = open(l->token, O_RDWR | O_NONBLOCK, 0)) == -1) {
-			warning("%.200s:%d: file '%.200s' cannot be opened",
-				l->filename, l->cline, l->token);
-			return 0;
-		    } else {
-			close(fd);
-
-			if (stream->file != NULL) {
-			    warning("%.200s:%d: file '%.200s' overwrites previous definition '%.200s'",
-			     l->filename, l->cline, l->token, stream->file);
-			    xfree(stream->file);
-			}
-
-			stream->file = xstrdup(l->token);
-		    }
+                    if (filecheck) {
+                        /* try filename */
+                        if ((fd = open(l->token, O_RDWR | O_NONBLOCK, 0)) == -1) {
+                            warning("%.200s:%d: file '%.200s' cannot be opened",
+                                    l->filename, l->cline, l->token);
+                            return 0;
+                        } else {
+                            close(fd);
+
+                            if (stream->file != NULL) {
+                                warning("%.200s:%d: file '%.200s' overwrites previous definition '%.200s'",
+                                        l->filename, l->cline, l->token, stream->file);
+                                xfree(stream->file);
+                            }
+
+                            stream->file = xstrdup(l->token);
+                        }
+                    } else {
+                        stream->file = xstrdup(l->token);
+                    }
 		}
 		}
 		break;		/* LXT_CPU/IF/IO/IO1/MEM/PF/PFQ/MBUF/DEBUG/PROC/SENSOR */
 		break;		/* LXT_CPU/IF/IO/IO1/MEM/PF/PFQ/MBUF/DEBUG/PROC/SENSOR */
 	    default:
 	    default:
@@ -421,7 +430,7 @@ read_source(struct sourcelist * sol, struct lex * l)
 }
 }
 /* Read symux.conf */
 /* Read symux.conf */
 int
 int
-read_config_file(struct muxlist * mul, const char *filename)
+read_config_file(struct muxlist * mul, const char *filename, int filechecks)
 {
 {
     struct lex *l;
     struct lex *l;
     struct source *source;
     struct source *source;
@@ -444,7 +453,7 @@ read_config_file(struct muxlist * mul, const char *filename)
 	    }
 	    }
 	    break;
 	    break;
 	case LXT_SOURCE:
 	case LXT_SOURCE:
-	    if (!read_source(&sol, l)) {
+	    if (!read_source(&sol, l, filechecks)) {
 		free_sourcelist(&sol);
 		free_sourcelist(&sol);
 		return 0;
 		return 0;
 	    }
 	    }

+ 2 - 2
symon/symux/readconf.h

@@ -1,4 +1,4 @@
-/* $Id: readconf.h,v 1.8 2004/02/26 22:48:08 dijkstra Exp $ */
+/* $Id: readconf.h,v 1.9 2006/12/19 22:30:48 dijkstra Exp $ */
 
 
 /*
 /*
  * Copyright (c) 2001-2004 Willem Dijkstra
  * Copyright (c) 2001-2004 Willem Dijkstra
@@ -37,7 +37,7 @@
 #include "data.h"
 #include "data.h"
 
 
 __BEGIN_DECLS
 __BEGIN_DECLS
-int read_config_file(struct muxlist *, const char *);
+int read_config_file(struct muxlist *, const char *, int);
 __END_DECLS
 __END_DECLS
 
 
 #endif				/* _SYMUX_READCONF_H */
 #endif				/* _SYMUX_READCONF_H */

+ 5 - 3
symon/symux/symux.8

@@ -35,7 +35,7 @@
 .Nd symon stream multiplexer
 .Nd symon stream multiplexer
 .Sh SYNOPSIS
 .Sh SYNOPSIS
 .Nm
 .Nm
-.Op Fl vd
+.Op Fl dlv
 .Op Fl f Ar filename
 .Op Fl f Ar filename
 .Pp
 .Pp
 .Sh DESCRIPTION
 .Sh DESCRIPTION
@@ -71,8 +71,6 @@ the rrd files. It should be run as
 .Lp
 .Lp
 The options:
 The options:
 .Bl -tag -width Ds
 .Bl -tag -width Ds
-.It Fl v
-Show version.
 .It Fl d
 .It Fl d
 Stop
 Stop
 .Nm
 .Nm
@@ -84,6 +82,10 @@ Read configuration from
 .Ar filename
 .Ar filename
 instead of
 instead of
 .Pa /etc/symux.conf .
 .Pa /etc/symux.conf .
+.It Fl l
+List rrd files found in active configuration.
+.It Fl v
+Show version.
 .El
 .El
 .Sh CONFIGURATION
 .Sh CONFIGURATION
 .Nm
 .Nm

+ 208 - 159
symon/symux/symux.c

@@ -1,7 +1,7 @@
-/* $Id: symux.c,v 1.34 2005/10/16 15:27:03 dijkstra Exp $ */
+/* $Id: symux.c,v 1.36 2006/12/19 22:30:48 dijkstra Exp $ */
 
 
 /*
 /*
- * Copyright (c) 2001-2004 Willem Dijkstra
+ * Copyright (c) 2001-2006 Willem Dijkstra
  * All rights reserved.
  * All rights reserved.
  *
  *
  * Redistribution and use in source and binary forms, with or without
  * Redistribution and use in source and binary forms, with or without
@@ -108,11 +108,15 @@ main(int argc, char *argv[])
     char *arg_ra[4];
     char *arg_ra[4];
     struct stream *stream;
     struct stream *stream;
     struct source *source;
     struct source *source;
+    struct sourcelist *sol;
     struct mux *mux;
     struct mux *mux;
     FILE *f;
     FILE *f;
     int ch;
     int ch;
     int churnbuflen;
     int churnbuflen;
+    int flag_list;
     int offset;
     int offset;
+    int result;
+    unsigned int rrderrors;
     int slot;
     int slot;
     time_t timestamp;
     time_t timestamp;
 
 
@@ -121,67 +125,105 @@ main(int argc, char *argv[])
     /* reset flags */
     /* reset flags */
     flag_debug = 0;
     flag_debug = 0;
     flag_daemon = 0;
     flag_daemon = 0;
+    flag_list = 0;
+
     cfgfile = SYMUX_CONFIG_FILE;
     cfgfile = SYMUX_CONFIG_FILE;
 
 
-    while ((ch = getopt(argc, argv, "dvf:")) != -1) {
-	switch (ch) {
-	case 'd':
-	    flag_debug = 1;
-	    break;
-	case 'f':
-	    if (optarg && optarg[0] != '/') {
-		/* cfg path needs to be absolute, we will be a daemon soon */
-		cfgpath = xmalloc(MAXPATHLEN);
-		if ((cfgpath = getcwd(cfgpath, MAXPATHLEN)) == NULL)
-		    fatal("could not get working directory");
-
-		maxstringlen = strlen(cfgpath) + strlen(optarg) + 1;
-		cfgfile = xmalloc(maxstringlen);
-		strncpy(cfgfile, cfgpath, maxstringlen);
-		stringptr = cfgfile + strlen(cfgpath);
-		stringptr[0] = '/';
-		stringptr++;
-		strncpy(stringptr, optarg, maxstringlen - (cfgfile - stringptr));
-		cfgfile[maxstringlen] = '\0';
-
-		free(cfgpath);
-	    } else
-		cfgfile = xstrdup(optarg);
-
-	    break;
-	case 'v':
-	    info("symux version %s", SYMUX_VERSION);
-	default:
-	    info("usage: %s [-d] [-v] [-f cfgfile]", __progname);
-	    exit(EX_USAGE);
-	}
+    while ((ch = getopt(argc, argv, "df:lv")) != -1) {
+        switch (ch) {
+        case 'd':
+            flag_debug = 1;
+            break;
+        case 'f':
+            if (optarg && optarg[0] != '/') {
+                /* cfg path needs to be absolute, we will be a daemon soon */
+                cfgpath = xmalloc(MAXPATHLEN);
+                if ((cfgpath = getcwd(cfgpath, MAXPATHLEN)) == NULL)
+                    fatal("could not get working directory");
+
+                maxstringlen = strlen(cfgpath) + strlen(optarg) + 1;
+                cfgfile = xmalloc(maxstringlen);
+                strncpy(cfgfile, cfgpath, maxstringlen);
+                stringptr = cfgfile + strlen(cfgpath);
+                stringptr[0] = '/';
+                stringptr++;
+                strncpy(stringptr, optarg, maxstringlen - (cfgfile - stringptr));
+                cfgfile[maxstringlen] = '\0';
+
+                free(cfgpath);
+            } else
+                cfgfile = xstrdup(optarg);
+
+            break;
+        case 'l':
+            flag_list = 1;
+            break;
+        case 'v':
+            info("symux version %s", SYMUX_VERSION);
+        default:
+            info("usage: %s [-d] [-l] [-v] [-f cfgfile]", __progname);
+            exit(EX_USAGE);
+        }
+    }
+
+    if (flag_list == 1) {
+        /* read configuration without file checks */
+        result = read_config_file(&mul, cfgfile, 0);
+        if (!result) {
+            fatal("configuration contained errors; quitting");
+        }
+
+        mux = SLIST_FIRST(&mul);
+        if (mux == NULL) {
+            fatal("%s:%d: mux not found", __FILE__, __LINE__);
+        }
+
+        sol = &mux->sol;
+
+        if (sol == NULL) {
+            fatal("%s:%d: sourcelist not found", __FILE__, __LINE__);
+        }
+
+        SLIST_FOREACH(source, sol, sources) {
+            if (! SLIST_EMPTY(&source->sl)) {
+                SLIST_FOREACH(stream, &source->sl, streams) {
+                    if (stream->file != NULL) {
+                        info("%.200s", stream->file);
+                    }
+                }
+            }
+        }
+        return (EX_OK);
+    } else {
+        /* read configuration file with file access checks */
+        result = read_config_file(&mul, cfgfile, 1);
+        if (!result) {
+            fatal("configuration contained errors; quitting");
+        }
     }
     }
 
 
-    /* parse configuration file */
-    if (!read_config_file(&mul, cfgfile))
-	fatal("configuration contained errors; quitting");
 
 
     setegid(getgid());
     setegid(getgid());
     setgid(getgid());
     setgid(getgid());
 
 
     if (flag_debug != 1) {
     if (flag_debug != 1) {
-	if (daemon(0, 0) != 0)
-	    fatal("daemonize failed");
+        if (daemon(0, 0) != 0)
+            fatal("daemonize failed");
 
 
-	flag_daemon = 1;
+        flag_daemon = 1;
 
 
-	/* record pid */
-	f = fopen(SYMUX_PID_FILE, "w");
-	if (f) {
-	    fprintf(f, "%u\n", (u_int) getpid());
-	    fclose(f);
-	}
+        /* record pid */
+        f = fopen(SYMUX_PID_FILE, "w");
+        if (f) {
+            fprintf(f, "%u\n", (u_int) getpid());
+            fclose(f);
+        }
     }
     }
 
 
     info("symux version %s", SYMUX_VERSION);
     info("symux version %s", SYMUX_VERSION);
 
 
     if (flag_debug == 1)
     if (flag_debug == 1)
-	info("program id=%d", (u_int) getpid());
+        info("program id=%d", (u_int) getpid());
 
 
     mux = SLIST_FIRST(&mul);
     mux = SLIST_FIRST(&mul);
 
 
@@ -201,121 +243,128 @@ main(int argc, char *argv[])
 
 
     /* prepare sockets */
     /* prepare sockets */
     if (get_symon_sockets(mux) == 0)
     if (get_symon_sockets(mux) == 0)
-	fatal("no sockets could be opened for incoming symon traffic");
+        fatal("no sockets could be opened for incoming symon traffic");
     if (get_client_socket(mux) == 0)
     if (get_client_socket(mux) == 0)
-	fatal("socket for client connections could not be opened");
+        fatal("socket for client connections could not be opened");
 
 
+    rrderrors = 0;
     /* main loop */
     /* main loop */
-    for (;;) {			/* FOREVER */
-	wait_for_traffic(mux, &source, &packet);
-
-	if (flag_hup == 1) {
-	    flag_hup = 0;
-
-	    SLIST_INIT(&newmul);
-
-	    if (!read_config_file(&newmul, cfgfile)) {
-		info("new configuration contains errors; keeping old configuration");
-		free_muxlist(&newmul);
-	    } else {
-		info("read configuration file '%.100s' successfully", cfgfile);
-		free_muxlist(&mul);
-		mul = newmul;
-		mux = SLIST_FIRST(&mul);
-		get_symon_sockets(mux);
-		get_client_socket(mux);
-	    }
-	} else {
-
-	    /*
-	     * Put information from packet into stringbuf (shared region).
-	     * Note that the stringbuf is used twice: 1) to update the
-	     * rrdfile and 2) to collect all the data from a single packet
-	     * that needs to shared to the clients. This is the reason for
-	     * the hasseling with stringptr.
-	     */
-
-	    offset = mux->offset;
-	    maxstringlen = shared_getmaxlen();
-	    /* put time:ip: into shared region */
-	    slot = master_forbidread();
-	    timestamp = (time_t) packet.header.timestamp;
-	    stringbuf = shared_getmem(slot);
-	    debug("stringbuf = 0x%8x", stringbuf);
-	    snprintf(stringbuf, maxstringlen, "%s;", source->addr);
-
-	    /* hide this string region from rrd update */
-	    maxstringlen -= strlen(stringbuf);
-	    stringptr = stringbuf + strlen(stringbuf);
-
-	    while (offset < packet.header.length) {
-		bzero(&ps, sizeof(struct packedstream));
-		offset += sunpack(packet.data + offset, &ps);
-
-		/* find stream in source */
-		stream = find_source_stream(source, ps.type, ps.arg);
-
-		if (stream != NULL) {
-		    /* put type and arg in and hide from rrd */
-		    snprintf(stringptr, maxstringlen, "%s:%s:", type2str(ps.type), ps.arg);
-		    maxstringlen -= strlen(stringptr);
-		    stringptr += strlen(stringptr);
-		    /* put timestamp in and show to rrd */
-		    snprintf(stringptr, maxstringlen, "%u", (unsigned int)timestamp);
-		    arg_ra[3] = stringptr;
-		    maxstringlen -= strlen(stringptr);
-		    stringptr += strlen(stringptr);
-
-		    /* put measurements in */
-		    ps2strn(&ps, stringptr, maxstringlen, PS2STR_RRD);
-
-		    if (stream->file != NULL) {
-			/* clear optind for getopt call by rrdupdate */
-			optind = 0;
-			/* save if file specified */
-			arg_ra[0] = "rrdupdate";
-			arg_ra[1] = "--";
-			arg_ra[2] = stream->file;
-
-			/*
-			 * This call will cost a lot (symux will become
-			 * unresponsive and eat up massive amounts of cpu) if
-			 * the rrdfile is out of sync.
-			 */
-			rrd_update(4, arg_ra);
-
-			if (rrd_test_error()) {
-			    warning("rrd_update:%.200s", rrd_get_error());
-			    warning("%.200s %.200s %.200s %.200s", arg_ra[0], arg_ra[1],
-				    arg_ra[2], arg_ra[3]);
-			    rrd_clear_error();
-			} else {
-			    if (flag_debug == 1)
-				debug("%.200s %.200s %.200s %.200s", arg_ra[0], arg_ra[1],
-				      arg_ra[2], arg_ra[3]);
-			}
-		    }
-		    maxstringlen -= strlen(stringptr);
-		    stringptr += strlen(stringptr);
-		    snprintf(stringptr, maxstringlen, ";");
-		    maxstringlen -= strlen(stringptr);
-		    stringptr += strlen(stringptr);
-		} else {
-		    debug("ignored unaccepted stream %.16s(%.16s) from %.20s", type2str(ps.type),
-			  ((ps.arg == NULL) ? "0" : ps.arg), source->addr);
-		}
-	    }
-	    /*
-	     * packet = parsed and in ascii in shared region -> copy to
-	     * clients
-	     */
-	    snprintf(stringptr, maxstringlen, "\n");
-	    stringptr += strlen(stringptr);
-	    shared_setlen(slot, (stringptr - stringbuf));
-	    debug("churnbuffer used: %d", (stringptr - stringbuf));
-	    master_permitread();
-	}			/* flag_hup == 0 */
-    }				/* forever */
+    for (;;) {                  /* FOREVER */
+        wait_for_traffic(mux, &source, &packet);
+
+        if (flag_hup == 1) {
+            flag_hup = 0;
+
+            SLIST_INIT(&newmul);
+
+            if (!read_config_file(&newmul, cfgfile, 1)) {
+                info("new configuration contains errors; keeping old configuration");
+                free_muxlist(&newmul);
+            } else {
+                info("read configuration file '%.100s' successfully", cfgfile);
+                free_muxlist(&mul);
+                mul = newmul;
+                mux = SLIST_FIRST(&mul);
+                get_symon_sockets(mux);
+                get_client_socket(mux);
+            }
+        } else {
+
+            /*
+             * Put information from packet into stringbuf (shared region).
+             * Note that the stringbuf is used twice: 1) to update the
+             * rrdfile and 2) to collect all the data from a single packet
+             * that needs to shared to the clients. This is the reason for
+             * the hasseling with stringptr.
+             */
+
+            offset = mux->offset;
+            maxstringlen = shared_getmaxlen();
+            /* put time:ip: into shared region */
+            slot = master_forbidread();
+            timestamp = (time_t) packet.header.timestamp;
+            stringbuf = shared_getmem(slot);
+            debug("stringbuf = 0x%8x", stringbuf);
+            snprintf(stringbuf, maxstringlen, "%s;", source->addr);
+
+            /* hide this string region from rrd update */
+            maxstringlen -= strlen(stringbuf);
+            stringptr = stringbuf + strlen(stringbuf);
+
+            while (offset < packet.header.length) {
+                bzero(&ps, sizeof(struct packedstream));
+                offset += sunpack(packet.data + offset, &ps);
+
+                /* find stream in source */
+                stream = find_source_stream(source, ps.type, ps.arg);
+
+                if (stream != NULL) {
+                    /* put type and arg in and hide from rrd */
+                    snprintf(stringptr, maxstringlen, "%s:%s:", type2str(ps.type), ps.arg);
+                    maxstringlen -= strlen(stringptr);
+                    stringptr += strlen(stringptr);
+                    /* put timestamp in and show to rrd */
+                    snprintf(stringptr, maxstringlen, "%u", (unsigned int)timestamp);
+                    arg_ra[3] = stringptr;
+                    maxstringlen -= strlen(stringptr);
+                    stringptr += strlen(stringptr);
+
+                    /* put measurements in */
+                    ps2strn(&ps, stringptr, maxstringlen, PS2STR_RRD);
+
+                    if (stream->file != NULL) {
+                        /* clear optind for getopt call by rrdupdate */
+                        optind = 0;
+                        /* save if file specified */
+                        arg_ra[0] = "rrdupdate";
+                        arg_ra[1] = "--";
+                        arg_ra[2] = stream->file;
+
+                        /*
+                         * This call will cost a lot (symux will become
+                         * unresponsive and eat up massive amounts of cpu) if
+                         * the rrdfile is out of sync.
+                         */
+                        rrd_update(4, arg_ra);
+
+                        if (rrd_test_error()) {
+                            if (rrderrors < SYMUX_MAXRRDERRORS) {
+                                rrderrors++;
+                                warning("rrd_update:%.200s", rrd_get_error());
+                                warning("%.200s %.200s %.200s %.200s", arg_ra[0], arg_ra[1],
+                                        arg_ra[2], arg_ra[3]);
+                                if (rrderrors == SYMUX_MAXRRDERRORS) {
+                                    warning("maximum rrd errors reached - will stop reporting them");
+                                }
+                            }
+                            rrd_clear_error();
+                        } else {
+                            if (flag_debug == 1)
+                                debug("%.200s %.200s %.200s %.200s", arg_ra[0], arg_ra[1],
+                                      arg_ra[2], arg_ra[3]);
+                        }
+                    }
+                    maxstringlen -= strlen(stringptr);
+                    stringptr += strlen(stringptr);
+                    snprintf(stringptr, maxstringlen, ";");
+                    maxstringlen -= strlen(stringptr);
+                    stringptr += strlen(stringptr);
+                } else {
+                    debug("ignored unaccepted stream %.16s(%.16s) from %.20s", type2str(ps.type),
+                          ((ps.arg == NULL) ? "0" : ps.arg), source->addr);
+                }
+            }
+            /*
+             * packet = parsed and in ascii in shared region -> copy to
+             * clients
+             */
+            snprintf(stringptr, maxstringlen, "\n");
+            stringptr += strlen(stringptr);
+            shared_setlen(slot, (stringptr - stringbuf));
+            debug("churnbuffer used: %d", (stringptr - stringbuf));
+            master_permitread();
+        }                       /* flag_hup == 0 */
+    }                           /* forever */
 
 
     /* NOT REACHED */
     /* NOT REACHED */
     return (EX_SOFTWARE);
     return (EX_SOFTWARE);

+ 3 - 0
symon/symux/symux.h

@@ -48,4 +48,7 @@
 /* Number of data slots for clients in shared memory */
 /* Number of data slots for clients in shared memory */
 #define SYMUX_SHARESLOTS  20
 #define SYMUX_SHARESLOTS  20
 
 
+/* Number of rrd errors logged before smothering sets in */
+#define SYMUX_MAXRRDERRORS 5
+
 #endif				/* _SYMUX_SYMUX_H */
 #endif				/* _SYMUX_SYMUX_H */

+ 4 - 1
symon/symux/symuxnet.c

@@ -1,4 +1,4 @@
-/* $Id: symuxnet.c,v 1.20 2005/10/21 14:58:47 dijkstra Exp $ */
+/* $Id: symuxnet.c,v 1.21 2006/06/30 08:21:23 dijkstra Exp $ */
 
 
 /*
 /*
  * Copyright (c) 2001-2004 Willem Dijkstra
  * Copyright (c) 2001-2004 Willem Dijkstra
@@ -290,6 +290,9 @@ accept_connection(int sock)
     socklen_t len;
     socklen_t len;
     int clientsock;
     int clientsock;
 
 
+    bzero(&sind, sizeof(struct sockaddr_storage));
+    len = 0;
+
     if ((clientsock = accept(sock, (struct sockaddr *) &sind, &len)) < 0)
     if ((clientsock = accept(sock, (struct sockaddr *) &sind, &len)) < 0)
 	fatal("failed to accept an incoming connection. (%.200s)",
 	fatal("failed to accept an incoming connection. (%.200s)",
 	      strerror(errno));
 	      strerror(errno));