Browse Source

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

Wictor Lund 3 years ago
parent
commit
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
 
    - 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
 
-   - 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
      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
      configured (Eric Dillenseger)
 
-
 19/03/2005 - 2.71
 
    - 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
              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.
 
 - 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
   debugging on initially to iron out any configuration problems:
@@ -105,5 +106,5 @@ for FreeBSD, NetBSD and Linux.
 
 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
 
 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
@@ -136,7 +136,7 @@ u_int32_t
 crc32_table[256];
 
 /* Convert lexical entities to stream entities */
-const int
+int
 token2type(const int token)
 {
     int i;
@@ -152,7 +152,7 @@ token2type(const int token)
     return 0;
 }
 /* Convert stream entities to their ascii representation */
-const char *
+char *
 type2str(const int streamtype)
 {
     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
@@ -301,8 +301,8 @@ struct packedstream {
 
 /* prototypes */
 __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 getheader(char *, struct symonpacketheader *);
 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
@@ -111,14 +111,14 @@ parse_token(const char *cp)
     return LXT_BADTOKEN;
 }
 /* Return the ascii representation of an opcode */
-const char *
+char *
 parse_opcode(const int op)
 {
     u_int i;
 
     for (i = 0; keywords[i].name; i++)
 	if (keywords[i].opcode == op)
-	    return keywords[i].name;
+	    return (char *) keywords[i].name;
 
     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
@@ -95,7 +95,7 @@ struct lex {
 };
 
 __BEGIN_DECLS
-const char *parse_opcode(int);
+char *parse_opcode(int);
 int lex_nexttoken(struct lex *);
 int parse_token(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
 #define _LIB_LIMITS_H
@@ -11,6 +11,7 @@
 #define SYMON_MAX_OBJSIZE      (_POSIX2_LINE_MAX)
 #define SYMON_SENSORMASK       0xFF     /* sensors 0-255 are allowed */
 #define SYMON_MAXDEBUGID       20       /* = CTL_DEBUG_MAXID; depends lib/data.h */
+#define SYMON_MAXCPUID         16       /* cpu0 - cpu15 */
 #define SYMON_DFBLOCKSIZE      512
 #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
 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
 #define _CONF_FREEBSD_H
 
 #include <sys/queue.h>
-#include <sys/socket.h>
 #include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/dkstat.h>
 #include <sys/resource.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
@@ -80,7 +80,7 @@ init_io(struct stream *st)
 void
 gets_io()
 {
-#if DEVSTAT_USER_API_VER == 5
+#if DEVSTAT_USER_API_VER >= 5
     io_numdevs = devstat_getnumdevs(NULL);
 #else
     io_numdevs = getnumdevs();
@@ -97,7 +97,7 @@ gets_io()
     /* clear the devinfo struct, as getdevs expects it to be all zeroes */
     bzero(io_stats.dinfo, sizeof(struct devinfo));
 
-#if DEVSTAT_USER_API_VER == 5
+#if DEVSTAT_USER_API_VER >= 5
     devstat_getdevs(NULL, &io_stats);
 #else
     getdevs(&io_stats);
@@ -117,7 +117,7 @@ get_io(char *symon_buf, int maxlen, struct stream *st)
 	    strlen(ds->device_name) < strlen(st->arg) &&
 	    isdigit(st->arg[strlen(ds->device_name)]) &&
 	    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,
 			  ds->operations[DEVSTAT_READ],
 			  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
@@ -131,12 +131,12 @@ get_mem(char *symon_buf, int maxlen, struct stream *st)
     }
     for (i = 0; i < vmnswp_dat; i++) {
 	struct xswdev vmiswp_dat;
-	int vmiswp_siz;
+	int vmiswp_siz = sizeof(vmiswp_dat);
 	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)
 		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
 

+ 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
@@ -73,6 +73,12 @@ init_pf(struct stream *st)
     fatal("pf support not available");
 }
 
+void
+gets_pf()
+{
+    fatal("pf support not available");
+}
+
 int
 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
 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

+ 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" ;;
 0)	echo "#undef HAS_KERN_MBSTAT" ;;
 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
 1)	echo "#define HAS_SENSORS_H	1" ;;
 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
 #define _CONF_OPENBSD_H
 
+#include "conf.h"
+
 #include <sys/dkstat.h>
 #include <sys/queue.h>
 #include <sys/types.h>
@@ -17,14 +19,24 @@
 #define SS_LEN(x)       ((x)->ss_len)
 
 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 {
-	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;
+#endif
     struct {
-	char rawdev[SYMON_DFNAMESIZE];
+        char rawdev[SYMON_DFNAMESIZE];
     } df;
     struct ifreq ifr;
     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).
  *
@@ -51,25 +51,27 @@
  *
  * 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.
  */
 
+#include "conf.h"
+
 #include <sys/dkstat.h>
 #include <sys/param.h>
 #include <sys/sysctl.h>
 
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+
 #include "error.h"
 #include "symon.h"
 
-__BEGIN_DECLS
-int percentages(int, int *, long *, long *, long *);
-__END_DECLS
 
 /* Globals for this module all start with cp_ */
-static int cp_time_mib[] = {CTL_KERN, KERN_CPTIME};
 static size_t cp_size;
+
 /*
  *  percentages(cnt, out, new, old, diffs) - calculate percentage change
  *      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
  *      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
 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
@@ -119,6 +127,31 @@ init_cpu(struct stream *st)
 {
     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);
     /* Call get_cpu once to fill the cp_old structure */
     get_cpu(buf, sizeof(buf), st);
@@ -136,10 +169,17 @@ get_cpu(char *symon_buf, int maxlen, struct stream *st)
 {
     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) {
 	warning("%s:%d: sysctl kern.cp_time failed", __FILE__, __LINE__);
 	return 0;
     }
+#endif
 
     /* 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);

+ 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
@@ -35,6 +35,7 @@
 #include <sys/sysctl.h>
 #include <sys/errno.h>
 
+#include <errno.h>
 #include <string.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
@@ -77,6 +77,11 @@ get_pf(char *symon_buf, int maxlen, struct stream *st)
     fatal("pf support not available");
     return 0;
 }
+void
+gets_pf()
+{
+    fatal("pf support not available");
+}
 
 #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 "../platform/${OS}/Makefile.inc"
 
-LIBS+=	-L../lib -lsymon
+LIBS+=	${SYMON_LIBS} -L../lib -lsymon
 MODS!=	( for g in ../platform/stub/sm_*.c; do \
 		f=../platform/${OS}/`basename $$g`; \
 		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
@@ -273,7 +273,7 @@ main(int argc, char *argv[])
 
     last_update = time(NULL);
     for (;;) {			/* FOREVER */
-	sleep(symon_interval);	/* alarm will interrupt sleep */
+	sleep(symon_interval * 2);	/* alarm will interrupt sleep */
 	now = time(NULL);
 
 	if (flag_hup == 1) {
@@ -304,17 +304,15 @@ main(int argc, char *argv[])
 	    }
 	} else {
 	    /* 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 */
 	    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 "../platform/${OS}/Makefile.inc"
 
 SRCS=	symux.c readconf.c symuxnet.c share.c
 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.
 
 all: symux symux.cat8

+ 40 - 142
symon/symux/c_smrrds.sh

@@ -1,8 +1,8 @@
 #!/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.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -31,19 +31,25 @@
 
 # --- user configuration starts here
 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
-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() {
     file=$1
     shift
@@ -88,147 +94,39 @@ oneday)
 esac
 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
 if [ X"$1$2$3$4$5$6$7$8$9" = "X" ]; then
     cat <<EOF
 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:
-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
     exit 1;
 fi
 
+RRD_ARGS="--step=$INTERVAL --start=0"
+
 for i in $args
 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
     echo "$i exists - ignoring"
     i="done"
 fi
 
-RRD_ARGS="--step=$INTERVAL --start=0"
-
-case $i in
+j=`basename $i`
+case $j in
 
 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)
@@ -324,13 +222,13 @@ pf.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)
     # Build mbuf file
@@ -368,7 +266,7 @@ io1_*.rrd)
     ;;
 *)
     # Default match
-    echo $i - unknown
+    echo $i - cannot determine filetype from filename
     ;;
 esac
 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
@@ -46,7 +46,7 @@
 
 __BEGIN_DECLS
 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 *);
 __END_DECLS
 
@@ -163,12 +163,11 @@ read_mux(struct muxlist * mul, struct lex * l)
     if (rename_mux(mul, mux, muxname) == NULL)
 	fatal("%s:%d: internal error: dual mux", __FILE__, __LINE__);
 
-
     return 1;
 }
 /* source <host> { accept ... | write ... | datadir ... } */
 int
-read_source(struct sourcelist * sol, struct lex * l)
+read_source(struct sourcelist * sol, struct lex * l, int filecheck)
 {
     struct source *source;
     struct stream *stream;
@@ -268,20 +267,22 @@ read_source(struct sourcelist * sol, struct lex * l)
 		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);
 	    path[_POSIX2_LINE_MAX - 1] = '\0';
@@ -316,15 +317,19 @@ read_source(struct sourcelist * sol, struct lex * l)
 			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 */
@@ -382,22 +387,26 @@ read_source(struct sourcelist * sol, struct lex * l)
 			return 0;
 		    }
 		} 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 */
 	    default:
@@ -421,7 +430,7 @@ read_source(struct sourcelist * sol, struct lex * l)
 }
 /* Read symux.conf */
 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 source *source;
@@ -444,7 +453,7 @@ read_config_file(struct muxlist * mul, const char *filename)
 	    }
 	    break;
 	case LXT_SOURCE:
-	    if (!read_source(&sol, l)) {
+	    if (!read_source(&sol, l, filechecks)) {
 		free_sourcelist(&sol);
 		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
@@ -37,7 +37,7 @@
 #include "data.h"
 
 __BEGIN_DECLS
-int read_config_file(struct muxlist *, const char *);
+int read_config_file(struct muxlist *, const char *, int);
 __END_DECLS
 
 #endif				/* _SYMUX_READCONF_H */

+ 5 - 3
symon/symux/symux.8

@@ -35,7 +35,7 @@
 .Nd symon stream multiplexer
 .Sh SYNOPSIS
 .Nm
-.Op Fl vd
+.Op Fl dlv
 .Op Fl f Ar filename
 .Pp
 .Sh DESCRIPTION
@@ -71,8 +71,6 @@ the rrd files. It should be run as
 .Lp
 The options:
 .Bl -tag -width Ds
-.It Fl v
-Show version.
 .It Fl d
 Stop
 .Nm
@@ -84,6 +82,10 @@ Read configuration from
 .Ar filename
 instead of
 .Pa /etc/symux.conf .
+.It Fl l
+List rrd files found in active configuration.
+.It Fl v
+Show version.
 .El
 .Sh CONFIGURATION
 .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.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -108,11 +108,15 @@ main(int argc, char *argv[])
     char *arg_ra[4];
     struct stream *stream;
     struct source *source;
+    struct sourcelist *sol;
     struct mux *mux;
     FILE *f;
     int ch;
     int churnbuflen;
+    int flag_list;
     int offset;
+    int result;
+    unsigned int rrderrors;
     int slot;
     time_t timestamp;
 
@@ -121,67 +125,105 @@ main(int argc, char *argv[])
     /* reset flags */
     flag_debug = 0;
     flag_daemon = 0;
+    flag_list = 0;
+
     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());
     setgid(getgid());
 
     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);
 
     if (flag_debug == 1)
-	info("program id=%d", (u_int) getpid());
+        info("program id=%d", (u_int) getpid());
 
     mux = SLIST_FIRST(&mul);
 
@@ -201,121 +243,128 @@ main(int argc, char *argv[])
 
     /* prepare sockets */
     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)
-	fatal("socket for client connections could not be opened");
+        fatal("socket for client connections could not be opened");
 
+    rrderrors = 0;
     /* 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 */
     return (EX_SOFTWARE);

+ 3 - 0
symon/symux/symux.h

@@ -48,4 +48,7 @@
 /* Number of data slots for clients in shared memory */
 #define SYMUX_SHARESLOTS  20
 
+/* Number of rrd errors logged before smothering sets in */
+#define SYMUX_MAXRRDERRORS 5
+
 #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
@@ -290,6 +290,9 @@ accept_connection(int sock)
     socklen_t len;
     int clientsock;
 
+    bzero(&sind, sizeof(struct sockaddr_storage));
+    len = 0;
+
     if ((clientsock = accept(sock, (struct sockaddr *) &sind, &len)) < 0)
 	fatal("failed to accept an incoming connection. (%.200s)",
 	      strerror(errno));