Browse Source

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

Wictor Lund 3 years ago
parent
commit
fdb301aff6
72 changed files with 1605 additions and 918 deletions
  1. 25 1
      symon/CHANGELOG
  2. 3 5
      symon/HACKERS
  3. 7 6
      symon/INSTALL
  4. 2 2
      symon/Makefile.inc
  5. 4 2
      symon/client/SymuxClient.pm
  6. 2 2
      symon/lib/Makefile
  7. 13 11
      symon/lib/data.c
  8. 20 11
      symon/lib/data.h
  9. 2 1
      symon/lib/lex.c
  10. 24 23
      symon/lib/lex.h
  11. 17 0
      symon/lib/sylimits.h
  12. 23 1
      symon/platform/FreeBSD/platform.h
  13. 25 25
      symon/platform/FreeBSD/sm_cpu.c
  14. 10 11
      symon/platform/FreeBSD/sm_debug.c
  15. 108 0
      symon/platform/FreeBSD/sm_df.c
  16. 56 50
      symon/platform/FreeBSD/sm_if.c
  17. 11 12
      symon/platform/FreeBSD/sm_io.c
  18. 10 12
      symon/platform/FreeBSD/sm_mbuf.c
  19. 13 11
      symon/platform/FreeBSD/sm_mem.c
  20. 56 46
      symon/platform/FreeBSD/sm_pf.c
  21. 47 39
      symon/platform/FreeBSD/sm_pfq.c
  22. 27 24
      symon/platform/FreeBSD/sm_proc.c
  23. 19 2
      symon/platform/Linux/platform.h
  24. 30 46
      symon/platform/Linux/sm_cpu.c
  25. 29 29
      symon/platform/Linux/sm_if.c
  26. 135 0
      symon/platform/Linux/sm_mem.c
  27. 1 1
      symon/platform/NetBSD/Makefile.inc
  28. 22 1
      symon/platform/NetBSD/platform.h
  29. 21 24
      symon/platform/NetBSD/sm_cpu.c
  30. 9 11
      symon/platform/NetBSD/sm_debug.c
  31. 108 0
      symon/platform/NetBSD/sm_df.c
  32. 17 16
      symon/platform/NetBSD/sm_if.c
  33. 8 11
      symon/platform/NetBSD/sm_io.c
  34. 10 12
      symon/platform/NetBSD/sm_mbuf.c
  35. 17 12
      symon/platform/NetBSD/sm_proc.c
  36. 19 22
      symon/platform/NetBSD/sm_sensor.c
  37. 21 1
      symon/platform/OpenBSD/platform.h
  38. 19 22
      symon/platform/OpenBSD/sm_cpu.c
  39. 9 11
      symon/platform/OpenBSD/sm_debug.c
  40. 108 0
      symon/platform/OpenBSD/sm_df.c
  41. 18 19
      symon/platform/OpenBSD/sm_if.c
  42. 9 12
      symon/platform/OpenBSD/sm_io.c
  43. 16 20
      symon/platform/OpenBSD/sm_mbuf.c
  44. 21 14
      symon/platform/OpenBSD/sm_mem.c
  45. 54 46
      symon/platform/OpenBSD/sm_pf.c
  46. 39 35
      symon/platform/OpenBSD/sm_pfq.c
  47. 16 10
      symon/platform/OpenBSD/sm_proc.c
  48. 19 20
      symon/platform/OpenBSD/sm_sensor.c
  49. 6 6
      symon/platform/stub/sm_cpu.c
  50. 5 4
      symon/platform/stub/sm_debug.c
  51. 26 0
      symon/platform/stub/sm_df.c
  52. 5 5
      symon/platform/stub/sm_if.c
  53. 5 3
      symon/platform/stub/sm_io.c
  54. 5 3
      symon/platform/stub/sm_mbuf.c
  55. 10 4
      symon/platform/stub/sm_mem.c
  56. 10 5
      symon/platform/stub/sm_pf.c
  57. 5 6
      symon/platform/stub/sm_pfq.c
  58. 11 3
      symon/platform/stub/sm_proc.c
  59. 5 3
      symon/platform/stub/sm_sensor.c
  60. 5 4
      symon/symon/readconf.c
  61. 9 7
      symon/symon/symon.8
  62. 12 11
      symon/symon/symon.c
  63. 31 29
      symon/symon/symon.h
  64. 2 2
      symon/symon/symonnet.c
  65. 24 3
      symon/symux/c_smrrds.sh
  66. 11 5
      symon/symux/readconf.c
  67. 70 85
      symon/symux/share.c
  68. 10 15
      symon/symux/share.h
  69. 16 10
      symon/symux/symux.8
  70. 11 9
      symon/symux/symux.c
  71. 4 1
      symon/symux/symux.h
  72. 8 3
      symon/symux/symuxnet.c

+ 25 - 1
symon/CHANGELOG

@@ -1,3 +1,27 @@
+23/10/2005 - 2.72
+
+   - probes use a new "api" that allows per probe storage of
+     precomputed data
+
+   - Marc Balmer donated the df probe
+
+   - 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)
+
+   - 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
+     still killed, but have a bit more time to catch up.
+
+   - Ulrich Spörlein updated proc probe for FreeBSD-current.
+
+   - sm_mem for FreeBSD did not clear swap stats between calls (J. Martin
+     Petersen)
+
+   - 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
@@ -396,4 +420,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.43 2005/03/22 07:17:42 dijkstra Exp $
+$Id: CHANGELOG,v 1.48 2005/10/21 14:58:41 dijkstra Exp $

+ 3 - 5
symon/HACKERS

@@ -1,11 +1,12 @@
-$Id: HACKERS,v 1.1 2005/03/20 16:17:22 dijkstra Exp $
+$Id: HACKERS,v 1.2 2005/10/16 15:26:47 dijkstra Exp $
 
 Adding a new probe
 ------------------
 
 Get your measurement as fast as possible with as little fuss as possible. Ideal
 is to get all items that the user might want to query in one gets() and give
-symon the readings for a particular item in a get().
+symon the readings for a particular item in a get(). This way, all information
+submitted by one probe is measured at the same time.
 
 Places to touch:
 
@@ -27,6 +28,3 @@ Places to touch:
 
 - symon/symon.8, symux/symux.8: add your token and its internal format to the
   manual pages.
-
-
-

+ 7 - 6
symon/INSTALL

@@ -8,18 +8,19 @@ symux needs read and write access to its rrdfiles.
 symon needs to interface with your kernel. Depending on your host system this
 leads to different privilege requirements:
 
-OpenBSD:  - sysctl: cpu, debug, if, io, mbuf, mem, proc, sensor
+OpenBSD:  - no privs: cpu, debug, df, if, io, mbuf, mem, proc, sensor
           - rw on /dev/pf for pf
 
-NetBSD:   - sysctl: cpu, debug, if, io, mbuf, proc
+NetBSD:   - no privs: cpu, debug, df, if, io, mbuf, proc
           - r on /dev/sysmon for sensor
 
-FreeBSD:  - sysctl: all
+FreeBSD:  - no privs: all
           - non-chroot on FreeBSD 5.x for CPU ticks in proc
           - rw on /dev/pf for pf and pfq
 
 Linux:    - r on /proc/net/dev: if
           - r on /proc/stat: cpu
+          - r on /proc/meminfo: mem
 
 Real quick on OpenBSD
 =====================
@@ -99,10 +100,10 @@ Historical data can be gathered using rrdfetch(1) from symux's rrd files.
 Portability
 ===========
 
-This package was originally built as an OpenBSD application. It now has
-rudimentary support for FreeBSD, NetBSD and Linux.
+This package was originally built as an OpenBSD application. It now has support
+for FreeBSD, NetBSD and Linux.
 
 Willem Dijkstra - wpd@xs4all.nl
 
-$Id: INSTALL,v 1.18 2005/03/20 16:17:22 dijkstra Exp $
+$Id: INSTALL,v 1.19 2005/10/21 14:58:41 dijkstra Exp $
 

+ 2 - 2
symon/Makefile.inc

@@ -1,6 +1,6 @@
-# $Id: Makefile.inc,v 1.31 2005/03/20 16:17:22 dijkstra Exp $
+# $Id: Makefile.inc,v 1.32 2005/09/30 14:04:56 dijkstra Exp $
 
-V=2.71
+V=2.72
 OS!=uname -s
 
 AR?=	ar

+ 4 - 2
symon/client/SymuxClient.pm

@@ -1,4 +1,4 @@
-# $Id: SymuxClient.pm,v 1.10 2005/03/20 16:17:22 dijkstra Exp $
+# $Id: SymuxClient.pm,v 1.11 2005/10/16 15:26:50 dijkstra Exp $
 #
 # Copyright (c) 2001-2005 Willem Dijkstra
 # All rights reserved.
@@ -67,7 +67,9 @@ my $streamitem =
      io     => {total_rxfers => 1, total_wxfers => 2, total_seeks => 3,
 		total_rbytes => 4, total_rbytes => 5 },
      pfq    => {sent_bytes => 1, sent_packets => 2, drop_bytes => 3,
-		drop_packets => 4}};
+		drop_packets => 4}
+     df     => {blocks => 1, bfree => 2, bavail => 3, files => 4, ffree => 5,
+		syncwrites => 6, asyncwrites => 7}};
 sub new {
     my ($class, %arg) = @_;
     my $self;

+ 2 - 2
symon/lib/Makefile

@@ -1,10 +1,10 @@
-# $Id: Makefile,v 1.12 2004/09/25 10:21:56 dijkstra Exp $
+# $Id: Makefile,v 1.13 2005/10/16 15:26:51 dijkstra Exp $
 .include "../Makefile.inc"
 .include "../platform/${OS}/Makefile.inc"
 
 SRCS=   error.c lex.c xmalloc.c net.c data.c
 OBJS+=	${SRCS:R:S/$/.o/g}
-CFLAGS+=-I../platform/${OS}
+CFLAGS+=-I../platform/${OS} -I.
 
 all: libsymon.a
 

+ 13 - 11
symon/lib/data.c

@@ -1,4 +1,4 @@
-/* $Id: data.c,v 1.27 2005/03/20 16:17:22 dijkstra Exp $ */
+/* $Id: data.c,v 1.28 2005/10/16 15:26:51 dijkstra Exp $ */
 
 /*
  * Copyright (c) 2001-2005 Willem Dijkstra
@@ -108,6 +108,7 @@ struct {
     { MT_SENSOR, "D" },
     { MT_IO2, "LLLLL" },
     { MT_PFQ, "LLLL" },
+    { MT_DF, "LLLLLLL" },
     { MT_TEST, "LLLLDDDDllllssssccccbbbb" },
     { MT_EOT, "" }
 };
@@ -127,6 +128,7 @@ struct {
     { MT_SENSOR, LXT_SENSOR },
     { MT_IO2, LXT_IO },
     { MT_PFQ, LXT_PFQ },
+    { MT_DF, LXT_DF },
     { MT_EOT, LXT_BADTOKEN }
 };
 /* parallel crc32 table */
@@ -440,11 +442,11 @@ sunpack(char *buf, struct packedstream * ps)
     type = ps->type = (*in);
     in++;
     if ((*in) != '\0') {
-	strncpy(ps->args, in, sizeof(ps->args));
-	ps->args[sizeof(ps->args) - 1] = '\0';
-	in += strlen(ps->args) + 1;
+	strncpy(ps->arg, in, sizeof(ps->arg));
+	ps->arg[sizeof(ps->arg) - 1] = '\0';
+	in += strlen(ps->arg) + 1;
     } else {
-	ps->args[0] = '\0';
+	ps->arg[0] = '\0';
 	in++;
     }
 
@@ -606,7 +608,7 @@ create_stream(int type, char *args)
     p->type = type;
 
     if (args != NULL)
-	p->args = xstrdup(args);
+	p->arg = xstrdup(args);
 
     return p;
 }
@@ -622,7 +624,7 @@ find_source_stream(struct source * source, int type, char *args)
     SLIST_FOREACH(p, &source->sl, streams) {
 	if (((void *) p != NULL) && (p->type == type)
 	    && (((void *) args != (void *) p)
-		&& strncmp(args, p->args, _POSIX2_LINE_MAX) == 0))
+		&& strncmp(args, p->arg, _POSIX2_LINE_MAX) == 0))
 	    return p;
     }
 
@@ -658,7 +660,7 @@ find_mux_stream(struct mux * mux, int type, char *args)
     SLIST_FOREACH(p, &mux->sl, streams) {
 	if (((void *) p != NULL) && (p->type == type)
 	    && (((void *) args != (void *) p)
-		&& strncmp(args, p->args, _POSIX2_LINE_MAX) == 0))
+		&& strncmp(args, p->arg, _POSIX2_LINE_MAX) == 0))
 	    return p;
     }
 
@@ -836,8 +838,8 @@ free_streamlist(struct streamlist * sl)
     while (p) {
 	np = SLIST_NEXT(p, streams);
 
-	if (p->args != NULL)
-	    xfree(p->args);
+	if (p->arg != NULL)
+	    xfree(p->arg);
 	if (p->file != NULL)
 	    xfree(p->file);
 	xfree(p);
@@ -888,7 +890,7 @@ calculate_churnbuffer(struct sourcelist * sol)
 	len = snprintf(&buf[0], _POSIX2_LINE_MAX, "%s;", source->addr);
 	SLIST_FOREACH(stream, &source->sl, streams) {
 	    len += strlen(type2str(stream->type)) + strlen(":");
-	    len += strlen(stream->args) + strlen(":");
+	    len += strlen(stream->arg) + strlen(":");
 	    len += (sizeof(time_t) * 3) + strlen(":"); /* 3 > ln(255) / ln(10) */
 	    len += strlentype(stream->type);
 	    n++;

+ 20 - 11
symon/lib/data.h

@@ -1,4 +1,4 @@
-/* $Id: data.h,v 1.26 2005/03/20 16:17:22 dijkstra Exp $ */
+/* $Id: data.h,v 1.27 2005/10/16 15:26:51 dijkstra Exp $ */
 
 /*
  * Copyright (c) 2001-2005 Willem Dijkstra
@@ -40,13 +40,13 @@
 #ifndef _SYMON_LIB_DATA_H
 #define _SYMON_LIB_DATA_H
 
-#include <sys/queue.h>
-#include <sys/types.h>
-#include <sys/socket.h>
+#include "platform.h"
+
 #include <netinet/in.h>
 #include <limits.h>
 
 #include "lex.h"
+#include "sylimits.h"
 
 /* Polynominal to use for CRC generation */
 #define SYMON_CRCPOLY  0x04c11db7
@@ -78,6 +78,7 @@ static inline u_int64_t
  * so that works out to about 38 packedstreams in a single symon packet.
  */
 #define SYMON_PACKET_VER  1
+#define SYMON_UNKMUX   "<unknown mux>"	/* mux nodes without host addr */
 
 /* Sending structures over the network is dangerous as the compiler might have
  * added extra padding between items. symonpacketheader below is therefore also
@@ -105,9 +106,10 @@ struct symonpacket {
  */
 struct stream {
     int type;
-    char *args;
+    char *arg;
     char *file;
     SLIST_ENTRY(stream) streams;
+    union stream_parg parg;
 };
 SLIST_HEAD(streamlist, stream);
 
@@ -152,21 +154,19 @@ SLIST_HEAD(muxlist, mux);
 #define MT_SENSOR 8
 #define MT_IO2    9
 #define MT_PFQ    10
-#define MT_TEST   11
-#define MT_EOT    12
+#define MT_DF	  11
+#define MT_TEST   12
+#define MT_EOT    13
 
 /*
  * Unpacking of incoming packets is done via a packedstream structure. This
  * structure defines the maximum amount of data that can be contained in a
  * single network representation of a stream.
  */
-#define SYMON_UNKMUX   "<unknown mux>"	/* mux nodes without host addr */
-#define SYMON_PS_ARGLEN        16	/* maximum argument length */
-#define SYMON_PS_ARGLENSTR    "15"	/* maximum number of chars in an argument, as str */
 struct packedstream {
     int type;
     int padding;
-    char args[SYMON_PS_ARGLEN];
+    char arg[SYMON_PS_ARGLEN];
     union {
 	struct symonpacketheader header;
 	struct {
@@ -287,6 +287,15 @@ struct packedstream {
 	    u_int16_t c[4];
 	    u_int8_t b[4];
 	}      ps_test;
+	struct {
+	    u_int64_t blocks;
+	    u_int64_t bfree;
+	    u_int64_t bavail;
+	    u_int64_t files;
+	    u_int64_t ffree;
+	    u_int64_t syncwrites;
+	    u_int64_t asyncwrites;
+	}      ps_df;
     }     data;
 };
 

+ 2 - 1
symon/lib/lex.c

@@ -1,4 +1,4 @@
-/* $Id: lex.c,v 1.25 2005/03/20 16:17:22 dijkstra Exp $ */
+/* $Id: lex.c,v 1.26 2005/10/16 15:26:51 dijkstra Exp $ */
 
 /*
  * Copyright (c) 2001-2005 Willem Dijkstra
@@ -72,6 +72,7 @@ static struct {
     { "cpu", LXT_CPU },
     { "datadir", LXT_DATADIR },
     { "debug", LXT_DEBUG },
+    { "df", LXT_DF },
     { "every", LXT_EVERY },
     { "if", LXT_IF },
     { "in", LXT_IN },

+ 24 - 23
symon/lib/lex.h

@@ -1,4 +1,4 @@
-/* $Id: lex.h,v 1.21 2005/03/20 16:17:22 dijkstra Exp $ */
+/* $Id: lex.h,v 1.22 2005/10/16 15:26:51 dijkstra Exp $ */
 
 /*
  * Copyright (c) 2001-2005 Willem Dijkstra
@@ -51,28 +51,29 @@
 #define LXT_CPU        5
 #define LXT_DATADIR    6
 #define LXT_DEBUG      7
-#define LXT_END        8
-#define LXT_EVERY      9
-#define LXT_IF        10
-#define LXT_IN        11
-#define LXT_IO        12
-#define LXT_IO1       13
-#define LXT_MEM       14
-#define LXT_MONITOR   15
-#define LXT_MUX       16
-#define LXT_OPEN      17
-#define LXT_PF        18
-#define LXT_PORT      19
-#define LXT_PROC      20
-#define LXT_SECOND    21
-#define LXT_SECONDS   22
-#define LXT_SENSOR    23
-#define LXT_SOURCE    24
-#define LXT_STREAM    25
-#define LXT_TO        26
-#define LXT_WRITE     27
-#define LXT_MBUF      28
-#define LXT_PFQ       29
+#define LXT_DF         8
+#define LXT_END        9
+#define LXT_EVERY     10
+#define LXT_IF        11
+#define LXT_IN        12
+#define LXT_IO        13
+#define LXT_IO1       14
+#define LXT_MBUF      15
+#define LXT_MEM       16
+#define LXT_MONITOR   17
+#define LXT_MUX       18
+#define LXT_OPEN      19
+#define LXT_PF        20
+#define LXT_PFQ       21
+#define LXT_PORT      22
+#define LXT_PROC      23
+#define LXT_SECOND    24
+#define LXT_SECONDS   25
+#define LXT_SENSOR    26
+#define LXT_SOURCE    27
+#define LXT_STREAM    28
+#define LXT_TO        29
+#define LXT_WRITE     30
 
 struct lex {
     char *buffer;		/* current line(s) */

+ 17 - 0
symon/lib/sylimits.h

@@ -0,0 +1,17 @@
+/* $Id: sylimits.h,v 1.3 2005/10/21 14:58:42 dijkstra Exp $ */
+
+#ifndef _LIB_LIMITS_H
+#define _LIB_LIMITS_H
+
+#define SYMON_PS_ARGLEN        16       /* maximum argument length */
+#define SYMON_PS_ARGLENSTR     "15"     /* maximum number of chars in an argument, as str */
+#define SYMON_WARN_SENDERR     50       /* warn every x errors */
+#define SYMON_MAX_DOBJECTS     10000    /* max dynamic allocation; local limit per
+					 * measurement module */
+#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_DFBLOCKSIZE      512
+#define SYMON_DFNAMESIZE       16
+
+#endif

+ 23 - 1
symon/platform/FreeBSD/platform.h

@@ -1,13 +1,35 @@
-/* $Id: platform.h,v 1.1 2004/08/07 12:21:36 dijkstra Exp $ */
+/* $Id: platform.h,v 1.4 2005/10/21 14:58:43 dijkstra Exp $ */
 
 #ifndef _CONF_FREEBSD_H
 #define _CONF_FREEBSD_H
 
 #include <sys/queue.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/resource.h>
+
+#include <net/if.h>
+#include <net/if_mib.h>
+
+#include "sylimits.h"
 
 #define SYMON_USER      "_symon"
 #define SEM_ARGS        (SEM_A|SEM_R)
 #define SA_LEN(x)       ((x)->sa_len)
 #define SS_LEN(x)       ((x)->ss_len)
 
+union stream_parg {
+    struct {
+	long time[CPUSTATES];
+	long old[CPUSTATES];
+	long diff[CPUSTATES];
+	int states[CPUSTATES];
+    } cp;
+    struct {
+	char rawdev[SYMON_DFNAMESIZE];
+    } df;
+    struct ifreq ifr;
+    int sn;
+};
+
 #endif

+ 25 - 25
symon/platform/FreeBSD/sm_cpu.c

@@ -1,4 +1,4 @@
-/* $Id: sm_cpu.c,v 1.2 2004/08/08 17:21:18 dijkstra Exp $ */
+/* $Id: sm_cpu.c,v 1.4 2005/10/18 19:58:06 dijkstra Exp $ */
 
 /* The author of this code is Matthew Gream.
  *
@@ -56,6 +56,8 @@
  * This module uses the sysctl interface and can run as any user.
  */
 
+#include "conf.h"
+
 #include <sys/param.h>
 #include <sys/dkstat.h>
 #include <sys/sysctl.h>
@@ -72,10 +74,6 @@ static char cp_time_mib_str[] = "kern.cp_time";
 static int cp_time_mib[CTL_MAXNAME];
 static size_t cp_time_len = 0;
 static size_t cp_size;
-static long cp_time[CPUSTATES];
-static long cp_old[CPUSTATES];
-static long cp_diff[CPUSTATES];
-static int cp_states[CPUSTATES];
 /*
  *  percentages(cnt, out, new, old, diffs) - calculate percentage change
  *      between array "old" and "new", putting the percentages i "out".
@@ -119,47 +117,49 @@ percentages(int cnt, int *out, register long *new, register long *old, long *dif
     /* return the total in case the caller wants to use it */
     return total_change;
 }
-/* Prepare cpu module for use */
+
 void
-init_cpu(char *s)
+init_cpu(struct stream *st)
 {
+    char buf[SYMON_MAX_OBJSIZE];
+
     cp_time_len = CTL_MAXNAME;
     if (sysctlnametomib(cp_time_mib_str, cp_time_mib, &cp_time_len) < 0) {
 	warning("sysctlnametomib for cpu failed");
 	cp_time_len = 0;
     }
 
-    cp_size = sizeof(cp_time);
-    get_cpu(NULL, 0, NULL);
+    cp_size = sizeof(st->parg.cp.time);
+    get_cpu(buf, sizeof(buf), st);
 
-    info("started module cpu(%.200s)", s);
+    info("started module cpu(%.200s)", st->arg);
 }
+
 void
 gets_cpu()
 {
+    /* EMPTY */
 }
-/* Get new cpu measurements */
+
 int
-get_cpu(char *symon_buf, int maxlen, char *s)
+get_cpu(char *symon_buf, int maxlen, struct stream *st)
 {
-    if (!cp_time_len)
+    if (!cp_time_len) {
 	return 0;
+    }
 
-    if (sysctl(cp_time_mib, cp_time_len, &cp_time, &cp_size, NULL, 0) < 0) {
+    if (sysctl(cp_time_mib, cp_time_len, &st->parg.cp.time, &cp_size, NULL, 0) < 0) {
 	warning("%s:%d: sysctl kern.cp_time failed", __FILE__, __LINE__);
 	return 0;
     }
 
     /* convert cp_time counts to percentages */
-    (void)percentages(CPUSTATES, cp_states, cp_time, cp_old, cp_diff);
-
-    if (!symon_buf)
-	return 0;
-
-    return snpack(symon_buf, maxlen, s, MT_CPU,
-		  (double) (cp_states[CP_USER] / 10.0),
-		  (double) (cp_states[CP_NICE] / 10.0),
-		  (double) (cp_states[CP_SYS] / 10.0),
-		  (double) (cp_states[CP_INTR] / 10.0),
-		  (double) (cp_states[CP_IDLE] / 10.0));
+    (void)percentages(CPUSTATES, st->parg.cp.states, st->parg.cp.time, st->parg.cp.old, st->parg.cp.diff);
+
+    return snpack(symon_buf, maxlen, st->arg, MT_CPU,
+		  (double) (st->parg.cp.states[CP_USER] / 10.0),
+		  (double) (st->parg.cp.states[CP_NICE] / 10.0),
+		  (double) (st->parg.cp.states[CP_SYS] / 10.0),
+		  (double) (st->parg.cp.states[CP_INTR] / 10.0),
+		  (double) (st->parg.cp.states[CP_IDLE] / 10.0));
 }

+ 10 - 11
symon/platform/FreeBSD/sm_debug.c

@@ -1,8 +1,8 @@
-/* $Id: sm_debug.c,v 1.1 2004/08/07 12:21:36 dijkstra Exp $ */
+/* $Id: sm_debug.c,v 1.3 2005/10/18 19:58:06 dijkstra Exp $ */
 
 /*
  * Copyright (c)      2004 Matthew Gream
- * Copyright (c) 2001-2004 Willem Dijkstra
+ * Copyright (c) 2001-2005 Willem Dijkstra
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -35,9 +35,10 @@
  * Get current debug statistics from kernel and return them in symon_buf as
  *
  * debug0 : debug1 : ... : debug19
- *
  */
 
+#include "conf.h"
+
 #include <sys/param.h>
 #include <sys/sysctl.h>
 
@@ -46,20 +47,18 @@
 #include "error.h"
 #include "symon.h"
 
-#define SYMON_MAXDEBUGID      20/* = CTL_DEBUG_MAXID; depends lib/data.h */
-
 /* Globals for this module start with db_ */
 static int db_mib[] = { CTL_DEBUG, 0 };
 static int db_v[SYMON_MAXDEBUGID];
-/* Prepare if module for first use */
+
 void
-init_debug(char *s)
+init_debug(struct stream *st)
 {
-    info("started module debug(%.200s)", s);
+    info("started module debug(%.200s)", st->arg);
 }
-/* Get debug statistics */
+
 int
-get_debug(char *symon_buf, int maxlen, char *s)
+get_debug(char *symon_buf, int maxlen, struct stream *st)
 {
     size_t len;
     int i;
@@ -73,7 +72,7 @@ get_debug(char *symon_buf, int maxlen, char *s)
 	sysctl(db_mib, sizeof(db_mib)/sizeof(int), &db_v[i], &len, NULL, 0);
     }
 
-    return snpack(symon_buf, maxlen, s, MT_DEBUG,
+    return snpack(symon_buf, maxlen, st->arg, MT_DEBUG,
 		  db_v[0], db_v[1], db_v[2], db_v[3], db_v[4], db_v[5], db_v[6],
 		  db_v[7], db_v[8], db_v[9], db_v[10], db_v[11], db_v[12], db_v[13],
 		  db_v[14], db_v[15], db_v[16], db_v[17], db_v[18], db_v[19]);

+ 108 - 0
symon/platform/FreeBSD/sm_df.c

@@ -0,0 +1,108 @@
+/* $Id: sm_df.c,v 1.2 2005/10/18 19:58:11 dijkstra Exp $ */
+
+/*
+ * Copyright (c) 2005 Marc Balmer
+ * 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 df statistics and return them in symon_buf as
+ *
+ *   blocks : bfree : bavail : files : ffree : \
+ *   syncwrites : asyncwrites
+ */
+
+#include "conf.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/mount.h>
+#include <ufs/ufs/dinode.h>
+#include <ufs/ffs/fs.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <fstab.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "error.h"
+#include "symon.h"
+
+/* Globals for this module start with df_ */
+static struct statfs *df_stats = NULL;
+static int df_parts = 0;
+
+void
+init_df(struct stream *st)
+{
+    strlcpy(st->parg.df.rawdev, "/dev/", sizeof(st->parg.df.rawdev));
+    strlcat(st->parg.df.rawdev, st->arg, sizeof(st->parg.df.rawdev));
+
+    info("started module df(%.200s)", st->arg);
+}
+
+void
+gets_df()
+{
+    if ((df_parts = getmntinfo(&df_stats, MNT_NOWAIT)) == 0) {
+	warning("df failed");
+    }
+}
+
+/*
+ * from src/bin/df.c:
+ * Convert statfs returned filesystem size into BLOCKSIZE units.
+ * Attempts to avoid overflow for large filesystems.
+ */
+#define fsbtoblk(num, fsbs, bs) \
+	(((fsbs) != 0 && (fsbs) < (bs)) ? \
+		(num) / ((bs) / (fsbs)) : (num) * ((fsbs) / (bs)))
+
+int
+get_df(char *symon_buf, int maxlen, struct stream *st)
+{
+    int n;
+
+    for (n = 0; n < df_parts; n++) {
+	if (!strncmp(df_stats[n].f_mntfromname, st->parg.df.rawdev, SYMON_DFNAMESIZE)) {
+	    return snpack(symon_buf, maxlen, st->arg, MT_DF,
+			  (u_int64_t)fsbtoblk(df_stats[n].f_blocks, df_stats[n].f_bsize, SYMON_DFBLOCKSIZE),
+			  (u_int64_t)fsbtoblk(df_stats[n].f_bfree, df_stats[n].f_bsize, SYMON_DFBLOCKSIZE),
+			  (u_int64_t)fsbtoblk(df_stats[n].f_bavail, df_stats[n].f_bsize, SYMON_DFBLOCKSIZE),
+			  (u_int64_t)df_stats[n].f_files,
+			  (u_int64_t)df_stats[n].f_ffree,
+			  (u_int64_t)df_stats[n].f_syncwrites,
+			  (u_int64_t)df_stats[n].f_asyncwrites);
+	}
+    }
+
+    warning("df(%.200s) failed (no such device)", st->arg);
+    return 0;
+}

+ 56 - 50
symon/platform/FreeBSD/sm_if.c

@@ -1,7 +1,8 @@
-/* $Id: sm_if.c,v 1.1 2005/01/14 16:12:55 dijkstra Exp $ */
+/* $Id: sm_if.c,v 1.3 2005/10/18 19:58:06 dijkstra Exp $ */
 
 /*
  * Copyright (c) 2005 Fredrik Soderblom
+ * Copyright (c) 2005 Willem Dijkstra
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -35,7 +36,6 @@
  *
  * ipackets : opackets : ibytes : obytes : imcasts : omcasts : ierrors :
  * oerrors : colls : drops
- *
  */
 
 #include <sys/types.h>
@@ -53,88 +53,94 @@
 
 #include "error.h"
 #include "symon.h"
+#include "xmalloc.h"
 
 /* Globals for this module start with if_ */
-static int if_s = -1;
-/* Prepare if module for first use */
+static int if_cur = 0;
+static int if_max = 0;
+struct ifmibdata *if_md = NULL;
+
 void
-init_if(char *s)
+init_if(struct stream *st)
 {
-    if (if_s == -1)
-	if ((if_s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
-	    fatal("%s:%d: socket failed, %.200",
-		  __FILE__, __LINE__, strerror(errno));
-
-    info("started module if(%.200s)", s);
+    info("started module if(%.200s)", st->arg);
 }
 
 int
 get_ifcount(void)
 {
-    int name[5], count;
+    int name[5] = {CTL_NET, PF_LINK, NETLINK_GENERIC, IFMIB_SYSTEM, IFMIB_IFCOUNT};
+    int count;
     size_t len;
-  
-    name[0] = CTL_NET;
-    name[1] = PF_LINK;
-    name[2] = NETLINK_GENERIC;
-    name[3] = IFMIB_SYSTEM;
-    name[4] = IFMIB_IFCOUNT;
 
     len = sizeof(int);
 
-    if (sysctl(name, 5, &count, &len, NULL, 0) != -1)
-        return(count);
-    else
-        return(-1);
+    if (sysctl(name, 5, &count, &len, NULL, 0) != -1) {
+	return count;
+    } else {
+	return -1;
+    }
 }
 
 int
 get_ifmib_general(int row, struct ifmibdata *ifmd)
 {
-    int name[6];
+    int name[6] = {CTL_NET, PF_LINK, NETLINK_GENERIC, IFMIB_IFDATA, row, IFDATA_GENERAL};
     size_t len;
 
-    name[0] = CTL_NET;
-    name[1] = PF_LINK;
-    name[2] = NETLINK_GENERIC;
-    name[3] = IFMIB_IFDATA;
-    name[4] = row;
-    name[5] = IFDATA_GENERAL;
-
     len = sizeof(*ifmd);
 
     return sysctl(name, 6, ifmd, &len, (void *)0, 0);
 }
 
-/* Get interface statistics */
 void
 gets_if()
 {
+    int i;
+
+    /* how much memory is needed */
+    if_cur = get_ifcount();
+
+    /* increase buffers if necessary */
+    if (if_cur > if_max) {
+	if_max = if_cur;
+
+	if (if_max > SYMON_MAX_DOBJECTS) {
+	    fatal("%s:%d: dynamic object limit (%d) exceeded for ifmibdata structures",
+		  __FILE__, __LINE__, SYMON_MAX_DOBJECTS);
+	}
+
+	if_md = xrealloc(if_md, if_max * sizeof(struct ifmibdata));
+    }
+
+    /* read data */
+    for (i = 1; i <= if_cur; i++) {
+	get_ifmib_general(i, &if_md[i - 1]);
+    }
 }
+
 int
-get_if(char *symon_buf, int maxlen, char *interface)
+get_if(char *symon_buf, int maxlen, struct stream *st)
 {
     int i;
-    struct ifmibdata ifmd;
     struct if_data ifdata;
-    int ifcount = get_ifcount();
 
-    for (i = 1; i <= ifcount; i++) {
-        get_ifmib_general(i, &ifmd);
-        if (!strcmp(ifmd.ifmd_name, interface))
-            break;
+    for (i = 1; i <= if_cur; i++) {
+	if (!strcmp(if_md[i - 1].ifmd_name, st->arg)) {
+	    ifdata = if_md[i - 1].ifmd_data;
+	    return snpack(symon_buf, maxlen, st->arg, MT_IF,
+			  ifdata.ifi_ipackets,
+			  ifdata.ifi_opackets,
+			  ifdata.ifi_ibytes,
+			  ifdata.ifi_obytes,
+			  ifdata.ifi_imcasts,
+			  ifdata.ifi_omcasts,
+			  ifdata.ifi_ierrors,
+			  ifdata.ifi_oerrors,
+			  ifdata.ifi_collisions,
+			  ifdata.ifi_iqdrops);
+	}
     }
 
-    ifdata = ifmd.ifmd_data;
-    return snpack(symon_buf, maxlen, interface, MT_IF,
-		  ifdata.ifi_ipackets,
-		  ifdata.ifi_opackets,
-		  ifdata.ifi_ibytes,
-		  ifdata.ifi_obytes,
-		  ifdata.ifi_imcasts,
-		  ifdata.ifi_omcasts,
-		  ifdata.ifi_ierrors,
-		  ifdata.ifi_oerrors,
-		  ifdata.ifi_collisions,
-		  ifdata.ifi_iqdrops);
+    return 0;
 }

+ 11 - 12
symon/platform/FreeBSD/sm_io.c

@@ -1,4 +1,4 @@
-/* $Id: sm_io.c,v 1.1 2005/03/20 16:17:22 dijkstra Exp $ */
+/* $Id: sm_io.c,v 1.3 2005/10/18 19:58:06 dijkstra Exp $ */
 
 /*
  * Copyright (c) 2005 J. Martin Petersen
@@ -32,8 +32,6 @@
 
 /*
  * nr of reads : nr of writes : seeks (zero) : read bytes : written bytes
- *
- * Non re-entrant code
  */
 
 #include "conf.h"
@@ -64,10 +62,11 @@ static int io_numdevs = 0;
 void
 privinit_io()
 {
+    /* EMPTY */
 }
 
 void
-init_io(char *s)
+init_io(struct stream *st)
 {
     io_stats.dinfo = malloc(sizeof(struct devinfo));
     if (io_stats.dinfo == NULL) {
@@ -75,7 +74,7 @@ init_io(char *s)
     }
 
     io_stats.dinfo->mem_ptr = NULL;
-    info("started module io(%.200s)",s);
+    info("started module io(%.200s)", st->arg);
 }
 
 void
@@ -106,7 +105,7 @@ gets_io()
 }
 
 int
-get_io(char *symon_buf, int maxlen, char *dev)
+get_io(char *symon_buf, int maxlen, struct stream *st)
 {
     unsigned int i;
     struct devstat *ds;
@@ -114,12 +113,12 @@ get_io(char *symon_buf, int maxlen, char *dev)
     for (i=0; i < io_numdevs; i++) {
 	ds = &io_stats.dinfo->devices[i];
 
-	if (strncmp(ds->device_name, dev, strlen(ds->device_name)) == 0 &&
-	    strlen(ds->device_name) < strlen(dev) &&
-	    isdigit(dev[strlen(ds->device_name)]) &&
-	    atoi(&dev[strlen(ds->device_name)]) == ds->unit_number) {
+	if (strncmp(ds->device_name, st->arg, strlen(ds->device_name)) == 0 &&
+	    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
-	    return snpack(symon_buf, maxlen, dev, MT_IO2,
+	    return snpack(symon_buf, maxlen, st->arg, MT_IO2,
 			  ds->operations[DEVSTAT_READ],
 			  ds->operations[DEVSTAT_WRITE],
 			  (uint64_t) 0, /* don't know how to find #seeks */
@@ -127,7 +126,7 @@ get_io(char *symon_buf, int maxlen, char *dev)
 			  ds->bytes[DEVSTAT_WRITE]);
 
 #else
-	    return snpack(symon_buf, maxlen, dev, MT_IO2,
+	    return snpack(symon_buf, maxlen, st->arg, MT_IO2,
 			  ds->num_reads,
 			  ds->num_writes,
 			  (uint64_t) 0, /* don't know how to find #seeks */

+ 10 - 12
symon/platform/FreeBSD/sm_mbuf.c

@@ -1,4 +1,4 @@
-/* $Id: sm_mbuf.c,v 1.3 2005/01/15 17:31:11 dijkstra Exp $ */
+/* $Id: sm_mbuf.c,v 1.5 2005/10/18 19:58:06 dijkstra Exp $ */
 
 /*
  * Copyright (c) 2004 Matthew Gream
@@ -46,9 +46,8 @@ static char mbstat_mib_str[] = "kern.ipc.mbstat";
 static int mbstat_mib[CTL_MAXNAME];
 static size_t mbstat_len = 0;
 
-/* Prepare if module for first use */
 void
-init_mbuf(char *s)
+init_mbuf(struct stream *st)
 {
     mbstat_len = CTL_MAXNAME;
     if (sysctlnametomib(mbstat_mib_str, mbstat_mib, &mbstat_len) < 0) {
@@ -56,12 +55,11 @@ init_mbuf(char *s)
 	mbstat_len = 0;
     }
 
-    info("started module mbuf(%.200s)", s);
+    info("started module mbuf(%.200s)", st->arg);
 }
 
-/* Get mbuf statistics */
 int
-get_mbuf(char *symon_buf, int maxlen, char *arg)
+get_mbuf(char *symon_buf, int maxlen, struct stream *st)
 {
     struct mbstat mbstat;
 #ifdef KERN_POOL
@@ -80,7 +78,7 @@ get_mbuf(char *symon_buf, int maxlen, char *arg)
 
     size = sizeof(mbstat);
     if (sysctl(mbstat_mib, mbstat_len, &mbstat, &size, NULL, 0) < 0) {
-	warning("mbuf(%.200s) failed (sysctl() %.200s)", arg, strerror(errno));
+	warning("mbuf(%.200s) failed (sysctl() %.200s)", st->arg, strerror(errno));
 	return (0);
     }
 
@@ -90,7 +88,7 @@ get_mbuf(char *symon_buf, int maxlen, char *arg)
     mib[2] = KERN_POOL_NPOOLS;
     size = sizeof(npools);
     if (sysctl(mib, 3, &npools, &size, NULL, 0) < 0) {
-	warning("mbuf(%.200s) failed (sysctl() %.200s)", arg, strerror(errno));
+	warning("mbuf(%.200s) failed (sysctl() %.200s)", st->arg, strerror(errno));
 	return (0);
     }
 
@@ -101,14 +99,14 @@ get_mbuf(char *symon_buf, int maxlen, char *arg)
 	mib[3] = i;
 	size = sizeof(pool);
 	if (sysctl(mib, 4, &pool, &size, NULL, 0) < 0) {
-	    warning("mbuf(%.200s) failed (sysctl() %.200s)", arg, strerror(errno));
+	    warning("mbuf(%.200s) failed (sysctl() %.200s)", st->arg, strerror(errno));
 	    return (0);
 	}
 	npools--;
 	mib[2] = KERN_POOL_NAME;
 	size = sizeof(name);
 	if (sysctl(mib, 4, name, &size, NULL, 0) < 0) {
-	    warning("mbuf(%.200s) failed (sysctl() %.200s)", arg, strerror(errno));
+	    warning("mbuf(%.200s) failed (sysctl() %.200s)", st->arg, strerror(errno));
 	    return (0);
 	}
 	if (!strcmp(name, "mbpl")) {
@@ -122,7 +120,7 @@ get_mbuf(char *symon_buf, int maxlen, char *arg)
 	    break;
     }
     if (flag != 3) {
-	warning("mbuf(%.200s) failed (flag != 3)", arg);
+	warning("mbuf(%.200s) failed (flag != 3)", st->arg);
 	return (0);
     }
 #endif
@@ -170,7 +168,7 @@ get_mbuf(char *symon_buf, int maxlen, char *arg)
 #endif
     stats[14] = mbstat.m_drain;
 
-    return snpack(symon_buf, maxlen, arg, MT_MBUF,
+    return snpack(symon_buf, maxlen, st->arg, MT_MBUF,
 		  stats[0],
 		  stats[1],
 		  stats[2],

+ 13 - 11
symon/platform/FreeBSD/sm_mem.c

@@ -1,4 +1,4 @@
-/* $Id: sm_mem.c,v 1.4 2005/03/20 16:17:22 dijkstra Exp $ */
+/* $Id: sm_mem.c,v 1.8 2005/10/18 19:58:06 dijkstra Exp $ */
 
 /*
  * Copyright (c) 2004      Matthew Gream
@@ -34,8 +34,6 @@
  * Get current memory statistics in bytes; reports them back in symon_buf as
  *
  * real active : real total : free : [swap used : swap total]
- *
- * This code is not re-entrant.
  */
 
 #include "conf.h"
@@ -75,9 +73,8 @@ static long me_stats[5];
 static struct vmtotal me_vmtotal;
 static size_t me_vmsize = sizeof(struct vmtotal);
 
-/* Prepare mem module for first use */
 void
-init_mem(char *s)
+init_mem(struct stream *st)
 {
     me_pagesize = sysconf(_SC_PAGESIZE);
     me_pageshift = 0;
@@ -98,11 +95,17 @@ init_mem(char *s)
 	me_vmiswp_mib_len = 0;
     }
 
-    info("started module mem(%.200s)", s);
+    info("started module mem(%.200s)", st->arg);
+}
+
+void
+gets_mem()
+{
+    /* EMPTY */
 }
-/* Get memory statistics */
+
 int
-get_mem(char *symon_buf, int maxlen, char *s)
+get_mem(char *symon_buf, int maxlen, struct stream *st)
 {
 #ifdef HAS_XSWDEV
     int i;
@@ -118,6 +121,7 @@ get_mem(char *symon_buf, int maxlen, char *s)
     me_stats[0] = pagetob(me_vmtotal.t_arm);
     me_stats[1] = pagetob(me_vmtotal.t_rm);
     me_stats[2] = pagetob(me_vmtotal.t_free);
+    me_stats[3] = me_stats[4] = 0;
 
 #ifdef HAS_XSWDEV
     vmnswp_siz = sizeof (int);
@@ -134,11 +138,9 @@ get_mem(char *symon_buf, int maxlen, char *s)
 	me_stats[3] += (vmiswp_dat.xsw_used * DEV_BSIZE);
 	me_stats[4] += (vmiswp_dat.xsw_nblks * DEV_BSIZE);
     }
-#else
-    me_stats[3] = me_stats[4] = 0;
 #endif
 
-    return snpack(symon_buf, maxlen, s, MT_MEM,
+    return snpack(symon_buf, maxlen, st->arg, MT_MEM,
 		  me_stats[0], me_stats[1], me_stats[2],
 		  me_stats[3], me_stats[4]);
 }

+ 56 - 46
symon/platform/FreeBSD/sm_pf.c

@@ -1,4 +1,4 @@
-/* $Id: sm_pf.c,v 1.2 2005/01/15 17:31:11 dijkstra Exp $ */
+/* $Id: sm_pf.c,v 1.4 2005/10/18 19:58:06 dijkstra Exp $ */
 
 /*
  * Copyright (c) 2002 Daniel Hartmeier
@@ -66,13 +66,15 @@ void
 privinit_pf()
 {
 }
+
 void
-init_pf(char *s)
+init_pf(struct stream *st)
 {
     fatal("pf support not available");
 }
+
 int
-get_pf(char *symon_buf, int maxlen, char *s)
+get_pf(char *symon_buf, int maxlen, struct stream *st)
 {
     fatal("pf support not available");
     return 0;
@@ -82,67 +84,75 @@ get_pf(char *symon_buf, int maxlen, char *s)
 
 /* Globals for this module start with pf_ */
 int pf_dev = -1;
-/* Priviledged init, called before priviledges are dropped */
+struct pf_status pf_stat;
+
 void
 privinit_pf()
 {
-    if ((pf_dev = open("/dev/pf", O_RDONLY)) == -1)
+    if ((pf_dev = open("/dev/pf", O_RDONLY)) == -1) {
 	warning("could not open \"/dev/pf\", %.200s", strerror(errno));
+    }
 }
-/* Prepare if module for first use */
+
 void
-init_pf(char *s)
+init_pf(struct stream *st)
 {
-    if (pf_dev == -1)
+    if (pf_dev == -1) {
 	privinit_pf();
+    }
 
-    info("started module pf(%.200s)", s);
+    info("started module pf()");
 }
-/* Get pf statistics */
-int
-get_pf(char *symon_buf, int maxlen, char *arg)
-{
-    struct pf_status s;
-    u_int64_t n;
 
+void
+gets_pf()
+{
     if (pf_dev == -1) {
-	warning("pf(%.200s) failed (dev == -1)", arg);
-	return 0;
+	warning("could not get pf stats (dev == -1)");
+	pf_stat.running = 0;
+	return;
     }
 
-    if (ioctl(pf_dev, DIOCGETSTATUS, &s)) {
-	warning("pf(%.200s) failed (ioctl error)", arg);
-	return 0;
+    if (ioctl(pf_dev, DIOCGETSTATUS, &pf_stat)) {
+	warning("could not get pf stats (ioctl error)");
+	pf_stat.running = 0;
+	return;
     }
+}
 
-    if (!s.running)
+int
+get_pf(char *symon_buf, int maxlen, struct stream *st)
+{
+    u_int64_t n;
+
+    if (!pf_stat.running) {
 	return 0;
+    }
 
-    n = s.states;
-    return snpack(symon_buf, maxlen, arg, MT_PF,
-		  s.bcounters[0][0],
-		  s.bcounters[0][1],
-		  s.bcounters[1][0],
-		  s.bcounters[1][1],
-		  s.pcounters[0][0][PF_PASS],
-		  s.pcounters[0][0][PF_DROP],
-		  s.pcounters[0][1][PF_PASS],
-		  s.pcounters[0][1][PF_DROP],
-		  s.pcounters[1][0][PF_PASS],
-		  s.pcounters[1][0][PF_DROP],
-		  s.pcounters[1][1][PF_PASS],
-		  s.pcounters[1][1][PF_DROP],
+    n = pf_stat.states;
+    return snpack(symon_buf, maxlen, st->arg, MT_PF,
+		  pf_stat.bcounters[0][0],
+		  pf_stat.bcounters[0][1],
+		  pf_stat.bcounters[1][0],
+		  pf_stat.bcounters[1][1],
+		  pf_stat.pcounters[0][0][PF_PASS],
+		  pf_stat.pcounters[0][0][PF_DROP],
+		  pf_stat.pcounters[0][1][PF_PASS],
+		  pf_stat.pcounters[0][1][PF_DROP],
+		  pf_stat.pcounters[1][0][PF_PASS],
+		  pf_stat.pcounters[1][0][PF_DROP],
+		  pf_stat.pcounters[1][1][PF_PASS],
+		  pf_stat.pcounters[1][1][PF_DROP],
 		  n,
-		  s.fcounters[0],
-		  s.fcounters[1],
-		  s.fcounters[2],
-		  s.counters[0],
-		  s.counters[1],
-		  s.counters[2],
-		  s.counters[3],
-		  s.counters[4],
-		  s.counters[5]
+		  pf_stat.fcounters[0],
+		  pf_stat.fcounters[1],
+		  pf_stat.fcounters[2],
+		  pf_stat.counters[0],
+		  pf_stat.counters[1],
+		  pf_stat.counters[2],
+		  pf_stat.counters[3],
+		  pf_stat.counters[4],
+		  pf_stat.counters[5]
 	);
 }
-
-#endif
+#endif /* HAS_PFVAR_H */

+ 47 - 39
symon/platform/FreeBSD/sm_pfq.c

@@ -1,4 +1,4 @@
-/* $Id: sm_pfq.c,v 1.1 2005/03/20 16:17:22 dijkstra Exp $ */
+/* $Id: sm_pfq.c,v 1.3 2005/10/18 19:58:06 dijkstra Exp $ */
 
 /*
  * Copyright (c) 2005 J. Martin Petersen
@@ -33,8 +33,6 @@
 /*
  * Get current altq statistics from pf and return them in symon_buf as
  * sent_bytes : sent_packets : drop_bytes : drop_packets
- *
- * Non re-entrant code: gets_pfq messes with the globals without locking.
  */
 
 #include "conf.h"
@@ -69,11 +67,13 @@ privinit_pfq()
 {
     fatal("pf support not available");
 }
+
 void
-init_pfq(char *s)
+init_pfq(struct stream *st)
 {
     fatal("pf support not available");
 }
+
 void
 gets_pfq()
 {
@@ -81,7 +81,7 @@ gets_pfq()
 }
 
 int
-get_pfq(char *b, int l, char *s)
+get_pfq(char *b, int l, struct stream *st)
 {
   fatal("pf support not available");
   return 0;
@@ -96,12 +96,12 @@ union class_stats {
 };
 
 /*
- * We don't reuse the data structures from altq/altq_{cbq|hfsc|priq}.h as they
+ * We do not use the data structures from altq/altq_{cbq|hfsc|priq}.h as they
  * are overly complex. For now we only grab the interesting stuff.
  */
 
 struct altq_stats {
-    char qname[PF_QNAME_SIZE];
+    char qname[PF_QNAME_SIZE + IFNAMSIZ + 1];
     u_int64_t sent_bytes;
     u_int64_t sent_packets;
     u_int64_t drop_bytes;
@@ -109,7 +109,8 @@ struct altq_stats {
 };
 
 static struct altq_stats *pfq_stats = NULL;
-static int pfq_numstats = 0;
+static int pfq_cur = 0;
+static int pfq_max = 0;
 int pfq_dev = -1;
 
 void
@@ -121,13 +122,13 @@ privinit_pfq()
 }
 
 void
-init_pfq(char *s)
+init_pfq(struct stream *st)
 {
     if (pfq_dev == -1) {
 	privinit_pfq();
     }
 
-    info("started module pfq(%.200s)",s);
+    info("started module pfq(%.200s)", st->arg);
 }
 
 void
@@ -148,16 +149,25 @@ gets_pfq()
     }
     nqs = qs.nr;
 
-    if (nqs > pfq_numstats) {
+    /* Allocate memory for info for the nqs queues */
+    if (nqs > pfq_max) {
 	if (pfq_stats) {
 	    xfree(pfq_stats);
 	}
 
-	pfq_stats = xmalloc(nqs * sizeof(struct altq_stats));
-	pfq_numstats = nqs;
+	pfq_max = 2 * nqs;
+
+	if (pfq_max > SYMON_MAX_DOBJECTS) {
+	    fatal("%s:%d: dynamic object limit (%d) exceeded for pf queue structures",
+		  __FILE__, __LINE__, SYMON_MAX_DOBJECTS);
+	}
+
+	pfq_stats = xmalloc(pfq_max * sizeof(struct altq_stats));
     }
 
-    /* loop through the queues, copy info */
+    pfq_cur = 0;
+
+    /* Loop through the queues, copy info */
     for (i = 0; i < nqs; i++) {
 	qs.nr = i;
 	if (ioctl(pfq_dev, DIOCGETALTQ, &qs)) {
@@ -175,59 +185,57 @@ gets_pfq()
 		fatal("pfq: DIOCGETQSTATS failed");
 	    }
 
-	    strncpy(pfq_stats[i].qname, qs.altq.qname, PF_QNAME_SIZE);
+	    /* We're now ready to copy the data we want. */
+	    snprintf(pfq_stats[pfq_cur].qname, sizeof(pfq_stats[0].qname),
+		     "%s/%s", qs.altq.ifname, qs.altq.qname);
 
 	    switch (qs.altq.scheduler) {
 	    case ALTQT_CBQ:
-		pfq_stats[i].sent_bytes = q.cbq.xmit_cnt.bytes;
-		pfq_stats[i].sent_packets = q.cbq.xmit_cnt.packets;
-		pfq_stats[i].drop_bytes = q.cbq.drop_cnt.bytes;
-		pfq_stats[i].drop_packets = q.cbq.drop_cnt.packets;
+		pfq_stats[pfq_cur].sent_bytes = q.cbq.xmit_cnt.bytes;
+		pfq_stats[pfq_cur].sent_packets = q.cbq.xmit_cnt.packets;
+		pfq_stats[pfq_cur].drop_bytes = q.cbq.drop_cnt.bytes;
+		pfq_stats[pfq_cur].drop_packets = q.cbq.drop_cnt.packets;
 		break;
 
 	    case ALTQT_PRIQ:
-		pfq_stats[i].sent_bytes = q.priq.xmitcnt.bytes;
-		pfq_stats[i].sent_packets = q.priq.xmitcnt.packets;
-		pfq_stats[i].drop_bytes = q.priq.dropcnt.bytes;
-		pfq_stats[i].drop_packets = q.priq.dropcnt.packets;
+		pfq_stats[pfq_cur].sent_bytes = q.priq.xmitcnt.bytes;
+		pfq_stats[pfq_cur].sent_packets = q.priq.xmitcnt.packets;
+		pfq_stats[pfq_cur].drop_bytes = q.priq.dropcnt.bytes;
+		pfq_stats[pfq_cur].drop_packets = q.priq.dropcnt.packets;
 		break;
 
 	    case ALTQT_HFSC:
-		pfq_stats[i].sent_bytes = q.hfsc.xmit_cnt.bytes;
-		pfq_stats[i].sent_packets = q.hfsc.xmit_cnt.packets;
-		pfq_stats[i].drop_bytes = q.hfsc.drop_cnt.bytes;
-		pfq_stats[i].drop_packets = q.hfsc.drop_cnt.packets;
+		pfq_stats[pfq_cur].sent_bytes = q.hfsc.xmit_cnt.bytes;
+		pfq_stats[pfq_cur].sent_packets = q.hfsc.xmit_cnt.packets;
+		pfq_stats[pfq_cur].drop_bytes = q.hfsc.drop_cnt.bytes;
+		pfq_stats[pfq_cur].drop_packets = q.hfsc.drop_cnt.packets;
 		break;
 
 	    default:
-		warning("pfq: unknown altq scheduler type (%d) encountered",
-			qs.altq.scheduler);
+		warning("pfq: unknown altq scheduler type encountered");
 		break;
 	    }
-	} else {
-	    /* Make sure the lookup in get_pfq fails immediately whenever
-	     * there's no queue in the slot. We do this by nul'ing the name */
-	    pfq_stats[i].qname[0] = '\0';
+	    pfq_cur++;
 	}
     }
 }
 
 int
-get_pfq(char *symon_buf, int maxlen, char *queue)
+get_pfq(char *symon_buf, int maxlen, struct stream *st)
 {
     unsigned int i;
 
-    for (i = 0; i < pfq_numstats; i++) {
-	if (strncmp(pfq_stats[i].qname, queue, PF_QNAME_SIZE) == 0) {
-	    return snpack(symon_buf, maxlen, queue, MT_PFQ,
+    for (i = 0; i < pfq_cur; i++) {
+	if (strncmp(pfq_stats[i].qname, st->arg, sizeof(pfq_stats[0].qname)) == 0) {
+	    return snpack(symon_buf, maxlen, st->arg, MT_PFQ,
 			  pfq_stats[i].sent_bytes,
 			  pfq_stats[i].sent_packets,
 			  pfq_stats[i].drop_bytes,
-			  pfq_stats[i].drop_packets);
+			  pfq_stats[i].drop_packets
+		);
 	}
     }
 
     return 0;
 }
-
 #endif

+ 27 - 24
symon/platform/FreeBSD/sm_proc.c

@@ -1,4 +1,4 @@
-/* $Id: sm_proc.c,v 1.4 2005/03/20 16:17:22 dijkstra Exp $ */
+/* $Id: sm_proc.c,v 1.7 2005/10/18 19:58:06 dijkstra Exp $ */
 
 /*
  * Copyright (c) 2004      Matthew Gream
@@ -35,8 +35,6 @@
  *
  * number of processes : ticks_user : ticks_system : ticks_interrupt :
  * cpuseconds : procsizes : resident segment sizes
- *
- * Non re-entrant code: gets_proc messes with globals r/w without a semaphore.
  */
 
 #include "conf.h"
@@ -121,20 +119,31 @@ gets_proc()
 	proc_cur = size / sizeof(struct kinfo_proc);
     }
 }
-/* Prepare io module for first use */
+
 void
-init_proc(char *s)
+privinit_proc()
 {
-    int mib[2] = {CTL_KERN, KERN_CLOCKRATE};
-    struct clockinfo cinf;
-    size_t size = sizeof(cinf);
 #ifdef HAS_KI_PADDR
     char errbuf[_POSIX2_LINE_MAX];
+
+    proc_kd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf);
+    if (proc_kd == NULL) {
+	warning("while opening kvm (chrooted?): %s", errbuf);
+    }
 #endif
+}
+
+void
+init_proc(struct stream *st)
+{
+    int mib[2] = {CTL_KERN, KERN_CLOCKRATE};
+    struct clockinfo cinf;
+    size_t size = sizeof(cinf);
 
     /* get clockrate */
-    if (sysctl(mib, 2, &cinf, &size, NULL, 0) == -1)
+    if (sysctl(mib, 2, &cinf, &size, NULL, 0) == -1) {
 	fatal("%s:%d: could not get clockrate", __FILE__, __LINE__);
+    }
 
     proc_stathz = cinf.stathz;
 
@@ -146,17 +155,11 @@ init_proc(char *s)
 	proc_pagesize >>= 1;
     }
 
-#ifdef HAS_KI_PADDR
-    proc_kd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf);
-    if (proc_kd == NULL)
-      warning("while opening kvm (chrooted?): %s", errbuf);
-#endif
-
-    info("started module proc(%.200s)", s);
+    info("started module proc(%.200s)", st->arg);
 }
-/* Get new io statistics */
+
 int
-get_proc(char *symon_buf, int maxlen, char *process)
+get_proc(char *symon_buf, int maxlen, struct stream *st)
 {
     int i;
     struct kinfo_proc *pp;
@@ -176,15 +179,15 @@ get_proc(char *symon_buf, int maxlen, char *process)
 
     for (pp = proc_ps, i = 0; i < proc_cur; pp++, i++) {
 #ifdef HAS_KI_PADDR
-	if (strncmp(process, pp->ki_comm, strlen(process)) == 0) {
+	if (strncmp(st->arg, pp->ki_comm, strlen(st->arg)) == 0) {
 	    /* cpu time - accumulated */
 	    if (proc_kd) {
 		if (kvm_read(proc_kd, (unsigned long)pp->ki_paddr, &pproc,
 			     sizeof(pproc)) == sizeof(pproc)) {
 #ifdef HAS_RUSAGE_EXT
-		    cpu_uticks += pproc.p_rux.p_uticks;  /* user */
-		    cpu_sticks += pproc.p_rux.p_sticks;  /* sys  */
-		    cpu_iticks += pproc.p_rux.p_iticks;  /* int  */
+		    cpu_uticks += pproc.p_rux.rux_uticks;  /* user */
+		    cpu_sticks += pproc.p_rux.rux_sticks;  /* sys  */
+		    cpu_iticks += pproc.p_rux.rux_iticks;  /* int  */
 #else
 		    cpu_uticks += pproc.p_uticks;  /* user */
 		    cpu_sticks += pproc.p_sticks;  /* sys  */
@@ -203,7 +206,7 @@ get_proc(char *symon_buf, int maxlen, char *process)
 				    pp->ki_ssize); /* stack */
 	    mem_rss += pagetob(pp->ki_rssize);     /* rss  */
 #else
-	if (strncmp(process, pp->kp_proc.p_comm, strlen(process)) == 0) {
+	if (strncmp(st->arg, pp->kp_proc.p_comm, strlen(st->arg)) == 0) {
 	    /* cpu time - accumulated */
 	    cpu_uticks += pp->kp_proc.p_uticks;  /* user */
 	    cpu_sticks += pp->kp_proc.p_sticks;  /* sys  */
@@ -226,7 +229,7 @@ get_proc(char *symon_buf, int maxlen, char *process)
     cpu_ticks = cpu_uticks + cpu_sticks + cpu_iticks;
     cpu_secs = cpu_ticks / proc_stathz;
 
-    return snpack(symon_buf, maxlen, process, MT_PROC,
+    return snpack(symon_buf, maxlen, st->arg, MT_PROC,
 		  n,
 		  cpu_uticks, cpu_sticks, cpu_iticks, cpu_secs, cpu_pcti,
 		  mem_procsize, mem_rss );

+ 19 - 2
symon/platform/Linux/platform.h

@@ -1,21 +1,38 @@
-/* $Id: platform.h,v 1.1 2004/08/07 12:21:36 dijkstra Exp $ */
+/* $Id: platform.h,v 1.3 2005/10/21 14:58:44 dijkstra Exp $ */
 
 #ifndef _CONF_LINUX_H
 #define _CONF_LINUX_H
 
 #include <stdio.h>
 #include <grp.h>
+
 #include "queue.h"
+#include "sylimits.h"
 
 #define SYMON_USER      "symon"
 #define SEM_ARGS        (S_IWUSR|S_IRUSR|IPC_CREAT|IPC_EXCL)
 #define SA_LEN(x)       (((x)->sa_family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in))
 #define SS_LEN(x)       (((x)->ss_family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in))
+#define strlcpy(x,y,z)  snprintf((x),(z),"%s", (y))
 
 union semun {
 	int val;
 };
 
-#define strlcpy(x,y,z)  snprintf((x),(z),"%s", (y))
+#define CPUSTATES 4
+#define CP_USER 0
+#define CP_NICE 1
+#define CP_SYS  2
+#define CP_IDLE 3
+
+union stream_parg {
+    struct {
+	long time[CPUSTATES];
+	long old[CPUSTATES];
+	long diff[CPUSTATES];
+	int states[CPUSTATES];
+	char name[6];
+    } cp;
+};
 
 #endif

+ 30 - 46
symon/platform/Linux/sm_cpu.c

@@ -1,11 +1,11 @@
-/* $Id: sm_cpu.c,v 1.1 2004/08/08 17:21:18 dijkstra Exp $ */
+/* $Id: sm_cpu.c,v 1.4 2005/10/21 14:58:44 dijkstra Exp $ */
 
 /* The author of this code is Willem Dijkstra (wpd@xs4all.nl).
  *
  * The percentages function was written by William LeFebvre and is part
  * of the 'top' utility. His copyright statement is below.
  *
- * Copyright (c) 2001-2004 Willem Dijkstra
+ * Copyright (c) 2001-2005 Willem Dijkstra
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -50,10 +50,6 @@
  * and returns them in symon_buf as
  *
  * 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 <sys/types.h>
@@ -72,12 +68,6 @@
 #include "symon.h"
 #include "xmalloc.h"
 
-#define CPUSTATES 4
-#define CP_USER 0
-#define CP_NICE 1
-#define CP_SYS  2
-#define CP_IDLE 3
-
 __BEGIN_DECLS
 int percentages(int, int *, long *, long *, long *);
 __END_DECLS
@@ -86,10 +76,6 @@ __END_DECLS
 static void *cp_buf = NULL;
 static int cp_size = 0;
 static int cp_maxsize = 0;
-static long cp_time[SYMON_MAXCPUS][CPUSTATES];
-static long cp_old[SYMON_MAXCPUS][CPUSTATES];
-static long cp_diff[SYMON_MAXCPUS][CPUSTATES];
-static int cp_states[SYMON_MAXCPUS][CPUSTATES];
 /*
  *  percentages(cnt, out, new, old, diffs) - calculate percentage change
  *      between array "old" and "new", putting the percentages i "out".
@@ -133,9 +119,9 @@ percentages(int cnt, int *out, register long *new, register long *old, long *dif
     /* return the total in case the caller wants to use it */
     return total_change;
 }
-/* Prepare cpu module for use */
+
 void
-init_cpu(char *s)
+init_cpu(struct stream *st)
 {
     char buf[SYMON_MAX_OBJSIZE];
 
@@ -144,12 +130,18 @@ init_cpu(char *s)
 	cp_buf = xmalloc(cp_maxsize);
     }
 
+    if (st->arg != NULL && isdigit(*st->arg)) {
+	snprintf(st->parg.cp.name, sizeof(st->parg.cp.name), "cpu%s", st->arg);
+    } else {
+	snprintf(st->parg.cp.name, sizeof(st->parg.cp.name), "cpu");
+    }
+
     gets_cpu();
-    /* Call get_cpu once to fill the cp_old structure */
-    get_cpu(buf, sizeof(buf), s);
+    get_cpu(buf, sizeof(buf), st);
 
-    info("started module cpu(%.200s)", s);
+    info("started module cpu(%.200s)", st->arg);
 }
+
 void
 gets_cpu()
 {
@@ -180,46 +172,38 @@ gets_cpu()
 	warning("could not read if statistics from /proc/stat: %.200s", strerror(errno));
     }
 }
-/* Get new cpu measurements */
+
 int
-get_cpu(char *symon_buf, int maxlen, char *s)
+get_cpu(char *symon_buf, int maxlen, struct stream *st)
 {
-    char cpuname[SYMON_MAX_OBJSIZE];
-    int nr = 0;
     char *line;
 
     if (cp_size <= 0) {
 	return 0;
     }
 
-    bzero(&cpuname, sizeof(cpuname));
-    if (s != NULL && isdigit(*s)) {
-	snprintf(cpuname, sizeof(cpuname), "cpu%s", s);
-	nr = strtol(s, NULL, 10);
-    } else {
-	snprintf(cpuname, sizeof(cpuname), "cpu");
-	nr = 0;
-    }
-
-    if ((line = strstr(cp_buf, cpuname)) == NULL) {
-	warning("could not find %s", &cpuname);
+    if ((line = strstr(cp_buf, st->parg.cp.name)) == NULL) {
+	warning("could not find %s", st->parg.cp.name);
 	return 0;
     }
 
-    line += strlen(cpuname);
+    line += strlen(st->parg.cp.name);
     if (4 > sscanf(line, "%lu %lu %lu %lu\n",
-		   &cp_time[nr][CP_USER], &cp_time[nr][CP_NICE],
-		   &cp_time[nr][CP_SYS], &cp_time[nr][CP_IDLE])) {
-	warning("could not parse cpu statistics for %.200s", &cpuname);
+		   &st->parg.cp.time[CP_USER],
+		   &st->parg.cp.time[CP_NICE],
+		   &st->parg.cp.time[CP_SYS],
+		   &st->parg.cp.time[CP_IDLE])) {
+	warning("could not parse cpu statistics for %.200s", &st->parg.cp.name);
 	return 0;
     }
 
-    percentages(CPUSTATES, cp_states[nr], cp_time[nr], cp_old[nr], cp_diff[nr]);
+    percentages(CPUSTATES, st->parg.cp.states, st->parg.cp.time,
+		st->parg.cp.old, st->parg.cp.diff);
 
-    return snpack(symon_buf, maxlen, s, MT_CPU,
-		  (double) (cp_states[nr][CP_USER] / 10.0),
-		  (double) (cp_states[nr][CP_NICE] / 10.0),
-		  (double) (cp_states[nr][CP_SYS] / 10.0),
+    return snpack(symon_buf, maxlen, st->arg, MT_CPU,
+		  (double) (st->parg.cp.states[CP_USER] / 10.0),
+		  (double) (st->parg.cp.states[CP_NICE] / 10.0),
+		  (double) (st->parg.cp.states[CP_SYS] / 10.0),
 		  (double) (0),
-		  (double) (cp_states[nr][CP_IDLE] / 10.0));
+		  (double) (st->parg.cp.states[CP_IDLE] / 10.0));
 }

+ 29 - 29
symon/platform/Linux/sm_if.c

@@ -1,7 +1,7 @@
-/* $Id: sm_if.c,v 1.3 2004/08/08 17:21:18 dijkstra Exp $ */
+/* $Id: sm_if.c,v 1.6 2005/10/19 20:06:05 dijkstra Exp $ */
 
 /*
- * Copyright (c) 2001-2004 Willem Dijkstra
+ * Copyright (c) 2001-2005 Willem Dijkstra
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -35,7 +35,6 @@
  *
  * ipackets : opackets : ibytes : obytes : imcasts : omcasts : ierrors :
  * oerrors : colls : drops
- *
  */
 
 #include <sys/types.h>
@@ -57,34 +56,35 @@ static int if_size = 0;
 static int if_maxsize = 0;
 struct if_device_stats
 {
-	unsigned long   rx_packets;             /* total packets received       */
-	unsigned long   tx_packets;             /* total packets transmitted    */
-	unsigned long   rx_bytes;               /* total bytes received         */
-	unsigned long   tx_bytes;               /* total bytes transmitted      */
-	unsigned long   rx_errors;              /* bad packets received         */
-	unsigned long   tx_errors;              /* packet transmit problems     */
-	unsigned long   rx_dropped;             /* no space in linux buffers    */
-	unsigned long   tx_dropped;             /* no space available in linux  */
-	unsigned long   multicast;              /* multicast packets received   */
-	unsigned long   collisions;
-	unsigned long   rx_frame_errors;        /* recv'd frame alignment error */
-	unsigned long   rx_fifo_errors;         /* recv'r fifo overrun          */
-	unsigned long   tx_carrier_errors;
-	unsigned long   tx_fifo_errors;
-	unsigned long   rx_compressed;
-	unsigned long   tx_compressed;
+    unsigned long   rx_packets;             /* total packets received       */
+    unsigned long   tx_packets;             /* total packets transmitted    */
+    unsigned long   rx_bytes;               /* total bytes received         */
+    unsigned long   tx_bytes;               /* total bytes transmitted      */
+    unsigned long   rx_errors;              /* bad packets received         */
+    unsigned long   tx_errors;              /* packet transmit problems     */
+    unsigned long   rx_dropped;             /* no space in linux buffers    */
+    unsigned long   tx_dropped;             /* no space available in linux  */
+    unsigned long   multicast;              /* multicast packets received   */
+    unsigned long   collisions;
+    unsigned long   rx_frame_errors;        /* recv'd frame alignment error */
+    unsigned long   rx_fifo_errors;         /* recv'r fifo overrun          */
+    unsigned long   tx_carrier_errors;
+    unsigned long   tx_fifo_errors;
+    unsigned long   rx_compressed;
+    unsigned long   tx_compressed;
 };
-/* Prepare if module for first use */
+
 void
-init_if(char *s)
+init_if(struct stream *st)
 {
     if (if_buf == NULL) {
 	if_maxsize = SYMON_MAX_OBJSIZE;
 	if_buf = xmalloc(if_maxsize);
     }
 
-    info("started module if(%.200s)", s);
+    info("started module if(%.200s)", st->arg);
 }
+
 void
 gets_if()
 {
@@ -115,9 +115,9 @@ gets_if()
 	warning("could not read if statistics from /proc/net/dev: %.200s", strerror(errno));
     }
 }
-/* Get interface statistics */
+
 int
-get_if(char *symon_buf, int maxlen, char *interface)
+get_if(char *symon_buf, int maxlen, struct stream *st)
 {
     char *line;
     struct if_device_stats stats;
@@ -126,12 +126,12 @@ get_if(char *symon_buf, int maxlen, char *interface)
 	return 0;
     }
 
-    if ((line = strstr(if_buf, interface)) == NULL) {
-	warning("could not find interface %s", interface);
+    if ((line = strstr(if_buf, st->arg)) == NULL) {
+	warning("could not find interface %s", st->arg);
 	return 0;
     }
 
-    line += strlen(interface);
+    line += strlen(st->arg);
     bzero(&stats, sizeof(struct if_device_stats));
 
     /* Inter-|   Receive                                                |  Transmit
@@ -142,11 +142,11 @@ get_if(char *symon_buf, int maxlen, char *interface)
 		    &stats.rx_frame_errors, &stats.rx_compressed, &stats.multicast,
 		    &stats.tx_bytes, &stats.tx_packets, &stats.tx_errors, &stats.tx_dropped, &stats.tx_fifo_errors,
 		    &stats.collisions, &stats.tx_carrier_errors, &stats.tx_compressed)) {
-	warning("could not parse interface statistics for %.200s", interface);
+	warning("could not parse interface statistics for %.200s", st->arg);
 	return 0;
     }
 
-    return snpack(symon_buf, maxlen, interface, MT_IF,
+    return snpack(symon_buf, maxlen, st->arg, MT_IF,
 		  stats.rx_packets,
 		  stats.tx_packets,
 		  stats.rx_bytes,

+ 135 - 0
symon/platform/Linux/sm_mem.c

@@ -0,0 +1,135 @@
+/* $Id: sm_mem.c,v 1.3 2005/10/19 20:06:05 dijkstra Exp $ */
+
+/*
+ * Copyright (c) 2005 Harm Schotanus
+ * 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 memory statistics in bytes; reports them back in symon_buf as
+ *
+ * real active : real total : free : [swap used : swap total]
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include "error.h"
+#include "conf.h"
+#include "symon.h"
+#include "xmalloc.h"
+
+#define ktob(size) ((size) << 10)
+
+/* Globals for this module all start with me_ */
+static void *me_buf = NULL;
+static int me_size = 0;
+static int me_maxsize = 0;
+static long me_stats[5];
+
+void
+init_mem(struct stream *st)
+{
+    if (me_buf == NULL) {
+	me_maxsize = SYMON_MAX_OBJSIZE;
+	me_buf = xmalloc(me_maxsize);
+    }
+
+    info("started module mem(%.200s)", st->arg);
+}
+
+void
+gets_mem()
+{
+   int fd;
+   if ((fd = open("/proc/meminfo", O_RDONLY)) < 0) {
+	warning("cannot access /proc/meminfo: %.200s", strerror(errno));
+   }
+
+   bzero(me_buf, me_maxsize);
+   me_size = read(fd, me_buf, me_maxsize);
+   close(fd);
+
+   if (me_size == me_maxsize) {
+	/* buffer is too small to hold all memory data */
+	me_maxsize += SYMON_MAX_OBJSIZE;
+	if (me_maxsize > SYMON_MAX_OBJSIZE * SYMON_MAX_DOBJECTS) {
+	    fatal("%s:%d: dynamic object limit (%d) exceeded for cp data",
+		__FILE__, __LINE__, SYMON_MAX_OBJSIZE * SYMON_MAX_DOBJECTS);
+	}
+	me_buf = xrealloc(me_buf, me_maxsize);
+	gets_mem();
+	return;
+    }
+
+   if (me_size == -1) {
+       warning("could not read if statistics from /proc/meminfo: %.200s", strerror(errno));
+   }
+}
+
+long
+mem_getitem(char *name)
+{
+    long stat;
+    char *line;
+
+    if (me_size <= 0) {
+	return 0;
+    }
+
+    if ((line = strstr(me_buf, name)) == NULL) {
+	warning("could not find %s in /proc/meminfo", name);
+	return 0;
+    }
+
+    line += strlen(name);
+    if (1 < sscanf(line, ": %lu Kb", &stat)) {
+	warning("could not parse memory statistics");
+	return 0;
+    } else {
+	return stat;
+    }
+}
+
+int
+get_mem(char *symon_buf, int maxlen, struct stream *st)
+{
+    me_stats[0] = ktob(mem_getitem("Active"));
+    me_stats[1] = ktob(mem_getitem("MemTotal"));
+    me_stats[2] = ktob(mem_getitem("MemFree"));
+    me_stats[3] = ktob(mem_getitem("SwapFree"));
+    me_stats[4] = ktob(mem_getitem("SwapTotal"));
+
+    me_stats[3] = me_stats[4] - me_stats[3];
+
+    return snpack(symon_buf, maxlen, st->arg, MT_MEM,
+		  me_stats[0], me_stats[1], me_stats[2],
+		  me_stats[3], me_stats[4]);
+}

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

@@ -1 +1 @@
-# $Id: Makefile.inc,v 1.1 2004/09/25 10:21:56 dijkstra Exp $
+# $Id: Makefile.inc,v 1.3 2005/10/21 14:58:45 dijkstra Exp $

+ 22 - 1
symon/platform/NetBSD/platform.h

@@ -1,9 +1,16 @@
-/* $Id: platform.h,v 1.1 2004/11/21 10:26:55 dijkstra Exp $ */
+/* $Id: platform.h,v 1.4 2005/10/21 14:58:45 dijkstra Exp $ */
 
 #ifndef _CONF_NETBSD_H
 #define _CONF_NETBSD_H
 
+#define _NETBSD_SOURCE 1
+
 #include <sys/queue.h>
+#include <sys/sched.h>
+
+#include <net/if.h>
+
+#include "sylimits.h"
 
 #define SYMON_USER      "_symon"
 #define SEM_ARGS        (IPC_W|IPC_R)
@@ -14,4 +21,18 @@ union semun {
 	int val;
 };
 
+union stream_parg {
+    struct {
+	u_int64_t time[CPUSTATES];
+	u_int64_t old[CPUSTATES];
+	u_int64_t diff[CPUSTATES];
+	int states[CPUSTATES];
+    } cp;
+    struct {
+	char rawdev[SYMON_DFNAMESIZE];
+    } df;
+    struct ifdatareq ifr;
+    int sn;
+};
+
 #endif

+ 21 - 24
symon/platform/NetBSD/sm_cpu.c

@@ -1,4 +1,4 @@
-/* $Id: sm_cpu.c,v 1.2 2004/08/08 17:21:18 dijkstra Exp $ */
+/* $Id: sm_cpu.c,v 1.4 2005/10/18 19:58:09 dijkstra Exp $ */
 
 /* The author of this code is Matthew Gream.
  *
@@ -71,10 +71,6 @@ __END_DECLS
 /* Globals for this module all start with cp_ */
 static int cp_time_mib[] = {CTL_KERN, KERN_CP_TIME};
 static size_t cp_size;
-static u_int64_t cp_time[CPUSTATES];
-static u_int64_t cp_old[CPUSTATES];
-static u_int64_t cp_diff[CPUSTATES];
-static int cp_states[CPUSTATES];
 /*
  *  percentages(cnt, out, new, old, diffs) - calculate percentage change
  *      between array "old" and "new", putting the percentages i "out".
@@ -118,38 +114,39 @@ percentages(int cnt, int *out, register u_int64_t *new, register u_int64_t *old,
     /* return the total in case the caller wants to use it */
     return total_change;
 }
-/* Prepare cpu module for use */
+
 void
-init_cpu(char *s)
+init_cpu(struct stream *st)
 {
-    cp_size = sizeof(cp_time);
-    get_cpu(0, 0, NULL);
+    char buf[SYMON_MAX_OBJSIZE];
+
+    cp_size = sizeof(st->parg.cp.time);
+    get_cpu(buf, sizeof(buf), st);
 
-    info("started module cpu(%.200s)", s);
+    info("started module cpu(%.200s)", st->arg);
 }
+
 void
 gets_cpu()
 {
+    /* EMPTY */
 }
-/* Get new cpu measurements */
+
 int
-get_cpu(char *symon_buf, int maxlen, char *s)
+get_cpu(char *symon_buf, int maxlen, struct stream *st)
 {
-    if (sysctl(cp_time_mib, 2, &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__);
 	return 0;
     }
 
     /* convert cp_time counts to percentages */
-    (void)percentages(CPUSTATES, cp_states, cp_time, cp_old, cp_diff);
-
-    if (!symon_buf)
-	return 0;
-
-    return snpack(symon_buf, maxlen, s, MT_CPU,
-		  (double) (cp_states[CP_USER] / 10.0),
-		  (double) (cp_states[CP_NICE] / 10.0),
-		  (double) (cp_states[CP_SYS] / 10.0),
-		  (double) (cp_states[CP_INTR] / 10.0),
-		  (double) (cp_states[CP_IDLE] / 10.0));
+    (void)percentages(CPUSTATES, st->parg.cp.states, st->parg.cp.time, st->parg.cp.old, st->parg.cp.diff);
+
+    return snpack(symon_buf, maxlen, st->arg, MT_CPU,
+		  (double) (st->parg.cp.states[CP_USER] / 10.0),
+		  (double) (st->parg.cp.states[CP_NICE] / 10.0),
+		  (double) (st->parg.cp.states[CP_SYS] / 10.0),
+		  (double) (st->parg.cp.states[CP_INTR] / 10.0),
+		  (double) (st->parg.cp.states[CP_IDLE] / 10.0));
 }

+ 9 - 11
symon/platform/NetBSD/sm_debug.c

@@ -1,8 +1,8 @@
-/* $Id: sm_debug.c,v 1.2 2005/02/04 09:49:26 dijkstra Exp $ */
+/* $Id: sm_debug.c,v 1.4 2005/10/18 19:58:09 dijkstra Exp $ */
 
 /*
  * Copyright (c) 2004      Matthew Gream
- * Copyright (c) 2001-2004 Willem Dijkstra
+ * Copyright (c) 2001-2005 Willem Dijkstra
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -35,7 +35,6 @@
  * Get current debug statistics from kernel and return them in symon_buf as
  *
  * debug0 : debug1 : ... : debug19
- *
  */
 
 #include <sys/param.h>
@@ -43,23 +42,22 @@
 
 #include <string.h>
 
+#include "conf.h"
 #include "error.h"
 #include "symon.h"
 
-#define SYMON_MAXDEBUGID      20 /* = CTL_DEBUG_MAXID; depends lib/data.h */
-
 /* Globals for this module start with db_ */
 static int db_mib[] = { CTL_DEBUG, 0, CTL_DEBUG_VALUE };
 static int db_v[SYMON_MAXDEBUGID];
-/* Prepare if module for first use */
+
 void
-init_debug(char *s)
+init_debug(struct stream *st)
 {
-    info("started module debug(%.200s)", s);
+    info("started module debug(%.200s)", st->arg);
 }
-/* Get debug statistics */
+
 int
-get_debug(char *symon_buf, int maxlen, char *s)
+get_debug(char *symon_buf, int maxlen, struct stream *st)
 {
     size_t len;
     int i;
@@ -73,7 +71,7 @@ get_debug(char *symon_buf, int maxlen, char *s)
 	sysctl(db_mib, sizeof(db_mib)/sizeof(int), &db_v[i], &len, NULL, 0);
     }
 
-    return snpack(symon_buf, maxlen, s, MT_DEBUG,
+    return snpack(symon_buf, maxlen, st->arg, MT_DEBUG,
 		  db_v[0], db_v[1], db_v[2], db_v[3], db_v[4], db_v[5], db_v[6],
 		  db_v[7], db_v[8], db_v[9], db_v[10], db_v[11], db_v[12], db_v[13],
 		  db_v[14], db_v[15], db_v[16], db_v[17], db_v[18], db_v[19]);

+ 108 - 0
symon/platform/NetBSD/sm_df.c

@@ -0,0 +1,108 @@
+/* $Id: sm_df.c,v 1.2 2005/10/18 19:58:11 dijkstra Exp $ */
+
+/*
+ * Copyright (c) 2005 Marc Balmer
+ * 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 df statistics and return them in symon_buf as
+ *
+ *   blocks : bfree : bavail : files : ffree : \
+ *   syncwrites : asyncwrites
+ */
+
+#include "conf.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/mount.h>
+#include <ufs/ufs/dinode.h>
+#include <ufs/ffs/fs.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <fstab.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "error.h"
+#include "symon.h"
+
+/* Globals for this module start with df_ */
+static struct statfs *df_stats = NULL;
+static int df_parts = 0;
+
+void
+init_df(struct stream *st)
+{
+    strlcpy(st->parg.df.rawdev, "/dev/", sizeof(st->parg.df.rawdev));
+    strlcat(st->parg.df.rawdev, st->arg, sizeof(st->parg.df.rawdev));
+
+    info("started module df(%.200s)", st->arg);
+}
+
+void
+gets_df()
+{
+    if ((df_parts = getmntinfo(&df_stats, MNT_NOWAIT)) == 0) {
+	warning("df failed");
+    }
+}
+
+/*
+ * from src/bin/df.c:
+ * Convert statfs returned filesystem size into BLOCKSIZE units.
+ * Attempts to avoid overflow for large filesystems.
+ */
+#define fsbtoblk(num, fsbs, bs) \
+	(((fsbs) != 0 && (fsbs) < (bs)) ? \
+		(num) / ((bs) / (fsbs)) : (num) * ((fsbs) / (bs)))
+
+int
+get_df(char *symon_buf, int maxlen, struct stream *st)
+{
+    int n;
+
+    for (n = 0; n < df_parts; n++) {
+	if (!strncmp(df_stats[n].f_mntfromname, st->parg.df.rawdev, SYMON_DFNAMESIZE)) {
+	    return snpack(symon_buf, maxlen, st->arg, MT_DF,
+			  (u_int64_t)fsbtoblk(df_stats[n].f_blocks, df_stats[n].f_bsize, SYMON_DFBLOCKSIZE),
+			  (u_int64_t)fsbtoblk(df_stats[n].f_bfree, df_stats[n].f_bsize, SYMON_DFBLOCKSIZE),
+			  (u_int64_t)fsbtoblk(df_stats[n].f_bavail, df_stats[n].f_bsize, SYMON_DFBLOCKSIZE),
+			  (u_int64_t)df_stats[n].f_files,
+			  (u_int64_t)df_stats[n].f_ffree,
+			  (u_int64_t)df_stats[n].f_syncwrites,
+			  (u_int64_t)df_stats[n].f_asyncwrites);
+	}
+    }
+
+    warning("df(%.200s) failed (no such device)", st->arg);
+    return 0;
+}

+ 17 - 16
symon/platform/NetBSD/sm_if.c

@@ -1,4 +1,4 @@
-/* $Id: sm_if.c,v 1.2 2004/08/07 14:48:35 dijkstra Exp $ */
+/* $Id: sm_if.c,v 1.4 2005/10/18 19:58:09 dijkstra Exp $ */
 
 /*
  * Copyright (c) 2004      Matthew Gream
@@ -35,7 +35,6 @@
  *
  * ipackets : opackets : ibytes : obytes : imcasts : omcasts : ierrors :
  * oerrors : colls : drops
- *
  */
 
 #include <sys/types.h>
@@ -58,37 +57,39 @@
 
 /* Globals for this module start with if_ */
 static int if_s = -1;
-/* Prepare if module for first use */
 void
-init_if(char *s)
+init_if(struct stream *st)
 {
-    if (if_s == -1)
-	if ((if_s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+    if (if_s == -1) {
+	if ((if_s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
 	    fatal("%s:%d: socket failed, %.200",
 		  __FILE__, __LINE__, strerror(errno));
+	}
+    }
+
+    strncpy(st->parg.ifr.ifdr_name, st->arg, sizeof(st->parg.ifr.ifdr_name));
 
-    info("started module if(%.200s)", s);
+    info("started module if(%.200s)", st->arg);
 }
-/* Get interface statistics */
+
 void
 gets_if()
 {
+    /* EMPTY */
 }
+
 int
-get_if(char *symon_buf, int maxlen, char *interface)
+get_if(char *symon_buf, int maxlen, struct stream *st)
 {
-    struct ifdatareq ifdr;
     const struct if_data* ifi;
 
-    strncpy(ifdr.ifdr_name, interface, sizeof (ifdr.ifdr_name));
-
-    if (ioctl(if_s, SIOCGIFDATA, (caddr_t)&ifdr)) {
-	warning("if(%.200s) failed (ioctl error)", interface);
+    if (ioctl(if_s, SIOCGIFDATA, (caddr_t)&st->parg.ifr)) {
+	warning("if(%.200s) failed (ioctl error)", st->arg);
 	return 0;
     }
-    ifi = &ifdr.ifdr_data;
+    ifi = &st->parg.ifr.ifdr_data;
 
-    return snpack(symon_buf, maxlen, interface, MT_IF,
+    return snpack(symon_buf, maxlen, st->arg, MT_IF,
 		  (u_int32_t) ifi->ifi_ipackets,
 		  (u_int32_t) ifi->ifi_opackets,
 		  (u_int32_t) ifi->ifi_ibytes,

+ 8 - 11
symon/platform/NetBSD/sm_io.c

@@ -1,4 +1,4 @@
-/* $Id: sm_io.c,v 1.1 2004/08/07 12:21:36 dijkstra Exp $ */
+/* $Id: sm_io.c,v 1.3 2005/10/18 19:58:09 dijkstra Exp $ */
 
 /*
  * Copyright (c) 2004      Matthew Gream
@@ -35,9 +35,6 @@
  * symon_buf as
  *
  * total nr of transfers : total seeks : total bytes transferred
- *
- * Non re-entrant code: gets_io messes with globals r/w without a semaphore.
- *
  */
 
 #include <sys/param.h>
@@ -93,22 +90,22 @@ gets_io()
 	      __FILE__, __LINE__);
     }
 }
-/* Prepare io module for first use */
+
 void
-init_io(char *s)
+init_io(struct stream *st)
 {
-    info("started module io(%.200s)", s);
+    info("started module io(%.200s)", st->arg);
 }
-/* Get new io statistics */
+
 int
-get_io(char *symon_buf, int maxlen, char *disk)
+get_io(char *symon_buf, int maxlen, struct stream *st)
 {
     int i;
 
     for (i = 0; i < io_maxdks; i++)
-	if (strncmp(io_dkstats[i].dk_name, disk,
+	if (strncmp(io_dkstats[i].dk_name, st->arg,
 		    sizeof(io_dkstats[i].dk_name)) == 0)
-	    return snpack(symon_buf, maxlen, disk, MT_IO2,
+	    return snpack(symon_buf, maxlen, st->arg, MT_IO2,
 			  io_dkstats[i].dk_rxfer,
 			  io_dkstats[i].dk_wxfer,
 			  io_dkstats[i].dk_seek,

+ 10 - 12
symon/platform/NetBSD/sm_mbuf.c

@@ -1,4 +1,4 @@
-/* $Id: sm_mbuf.c,v 1.1 2004/08/07 12:21:36 dijkstra Exp $ */
+/* $Id: sm_mbuf.c,v 1.3 2005/10/18 19:58:09 dijkstra Exp $ */
 
 /*
  * Copyright (c) 2003 Daniel Hartmeier
@@ -41,16 +41,14 @@
 #include "error.h"
 #include "symon.h"
 
-/* Prepare if module for first use */
 void
-init_mbuf(char *s)
+init_mbuf(struct stream *st)
 {
-    info("started module mbuf(%.200s)", s);
+    info("started module mbuf(%.200s)", st->arg);
 }
 
-/* Get mbuf statistics */
 int
-get_mbuf(char *symon_buf, int maxlen, char *arg)
+get_mbuf(char *symon_buf, int maxlen, struct stream *st)
 {
     struct mbstat mbstat;
 #ifdef KERN_POOL
@@ -72,7 +70,7 @@ get_mbuf(char *symon_buf, int maxlen, char *arg)
     mib[2] = MBUF_STATS;
     size = sizeof(mbstat);
     if (sysctl(mib, 3, &mbstat, &size, NULL, 0) < 0) {
-	warning("mbuf(%.200s) failed (sysctl() %.200s)", arg, strerror(errno));
+	warning("mbuf(%.200s) failed (sysctl() %.200s)", st->arg, strerror(errno));
 	return (0);
     }
 
@@ -82,7 +80,7 @@ get_mbuf(char *symon_buf, int maxlen, char *arg)
     mib[2] = KERN_POOL_NPOOLS;
     size = sizeof(npools);
     if (sysctl(mib, 3, &npools, &size, NULL, 0) < 0) {
-	warning("mbuf(%.200s) failed (sysctl() %.200s)", arg, strerror(errno));
+	warning("mbuf(%.200s) failed (sysctl() %.200s)", st->arg, strerror(errno));
 	return (0);
     }
 
@@ -93,14 +91,14 @@ get_mbuf(char *symon_buf, int maxlen, char *arg)
 	mib[3] = i;
 	size = sizeof(pool);
 	if (sysctl(mib, 4, &pool, &size, NULL, 0) < 0) {
-	    warning("mbuf(%.200s) failed (sysctl() %.200s)", arg, strerror(errno));
+	    warning("mbuf(%.200s) failed (sysctl() %.200s)", st->arg, strerror(errno));
 	    return (0);
 	}
 	npools--;
 	mib[2] = KERN_POOL_NAME;
 	size = sizeof(name);
 	if (sysctl(mib, 4, name, &size, NULL, 0) < 0) {
-	    warning("mbuf(%.200s) failed (sysctl() %.200s)", arg, strerror(errno));
+	    warning("mbuf(%.200s) failed (sysctl() %.200s)", st->arg, strerror(errno));
 	    return (0);
 	}
 	if (!strcmp(name, "mbpl")) {
@@ -114,7 +112,7 @@ get_mbuf(char *symon_buf, int maxlen, char *arg)
 	    break;
     }
     if (flag != 3) {
-	warning("mbuf(%.200s) failed (flag != 3)", arg);
+	warning("mbuf(%.200s) failed (flag != 3)", st->arg);
 	return (0);
     }
 #endif
@@ -153,7 +151,7 @@ get_mbuf(char *symon_buf, int maxlen, char *arg)
     stats[13] = mbstat.m_wait;
     stats[14] = mbstat.m_drain;
 
-    return snpack(symon_buf, maxlen, arg, MT_MBUF,
+    return snpack(symon_buf, maxlen, st->arg, MT_MBUF,
 		  stats[0],
 		  stats[1],
 		  stats[2],

+ 17 - 12
symon/platform/NetBSD/sm_proc.c

@@ -1,8 +1,8 @@
-/* $Id: sm_proc.c,v 1.2 2005/01/14 16:13:38 dijkstra Exp $ */
+/* $Id: sm_proc.c,v 1.4 2005/10/18 19:58:09 dijkstra Exp $ */
 
 /*
  * Copyright (c) 2004      Matthew Gream
- * Copyright (c) 2001-2004 Willem Dijkstra
+ * Copyright (c) 2001-2005 Willem Dijkstra
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -36,8 +36,6 @@
  *
  * number of processes : ticks_user : ticks_system : ticks_interrupt :
  * cpuseconds : procsizes : resident segment sizes
- *
- * Non re-entrant code: gets_proc messes with globals r/w without a semaphore.
  */
 
 #include <sys/param.h>
@@ -114,17 +112,24 @@ gets_proc()
 	proc_cur = size / sizeof(struct kinfo_proc);
     }
 }
-/* Prepare io module for first use */
+
+void
+privinit_proc()
+{
+    /* EMPTY */
+}
+
 void
-init_proc(char *s)
+init_proc(struct stream *st)
 {
     int mib[2] = {CTL_KERN, KERN_CLOCKRATE};
     struct clockinfo cinf;
     size_t size = sizeof(cinf);
 
     /* get clockrate */
-    if (sysctl(mib, 2, &cinf, &size, NULL, 0) == -1)
+    if (sysctl(mib, 2, &cinf, &size, NULL, 0) == -1) {
 	fatal("%s:%d: could not get clockrate", __FILE__, __LINE__);
+    }
 
     proc_stathz = cinf.stathz;
 
@@ -136,11 +141,11 @@ init_proc(char *s)
 	proc_pagesize >>= 1;
     }
 
-    info("started module proc(%.200s)", s);
+    info("started module proc(%.200s)", st->arg);
 }
-/* Get new io statistics */
+
 int
-get_proc(char *symon_buf, int maxlen, char *process)
+get_proc(char *symon_buf, int maxlen, struct stream *st)
 {
     int i;
     struct kinfo_proc *pp;
@@ -156,7 +161,7 @@ get_proc(char *symon_buf, int maxlen, char *process)
     int n = 0;
 
     for (pp = proc_ps, i = 0; i < proc_cur; pp++, i++) {
-	 if (strncmp(process, pp->kp_proc.p_comm, strlen(process)) == 0) {
+	 if (strncmp(st->arg, pp->kp_proc.p_comm, strlen(st->arg)) == 0) {
 	     /* cpu time - accumulated */
 	     cpu_uticks += pp->kp_proc.p_uticks;  /* user */
 	     cpu_sticks += pp->kp_proc.p_sticks;  /* sys  */
@@ -177,7 +182,7 @@ get_proc(char *symon_buf, int maxlen, char *process)
     cpu_ticks = cpu_uticks + cpu_sticks + cpu_iticks;
     cpu_secs = cpu_ticks / proc_stathz;
 
-    return snpack(symon_buf, maxlen, process, MT_PROC,
+    return snpack(symon_buf, maxlen, st->arg, MT_PROC,
 		  n,
 		  cpu_uticks, cpu_sticks, cpu_iticks, cpu_secs, cpu_pcti,
 		  mem_procsize, mem_rss );

+ 19 - 22
symon/platform/NetBSD/sm_sensor.c

@@ -1,4 +1,4 @@
-/* $Id: sm_sensor.c,v 1.1 2004/08/07 12:21:36 dijkstra Exp $ */
+/* $Id: sm_sensor.c,v 1.3 2005/10/18 19:58:09 dijkstra Exp $ */
 
 /*
  * Copyright (c) 2004      Matthew Gream
@@ -34,9 +34,6 @@
  * Get sensor data from the kernel and return in symon_buf as
  *
  * num : value
- *
- * This code is not re-entrant. It uses sysctl and can be run as any
- * user.
  */
 
 #include <errno.h>
@@ -53,57 +50,57 @@
 
 /* Globals for this module start with sn_ */
 static int sn_dev = -1;
-/* Priviledged init, called before priviledges are dropped */
 void
 privinit_sensor()
 {
-    if (sn_dev == -1 && (sn_dev = open("/dev/sysmon", O_RDONLY)) == -1)
+    if (sn_dev == -1 && (sn_dev = open("/dev/sysmon", O_RDONLY)) == -1) {
 	warning("could not open \"/dev/sysmon\", %.200s", strerror(errno));
+    }
 }
-/* Prepare if module for first use */
+
 void
-init_sensor(char *s)
+init_sensor(struct stream *st)
 {
-    if (sn_dev == -1)
+    if (sn_dev == -1) {
 	privinit_sensor();
+    }
 
-    info("started module sensors(%.200s)", s);
+    st->parg.sn = (strtol(st->arg, NULL, 10) & SYMON_SENSORMASK);
+
+    info("started module sensors(%.200s)", st->arg);
 }
-/* Get sensor statistics */
+
 int
-get_sensor(char *symon_buf, int maxlen, char *s)
+get_sensor(char *symon_buf, int maxlen, struct stream *st)
 {
-    int i;
     double t;
 
     envsys_basic_info_t e_info;
     envsys_tre_data_t e_data;
 
-    i = (int) (strtol(s, NULL, 10) & SYMON_SENSORMASK);
-
-    e_info.sensor = i;
+    e_info.sensor = st->parg.sn;
     if (ioctl(sn_dev, ENVSYS_GTREINFO, &e_info) == -1) {
 	warning("%s:%d: sensor can't get sensor info %.200s -- %.200s",
-		__FILE__, __LINE__, s, strerror(errno));
+		__FILE__, __LINE__, st->arg, strerror(errno));
 	return 0;
     }
 
     if (!(e_info.validflags & ENVSYS_FVALID)) {
 	warning("%s:%d: sensor info is invalid %.200s -- %.200s",
-		__FILE__, __LINE__, s, strerror(errno));
+		__FILE__, __LINE__, st->arg, strerror(errno));
 	return 0;
     }
 
-    e_data.sensor = i;
+    e_data.sensor = st->parg.sn;
     if (ioctl(sn_dev, ENVSYS_GTREDATA, &e_data) == -1) {
 	warning("%s:%d: sensor can't get sensor data %.200s -- %.200s",
-		__FILE__, __LINE__, s, strerror(errno));
+		__FILE__, __LINE__, st->arg, strerror(errno));
 	return 0;
     }
 
     if (!(e_data.validflags & ENVSYS_FCURVALID)) {
 	warning("%s:%d: sensor data is invalid %.200s -- %.200s",
-		__FILE__, __LINE__, s, strerror(errno));
+		__FILE__, __LINE__, st->arg, strerror(errno));
 	return 0;
     }
 
@@ -125,5 +122,5 @@ get_sensor(char *symon_buf, int maxlen, char *s)
 	    break;
     }
 
-    return snpack(symon_buf, maxlen, s, MT_SENSOR, t);
+    return snpack(symon_buf, maxlen, st->arg, MT_SENSOR, t);
 }

+ 21 - 1
symon/platform/OpenBSD/platform.h

@@ -1,13 +1,33 @@
-/* $Id: platform.h,v 1.1 2004/08/09 06:28:28 dijkstra Exp $ */
+/* $Id: platform.h,v 1.3 2005/10/21 14:58:46 dijkstra Exp $ */
 
 #ifndef _CONF_OPENBSD_H
 #define _CONF_OPENBSD_H
 
+#include <sys/dkstat.h>
 #include <sys/queue.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <net/if.h>
+
+#include "sylimits.h"
 
 #define SYMON_USER      "_symon"
 #define SEM_ARGS        (SEM_A|SEM_R)
 #define SA_LEN(x)       ((x)->sa_len)
 #define SS_LEN(x)       ((x)->ss_len)
 
+union stream_parg {
+    struct {
+	long time[CPUSTATES];
+	long old[CPUSTATES];
+	long diff[CPUSTATES];
+	int states[CPUSTATES];
+    } cp;
+    struct {
+	char rawdev[SYMON_DFNAMESIZE];
+    } df;
+    struct ifreq ifr;
+    int sn;
+};
+
 #endif

+ 19 - 22
symon/platform/OpenBSD/sm_cpu.c

@@ -1,11 +1,11 @@
-/* $Id: sm_cpu.c,v 1.19 2004/08/08 17:21:18 dijkstra Exp $ */
+/* $Id: sm_cpu.c,v 1.21 2005/10/18 19:58:11 dijkstra Exp $ */
 
 /* The author of this code is Willem Dijkstra (wpd@xs4all.nl).
  *
  * The percentages function was written by William LeFebvre and is part
  * of the 'top' utility. His copyright statement is below.
  *
- * Copyright (c) 2001-2004 Willem Dijkstra
+ * Copyright (c) 2001-2005 Willem Dijkstra
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -70,10 +70,6 @@ __END_DECLS
 /* Globals for this module all start with cp_ */
 static int cp_time_mib[] = {CTL_KERN, KERN_CPTIME};
 static size_t cp_size;
-static long cp_time[CPUSTATES];
-static long cp_old[CPUSTATES];
-static long cp_diff[CPUSTATES];
-static int cp_states[CPUSTATES];
 /*
  *  percentages(cnt, out, new, old, diffs) - calculate percentage change
  *      between array "old" and "new", putting the percentages i "out".
@@ -117,40 +113,41 @@ percentages(int cnt, int *out, register long *new, register long *old, long *dif
     /* return the total in case the caller wants to use it */
     return total_change;
 }
-/* Prepare cpu module for use */
+
 void
-init_cpu(char *s)
+init_cpu(struct stream *st)
 {
     char buf[SYMON_MAX_OBJSIZE];
 
-    cp_size = sizeof(cp_time);
+    cp_size = sizeof(st->parg.cp.time);
     /* Call get_cpu once to fill the cp_old structure */
-    get_cpu(buf, sizeof(buf), NULL);
+    get_cpu(buf, sizeof(buf), st);
 
-    info("started module cpu(%.200s)", s);
+    info("started module cpu(%.200s)", st->arg);
 }
 void
 gets_cpu()
 {
+    /* EMPTY */
 }
-/* Get new cpu measurements */
+
 int
-get_cpu(char *symon_buf, int maxlen, char *s)
+get_cpu(char *symon_buf, int maxlen, struct stream *st)
 {
     int total;
 
-    if (sysctl(cp_time_mib, 2, &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__);
 	return 0;
     }
 
     /* convert cp_time counts to percentages */
-    total = percentages(CPUSTATES, cp_states, cp_time, cp_old, cp_diff);
-
-    return snpack(symon_buf, maxlen, s, MT_CPU,
-		  (double) (cp_states[CP_USER] / 10.0),
-		  (double) (cp_states[CP_NICE] / 10.0),
-		  (double) (cp_states[CP_SYS] / 10.0),
-		  (double) (cp_states[CP_INTR] / 10.0),
-		  (double) (cp_states[CP_IDLE] / 10.0));
+    total = percentages(CPUSTATES, st->parg.cp.states, st->parg.cp.time, st->parg.cp.old, st->parg.cp.diff);
+
+    return snpack(symon_buf, maxlen, st->arg, MT_CPU,
+		  (double) (st->parg.cp.states[CP_USER] / 10.0),
+		  (double) (st->parg.cp.states[CP_NICE] / 10.0),
+		  (double) (st->parg.cp.states[CP_SYS] / 10.0),
+		  (double) (st->parg.cp.states[CP_INTR] / 10.0),
+		  (double) (st->parg.cp.states[CP_IDLE] / 10.0));
 }

+ 9 - 11
symon/platform/OpenBSD/sm_debug.c

@@ -1,7 +1,7 @@
-/* $Id: sm_debug.c,v 1.5 2004/08/07 12:21:36 dijkstra Exp $ */
+/* $Id: sm_debug.c,v 1.7 2005/10/18 19:58:11 dijkstra Exp $ */
 
 /*
- * Copyright (c) 2001-2004 Willem Dijkstra
+ * Copyright (c) 2001-2005 Willem Dijkstra
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -34,7 +34,6 @@
  * Get current debug statistics from kernel and return them in symon_buf as
  *
  * debug0 : debug1 : ... : debug19
- *
  */
 
 #include <sys/param.h>
@@ -42,23 +41,22 @@
 
 #include <string.h>
 
+#include "conf.h"
 #include "error.h"
 #include "symon.h"
 
-#define SYMON_MAXDEBUGID      20/* = CTL_DEBUG_MAXID; depends lib/data.h */
-
 /* Globals for this module start with db_ */
 static int db_mib[] = { CTL_DEBUG, 0, CTL_DEBUG_VALUE };
 static int db_v[SYMON_MAXDEBUGID];
-/* Prepare if module for first use */
+
 void
-init_debug(char *s)
+init_debug(struct stream *st)
 {
-    info("started module debug(%.200s)", s);
+    info("started module debug(%.200s)", st->arg);
 }
-/* Get debug statistics */
+
 int
-get_debug(char *symon_buf, int maxlen, char *s)
+get_debug(char *symon_buf, int maxlen, struct stream *st)
 {
     size_t len;
     int i;
@@ -72,7 +70,7 @@ get_debug(char *symon_buf, int maxlen, char *s)
 	sysctl(db_mib, sizeof(db_mib)/sizeof(int), &db_v[i], &len, NULL, 0);
     }
 
-    return snpack(symon_buf, maxlen, s, MT_DEBUG,
+    return snpack(symon_buf, maxlen, st->arg, MT_DEBUG,
 		  db_v[0], db_v[1], db_v[2], db_v[3], db_v[4], db_v[5], db_v[6],
 		  db_v[7], db_v[8], db_v[9], db_v[10], db_v[11], db_v[12], db_v[13],
 		  db_v[14], db_v[15], db_v[16], db_v[17], db_v[18], db_v[19]);

+ 108 - 0
symon/platform/OpenBSD/sm_df.c

@@ -0,0 +1,108 @@
+/* $Id: sm_df.c,v 1.3 2005/10/21 14:58:46 dijkstra Exp $ */
+
+/*
+ * Copyright (c) 2005 Marc Balmer
+ * 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 df statistics and return them in symon_buf as
+ *
+ *   blocks : bfree : bavail : files : ffree : \
+ *   syncwrites : asyncwrites
+ */
+
+#include "conf.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/mount.h>
+#include <ufs/ufs/dinode.h>
+#include <ufs/ffs/fs.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <fstab.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "error.h"
+#include "symon.h"
+
+/* Globals for this module start with df_ */
+static struct statfs *df_stats = NULL;
+static int df_parts = 0;
+
+void
+init_df(struct stream *st)
+{
+    strlcpy(st->parg.df.rawdev, "/dev/", sizeof(st->parg.df.rawdev));
+    strlcat(st->parg.df.rawdev, st->arg, sizeof(st->parg.df.rawdev));
+
+    info("started module df(%.200s)", st->arg);
+}
+
+void
+gets_df()
+{
+    if ((df_parts = getmntinfo(&df_stats, MNT_NOWAIT)) == 0) {
+	warning("df failed");
+    }
+}
+
+/*
+ * from src/bin/df.c:
+ * Convert statfs returned filesystem size into BLOCKSIZE units.
+ * Attempts to avoid overflow for large filesystems.
+ */
+#define fsbtoblk(num, fsbs, bs) \
+	(((fsbs) != 0 && (fsbs) < (bs)) ? \
+		(num) / ((bs) / (fsbs)) : (num) * ((fsbs) / (bs)))
+
+int
+get_df(char *symon_buf, int maxlen, struct stream *st)
+{
+    int n;
+
+    for (n = 0; n < df_parts; n++) {
+	if (!strncmp(df_stats[n].f_mntfromname, st->parg.df.rawdev, SYMON_DFNAMESIZE)) {
+	    return snpack(symon_buf, maxlen, st->arg, MT_DF,
+			  (u_int64_t)fsbtoblk(df_stats[n].f_blocks, df_stats[n].f_bsize, SYMON_DFBLOCKSIZE),
+			  (u_int64_t)fsbtoblk(df_stats[n].f_bfree, df_stats[n].f_bsize, SYMON_DFBLOCKSIZE),
+			  (u_int64_t)fsbtoblk(df_stats[n].f_bavail, df_stats[n].f_bsize, SYMON_DFBLOCKSIZE),
+			  (u_int64_t)df_stats[n].f_files,
+			  (u_int64_t)df_stats[n].f_ffree,
+			  (u_int64_t)df_stats[n].f_syncwrites,
+			  (u_int64_t)df_stats[n].f_asyncwrites);
+	}
+    }
+
+    warning("df(%.200s) failed (no such device)", st->arg);
+    return 0;
+}

+ 18 - 19
symon/platform/OpenBSD/sm_if.c

@@ -1,7 +1,7 @@
-/* $Id: sm_if.c,v 1.12 2004/08/07 14:48:35 dijkstra Exp $ */
+/* $Id: sm_if.c,v 1.15 2005/10/18 19:58:11 dijkstra Exp $ */
 
 /*
- * Copyright (c) 2001-2004 Willem Dijkstra
+ * Copyright (c) 2001-2005 Willem Dijkstra
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -35,7 +35,6 @@
  *
  * ipackets : opackets : ibytes : obytes : imcasts : omcasts : ierrors :
  * oerrors : colls : drops
- *
  */
 
 #include <sys/types.h>
@@ -48,8 +47,6 @@
 #include <net/if_types.h>
 #include <netinet/in.h>
 #include <netinet/in_var.h>
-#include <netns/ns.h>
-#include <netns/ns_if.h>
 #include <netipx/ipx.h>
 #include <netipx/ipx_if.h>
 
@@ -62,38 +59,40 @@
 
 /* Globals for this module start with if_ */
 static int if_s = -1;
-/* Prepare if module for first use */
+
 void
-init_if(char *s)
+init_if(struct stream *st)
 {
-    if (if_s == -1)
-	if ((if_s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+    if (if_s == -1) {
+	if ((if_s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
 	    fatal("%s:%d: socket failed, %.200",
 		  __FILE__, __LINE__, strerror(errno));
+	}
+    }
 
-    info("started module if(%.200s)", s);
+    strncpy(st->parg.ifr.ifr_name, st->arg, IFNAMSIZ - 1);
+    st->parg.ifr.ifr_name[IFNAMSIZ - 1] = '\0';
+
+    info("started module if(%.200s)", st->arg);
 }
-/* Get interface statistics */
+
 void
 gets_if()
 {
 }
 int
-get_if(char *symon_buf, int maxlen, char *interface)
+get_if(char *symon_buf, int maxlen, struct stream *st)
 {
-    struct ifreq ifr;
     struct if_data ifdata;
 
-    strncpy(ifr.ifr_name, interface, IFNAMSIZ - 1);
-    ifr.ifr_name[IFNAMSIZ - 1] = '\0';
-    ifr.ifr_data = (caddr_t) & ifdata;
+    st->parg.ifr.ifr_data = (caddr_t) &ifdata;
 
-    if (ioctl(if_s, SIOCGIFDATA, &ifr)) {
-	warning("if(%.200s) failed (ioctl error)", interface);
+    if (ioctl(if_s, SIOCGIFDATA, &st->parg.ifr)) {
+	warning("if(%.200s) failed (ioctl error)", st->arg);
 	return 0;
     }
 
-    return snpack(symon_buf, maxlen, interface, MT_IF,
+    return snpack(symon_buf, maxlen, st->arg, MT_IF,
 		  ifdata.ifi_ipackets,
 		  ifdata.ifi_opackets,
 		  ifdata.ifi_ibytes,

+ 9 - 12
symon/platform/OpenBSD/sm_io.c

@@ -1,4 +1,4 @@
-/* $Id: sm_io.c,v 1.16 2004/08/07 12:21:36 dijkstra Exp $ */
+/* $Id: sm_io.c,v 1.18 2005/10/18 19:58:11 dijkstra Exp $ */
 
 /*
  * Copyright (c) 2001-2004 Willem Dijkstra
@@ -35,9 +35,6 @@
  * symon_buf as
  *
  * total nr of transfers : total seeks : total bytes transferred
- *
- * Non re-entrant code: gets_io messes with globals r/w without a semaphore.
- *
  */
 
 #include <sys/param.h>
@@ -137,31 +134,31 @@ gets_io()
 	p++;
     }
 }
-/* Prepare io module for first use */
+
 void
-init_io(char *s)
+init_io(struct stream *st)
 {
-    info("started module io(%.200s)", s);
+    info("started module io(%.200s)", st->arg);
 }
-/* Get new io statistics */
+
 int
-get_io(char *symon_buf, int maxlen, char *disk)
+get_io(char *symon_buf, int maxlen, struct stream *st)
 {
     int i;
 
     /* look for disk */
     for (i = 0; i <= io_dks; i++) {
-	if (strncmp(io_dknames[i], disk,
+	if (strncmp(io_dknames[i], st->arg,
 		    (io_dkstr + io_maxstr - io_dknames[i])) == 0)
 #ifdef HAS_IO2
-	    return snpack(symon_buf, maxlen, disk, MT_IO2,
+	    return snpack(symon_buf, maxlen, st->arg, MT_IO2,
 			  io_dkstats[i].ds_rxfer,
 			  io_dkstats[i].ds_wxfer,
 			  io_dkstats[i].ds_seek,
 			  io_dkstats[i].ds_rbytes,
 			  io_dkstats[i].ds_wbytes);
 #else
-	    return snpack(symon_buf, maxlen, disk, MT_IO1,
+	    return snpack(symon_buf, maxlen, st->arg, MT_IO1,
 			  io_dkstats[i].ds_xfer,
 			  io_dkstats[i].ds_seek,
 			  io_dkstats[i].ds_bytes);

+ 16 - 20
symon/platform/OpenBSD/sm_mbuf.c

@@ -1,4 +1,4 @@
-/* $Id: sm_mbuf.c,v 1.4 2004/08/07 12:21:36 dijkstra Exp $ */
+/* $Id: sm_mbuf.c,v 1.6 2005/10/18 19:58:11 dijkstra Exp $ */
 
 /*
  * Copyright (c) 2003 Daniel Hartmeier
@@ -44,28 +44,24 @@
 
 #ifndef HAS_KERN_MBSTAT
 void
-init_mbuf(char *s)
+init_mbuf(struct stream *st)
 {
     fatal("mbuf module requires system upgrade (sysctl.h/KERN_MBSTAT)");
 }
 int
-get_mbuf(char *symon_buf, int maxlen, char *arg)
+get_mbuf(char *symon_buf, int maxlen, struct stream *st)
 {
     fatal("mbuf module requires system upgrade (sysctl.h/KERN_MBSTAT)");
-
-    return 0; /* NOT REACHED */
 }
 #else
-/* Prepare if module for first use */
 void
-init_mbuf(char *s)
+init_mbuf(struct stream *st)
 {
-    info("started module mbuf(%.200s)", s);
+    info("started module mbuf(%.200s)", st->arg);
 }
 
-/* Get mbuf statistics */
 int
-get_mbuf(char *symon_buf, int maxlen, char *arg)
+get_mbuf(char *symon_buf, int maxlen, struct stream *st)
 {
     struct mbstat mbstat;
     int npools;
@@ -84,8 +80,8 @@ get_mbuf(char *symon_buf, int maxlen, char *arg)
     mib[1] = KERN_MBSTAT;
     size = sizeof(mbstat);
     if (sysctl(mib, 2, &mbstat, &size, NULL, 0) < 0) {
-	warning("mbuf(%.200s) failed (sysctl() %.200s)", arg, strerror(errno));
-	return (0);
+	warning("mbuf(%.200s) failed (sysctl() %.200s)", st->arg, strerror(errno));
+	return 0;
     }
 
     mib[0] = CTL_KERN;
@@ -93,8 +89,8 @@ get_mbuf(char *symon_buf, int maxlen, char *arg)
     mib[2] = KERN_POOL_NPOOLS;
     size = sizeof(npools);
     if (sysctl(mib, 3, &npools, &size, NULL, 0) < 0) {
-	warning("mbuf(%.200s) failed (sysctl() %.200s)", arg, strerror(errno));
-	return (0);
+	warning("mbuf(%.200s) failed (sysctl() %.200s)", st->arg, strerror(errno));
+	return 0;
     }
 
     for (i = 1; npools; ++i) {
@@ -104,14 +100,14 @@ get_mbuf(char *symon_buf, int maxlen, char *arg)
 	mib[3] = i;
 	size = sizeof(pool);
 	if (sysctl(mib, 4, &pool, &size, NULL, 0) < 0) {
-	    warning("mbuf(%.200s) failed (sysctl() %.200s)", arg, strerror(errno));
-	    return (0);
+	    warning("mbuf(%.200s) failed (sysctl() %.200s)", st->arg, strerror(errno));
+	    return 0;
 	}
 	npools--;
 	mib[2] = KERN_POOL_NAME;
 	size = sizeof(name);
 	if (sysctl(mib, 4, name, &size, NULL, 0) < 0) {
-	    warning("mbuf(%.200s) failed (sysctl() %.200s)", arg, strerror(errno));
+	    warning("mbuf(%.200s) failed (sysctl() %.200s)", st->arg, strerror(errno));
 	    return (0);
 	}
 	if (!strcmp(name, "mbpl")) {
@@ -125,8 +121,8 @@ get_mbuf(char *symon_buf, int maxlen, char *arg)
 	    break;
     }
     if (flag != 3) {
-	warning("mbuf(%.200s) failed (flag != 3)", arg);
-	return (0);
+	warning("mbuf(%.200s) failed (flag != 3)", st->arg);
+	return 0;
     }
 
     totmbufs = 0;
@@ -153,7 +149,7 @@ get_mbuf(char *symon_buf, int maxlen, char *arg)
     stats[13] = mbstat.m_wait;
     stats[14] = mbstat.m_drain;
 
-    return snpack(symon_buf, maxlen, arg, MT_MBUF,
+    return snpack(symon_buf, maxlen, st->arg, MT_MBUF,
 		  stats[0],
 		  stats[1],
 		  stats[2],

+ 21 - 14
symon/platform/OpenBSD/sm_mem.c

@@ -1,4 +1,4 @@
-/* $Id: sm_mem.c,v 1.17 2005/02/25 15:10:10 dijkstra Exp $ */
+/* $Id: sm_mem.c,v 1.20 2005/10/18 19:58:11 dijkstra Exp $ */
 
 /*
  * Copyright (c) 2001-2004 Willem Dijkstra
@@ -34,8 +34,6 @@
  * Get current memory statistics in bytes; reports them back in symon_buf as
  *
  * real active : real total : free : [swap used : swap total]
- *
- * This code is not re-entrant.
  */
 
 #include <sys/param.h>
@@ -63,9 +61,9 @@ static size_t me_vmsize;
 static int me_pagesize;
 static int me_nswap;
 struct swapent *me_swdev = NULL;
-/* Prepare mem module for first use */
+
 void
-init_mem(char *s)
+init_mem(struct stream *st)
 {
     me_pagesize = sysconf(_SC_PAGESIZE);
     me_pageshift = 0;
@@ -80,22 +78,27 @@ init_mem(char *s)
     /* determine number of swap entries */
     me_nswap = swapctl(SWAP_NSWAP, 0, 0);
 
-    if (me_swdev)
+    if (me_swdev) {
 	xfree(me_swdev);
+    }
 
-    if (me_nswap != 0)
+    if (me_nswap != 0) {
 	me_swdev = xmalloc(me_nswap * sizeof(*me_swdev));
-    else
+    } else {
 	me_swdev = NULL;
+    }
 
-    if (me_swdev == NULL && me_nswap != 0)
+    if (me_swdev == NULL && me_nswap != 0) {
 	me_nswap = 0;
+    }
 
-    info("started module mem(%.200s)", s);
+    if (st != NULL) {
+	info("started module mem(%.200s)", st->arg);
+    }
 }
-/* Get memory statistics */
-int
-get_mem(char *symon_buf, int maxlen, char *s)
+
+void
+gets_mem()
 {
     int i, rnswap;
 
@@ -126,8 +129,12 @@ get_mem(char *symon_buf, int maxlen, char *s)
 	    }
 	}
     }
+}
 
-    return snpack(symon_buf, maxlen, s, MT_MEM,
+int
+get_mem(char *symon_buf, int maxlen, struct stream *st)
+{
+    return snpack(symon_buf, maxlen, st->arg, MT_MEM,
 		  me_stats[0], me_stats[1], me_stats[2],
 		  me_stats[3], me_stats[4]);
 }

+ 54 - 46
symon/platform/OpenBSD/sm_pf.c

@@ -1,4 +1,4 @@
-/* $Id: sm_pf.c,v 1.9 2005/01/15 17:31:11 dijkstra Exp $ */
+/* $Id: sm_pf.c,v 1.11 2005/10/18 19:58:11 dijkstra Exp $ */
 
 /*
  * Copyright (c) 2002 Daniel Hartmeier
@@ -67,12 +67,12 @@ privinit_pf()
 {
 }
 void
-init_pf(char *s)
+init_pf(struct stream *st)
 {
     fatal("pf support not available");
 }
 int
-get_pf(char *symon_buf, int maxlen, char *s)
+get_pf(char *symon_buf, int maxlen, struct stream *st)
 {
     fatal("pf support not available");
     return 0;
@@ -82,67 +82,75 @@ get_pf(char *symon_buf, int maxlen, char *s)
 
 /* Globals for this module start with pf_ */
 int pf_dev = -1;
-/* Priviledged init, called before priviledges are dropped */
+struct pf_status pf_stat;
+
 void
 privinit_pf()
 {
-    if ((pf_dev = open("/dev/pf", O_RDONLY)) == -1)
+    if ((pf_dev = open("/dev/pf", O_RDONLY)) == -1) {
 	warning("could not open \"/dev/pf\", %.200s", strerror(errno));
+    }
 }
-/* Prepare if module for first use */
+
 void
-init_pf(char *s)
+init_pf(struct stream *st)
 {
-    if (pf_dev == -1)
+    if (pf_dev == -1) {
 	privinit_pf();
+    }
 
-    info("started module pf(%.200s)", s);
+    info("started module pf()");
 }
-/* Get pf statistics */
-int
-get_pf(char *symon_buf, int maxlen, char *arg)
-{
-    struct pf_status s;
-    u_int64_t n;
 
+void
+gets_pf()
+{
     if (pf_dev == -1) {
-	warning("pf(%.200s) failed (dev == -1)", arg);
-	return 0;
+	warning("could not get pf stats (dev == -1)");
+	pf_stat.running = 0;
+	return;
     }
 
-    if (ioctl(pf_dev, DIOCGETSTATUS, &s)) {
-	warning("pf(%.200s) failed (ioctl error)", arg);
-	return 0;
+    if (ioctl(pf_dev, DIOCGETSTATUS, &pf_stat)) {
+	warning("could not get pf stats (ioctl error)");
+	pf_stat.running = 0;
+	return;
     }
+}
+
+int
+get_pf(char *symon_buf, int maxlen, struct stream *st)
+{
+    u_int64_t n;
 
-    if (!s.running)
+    if (!pf_stat.running) {
 	return 0;
+    }
 
-    n = s.states;
-    return snpack(symon_buf, maxlen, arg, MT_PF,
-		  s.bcounters[0][0],
-		  s.bcounters[0][1],
-		  s.bcounters[1][0],
-		  s.bcounters[1][1],
-		  s.pcounters[0][0][PF_PASS],
-		  s.pcounters[0][0][PF_DROP],
-		  s.pcounters[0][1][PF_PASS],
-		  s.pcounters[0][1][PF_DROP],
-		  s.pcounters[1][0][PF_PASS],
-		  s.pcounters[1][0][PF_DROP],
-		  s.pcounters[1][1][PF_PASS],
-		  s.pcounters[1][1][PF_DROP],
+    n = pf_stat.states;
+    return snpack(symon_buf, maxlen, st->arg, MT_PF,
+		  pf_stat.bcounters[0][0],
+		  pf_stat.bcounters[0][1],
+		  pf_stat.bcounters[1][0],
+		  pf_stat.bcounters[1][1],
+		  pf_stat.pcounters[0][0][PF_PASS],
+		  pf_stat.pcounters[0][0][PF_DROP],
+		  pf_stat.pcounters[0][1][PF_PASS],
+		  pf_stat.pcounters[0][1][PF_DROP],
+		  pf_stat.pcounters[1][0][PF_PASS],
+		  pf_stat.pcounters[1][0][PF_DROP],
+		  pf_stat.pcounters[1][1][PF_PASS],
+		  pf_stat.pcounters[1][1][PF_DROP],
 		  n,
-		  s.fcounters[0],
-		  s.fcounters[1],
-		  s.fcounters[2],
-		  s.counters[0],
-		  s.counters[1],
-		  s.counters[2],
-		  s.counters[3],
-		  s.counters[4],
-		  s.counters[5]
+		  pf_stat.fcounters[0],
+		  pf_stat.fcounters[1],
+		  pf_stat.fcounters[2],
+		  pf_stat.counters[0],
+		  pf_stat.counters[1],
+		  pf_stat.counters[2],
+		  pf_stat.counters[3],
+		  pf_stat.counters[4],
+		  pf_stat.counters[5]
 	);
 }
-
-#endif
+#endif /* HAS_PFVAR_H */

+ 39 - 35
symon/platform/OpenBSD/sm_pfq.c

@@ -1,4 +1,4 @@
-/* $Id: sm_pfq.c,v 1.1 2005/03/20 16:17:22 dijkstra Exp $ */
+/* $Id: sm_pfq.c,v 1.4 2005/10/21 14:58:46 dijkstra Exp $ */
 
 /*
  * Copyright (c) 2005 J. Martin Petersen
@@ -33,8 +33,6 @@
 /*
  * Get current altq statistics from pf and return them in symon_buf as
  * sent_bytes : sent_packets : drop_bytes : drop_packets
- *
- * Non re-entrant code: gets_pfq messes with the globals without locking.
  */
 
 #include "conf.h"
@@ -70,7 +68,7 @@ privinit_pfq()
     fatal("pf support not available");
 }
 void
-init_pfq(char *s)
+init_pfq(struct stream *st)
 {
     fatal("pf support not available");
 }
@@ -81,7 +79,7 @@ gets_pfq()
 }
 
 int
-get_pfq(char *b, int l, char *s)
+get_pfq(char *b, int l, struct stream *st)
 {
   fatal("pf support not available");
   return 0;
@@ -96,12 +94,12 @@ union class_stats {
 };
 
 /*
- * We don't reuse the data structures from altq/altq_{cbq|hfsc|priq}.h as they
+ * We do not use the data structures from altq/altq_{cbq|hfsc|priq}.h as they
  * are overly complex. For now we only grab the interesting stuff.
  */
 
 struct altq_stats {
-    char qname[PF_QNAME_SIZE];
+    char qname[PF_QNAME_SIZE + IFNAMSIZ + 1];
     u_int64_t sent_bytes;
     u_int64_t sent_packets;
     u_int64_t drop_bytes;
@@ -109,7 +107,8 @@ struct altq_stats {
 };
 
 static struct altq_stats *pfq_stats = NULL;
-static int pfq_numstats = 0;
+static int pfq_cur = 0;
+static int pfq_max = 0;
 int pfq_dev = -1;
 
 void
@@ -121,13 +120,13 @@ privinit_pfq()
 }
 
 void
-init_pfq(char *s)
+init_pfq(struct stream *st)
 {
     if (pfq_dev == -1) {
 	privinit_pfq();
     }
 
-    info("started module pfq(%.200s)",s);
+    info("started module pfq(%.200s)", st->arg);
 }
 
 void
@@ -149,15 +148,23 @@ gets_pfq()
     nqs = qs.nr;
 
     /* Allocate memory for info for the nqs queues */
-    if (nqs > pfq_numstats) {
+    if (nqs > pfq_max) {
 	if (pfq_stats) {
 	    xfree(pfq_stats);
 	}
 
-	pfq_stats = xmalloc(nqs * sizeof(struct altq_stats));
-	pfq_numstats = nqs;
+	pfq_max = 2 * nqs;
+
+	if (pfq_max > SYMON_MAX_DOBJECTS) {
+	    fatal("%s:%d: dynamic object limit (%d) exceeded for pf queue structures",
+		  __FILE__, __LINE__, SYMON_MAX_DOBJECTS);
+	}
+
+	pfq_stats = xmalloc(pfq_max * sizeof(struct altq_stats));
     }
 
+    pfq_cur = 0;
+
     /* Loop through the queues, copy info */
     for (i = 0; i < nqs; i++) {
 	qs.nr = i;
@@ -177,50 +184,48 @@ gets_pfq()
 	    }
 
 	    /* We're now ready to copy the data we want. */
-	    strncpy(pfq_stats[i].qname, qs.altq.qname, PF_QNAME_SIZE);
+	    snprintf(pfq_stats[pfq_cur].qname, sizeof(pfq_stats[0].qname),
+		     "%s/%s", qs.altq.ifname, qs.altq.qname);
 
 	    switch (qs.altq.scheduler) {
 	    case ALTQT_CBQ:
-		pfq_stats[i].sent_bytes = q.cbq.xmit_cnt.bytes;
-		pfq_stats[i].sent_packets = q.cbq.xmit_cnt.packets;
-		pfq_stats[i].drop_bytes = q.cbq.drop_cnt.bytes;
-		pfq_stats[i].drop_packets = q.cbq.drop_cnt.packets;
+		pfq_stats[pfq_cur].sent_bytes = q.cbq.xmit_cnt.bytes;
+		pfq_stats[pfq_cur].sent_packets = q.cbq.xmit_cnt.packets;
+		pfq_stats[pfq_cur].drop_bytes = q.cbq.drop_cnt.bytes;
+		pfq_stats[pfq_cur].drop_packets = q.cbq.drop_cnt.packets;
 		break;
 
 	    case ALTQT_PRIQ:
-		pfq_stats[i].sent_bytes = q.priq.xmitcnt.bytes;
-		pfq_stats[i].sent_packets = q.priq.xmitcnt.packets;
-		pfq_stats[i].drop_bytes = q.priq.dropcnt.bytes;
-		pfq_stats[i].drop_packets = q.priq.dropcnt.packets;
+		pfq_stats[pfq_cur].sent_bytes = q.priq.xmitcnt.bytes;
+		pfq_stats[pfq_cur].sent_packets = q.priq.xmitcnt.packets;
+		pfq_stats[pfq_cur].drop_bytes = q.priq.dropcnt.bytes;
+		pfq_stats[pfq_cur].drop_packets = q.priq.dropcnt.packets;
 		break;
 
 	    case ALTQT_HFSC:
-		pfq_stats[i].sent_bytes = q.hfsc.xmit_cnt.bytes;
-		pfq_stats[i].sent_packets = q.hfsc.xmit_cnt.packets;
-		pfq_stats[i].drop_bytes = q.hfsc.drop_cnt.bytes;
-		pfq_stats[i].drop_packets = q.hfsc.drop_cnt.packets;
+		pfq_stats[pfq_cur].sent_bytes = q.hfsc.xmit_cnt.bytes;
+		pfq_stats[pfq_cur].sent_packets = q.hfsc.xmit_cnt.packets;
+		pfq_stats[pfq_cur].drop_bytes = q.hfsc.drop_cnt.bytes;
+		pfq_stats[pfq_cur].drop_packets = q.hfsc.drop_cnt.packets;
 		break;
 
 	    default:
 		warning("pfq: unknown altq scheduler type encountered");
 		break;
 	    }
-	} else {
-	    /* Make sure the lookup in get_pfq fails immediately whenever
-	     * there's no queue in the slot. We do this by nul'ing the name */
-	    pfq_stats[i].qname[0] = '\0';
+	    pfq_cur++;
 	}
     }
 }
 
 int
-get_pfq(char *symon_buf, int maxlen, char *queue)
+get_pfq(char *symon_buf, int maxlen, struct stream *st)
 {
     unsigned int i;
 
-    for (i = 0; i < pfq_numstats; i++) {
-	if (strncmp(pfq_stats[i].qname, queue, PF_QNAME_SIZE) == 0) {
-	    return snpack(symon_buf, maxlen, queue, MT_PFQ,
+    for (i = 0; i < pfq_cur; i++) {
+	if (strncmp(pfq_stats[i].qname, st->arg, sizeof(pfq_stats[0].qname)) == 0) {
+	    return snpack(symon_buf, maxlen, st->arg, MT_PFQ,
 			  pfq_stats[i].sent_bytes,
 			  pfq_stats[i].sent_packets,
 			  pfq_stats[i].drop_bytes,
@@ -231,5 +236,4 @@ get_pfq(char *symon_buf, int maxlen, char *queue)
 
     return 0;
 }
-
 #endif

+ 16 - 10
symon/platform/OpenBSD/sm_proc.c

@@ -1,4 +1,4 @@
-/* $Id: sm_proc.c,v 1.5 2005/01/14 16:13:38 dijkstra Exp $ */
+/* $Id: sm_proc.c,v 1.7 2005/10/18 19:58:11 dijkstra Exp $ */
 
 /*
  * Copyright (c) 2001-2005 Willem Dijkstra
@@ -36,7 +36,6 @@
  * number of processes : ticks_user : ticks_system : ticks_interrupt :
  * cpuseconds : procsizes : resident segment sizes
  *
- * Non re-entrant code: gets_proc messes with globals r/w without a semaphore.
  */
 
 #include <sys/param.h>
@@ -112,17 +111,24 @@ gets_proc()
 	proc_cur = size / sizeof(struct kinfo_proc);
     }
 }
-/* Prepare io module for first use */
+
 void
-init_proc(char *s)
+privinit_proc()
+{
+    /* EMPTY */
+}
+
+void
+init_proc(struct stream *st)
 {
     int mib[2] = {CTL_KERN, KERN_CLOCKRATE};
     struct clockinfo cinf;
     size_t size = sizeof(cinf);
 
     /* get clockrate */
-    if (sysctl(mib, 2, &cinf, &size, NULL, 0) == -1)
+    if (sysctl(mib, 2, &cinf, &size, NULL, 0) == -1) {
 	fatal("%s:%d: could not get clockrate", __FILE__, __LINE__);
+    }
 
     proc_stathz = cinf.stathz;
 
@@ -134,11 +140,11 @@ init_proc(char *s)
 	proc_pagesize >>= 1;
     }
 
-    info("started module proc(%.200s)", s);
+    info("started module proc(%.200s)", st->arg);
 }
-/* Get new io statistics */
+
 int
-get_proc(char *symon_buf, int maxlen, char *process)
+get_proc(char *symon_buf, int maxlen, struct stream *st)
 {
     int i;
     struct kinfo_proc *pp;
@@ -154,7 +160,7 @@ get_proc(char *symon_buf, int maxlen, char *process)
     int n = 0;
 
     for (pp = proc_ps, i = 0; i < proc_cur; pp++, i++) {
-	 if (strncmp(process, pp->kp_proc.p_comm, strlen(process)) == 0) {
+	 if (strncmp(st->arg, pp->kp_proc.p_comm, strlen(st->arg)) == 0) {
 	     /* cpu time - accumulated */
 	     cpu_uticks += pp->kp_proc.p_uticks;  /* user */
 	     cpu_sticks += pp->kp_proc.p_sticks;  /* sys  */
@@ -175,7 +181,7 @@ get_proc(char *symon_buf, int maxlen, char *process)
     cpu_ticks = cpu_uticks + cpu_sticks + cpu_iticks;
     cpu_secs = cpu_ticks / proc_stathz;
 
-    return snpack(symon_buf, maxlen, process, MT_PROC,
+    return snpack(symon_buf, maxlen, st->arg, MT_PROC,
 		  n,
 		  cpu_uticks, cpu_sticks, cpu_iticks, cpu_secs, cpu_pcti,
 		  mem_procsize, mem_rss );

+ 19 - 20
symon/platform/OpenBSD/sm_sensor.c

@@ -1,7 +1,7 @@
-/* $Id: sm_sensor.c,v 1.5 2004/08/07 12:21:36 dijkstra Exp $ */
+/* $Id: sm_sensor.c,v 1.7 2005/10/18 19:58:11 dijkstra Exp $ */
 
 /*
- * Copyright (c) 2001-2004 Willem Dijkstra
+ * Copyright (c) 2001-2005 Willem Dijkstra
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -35,10 +35,10 @@
  *
  * num : value
  *
- * This code is not re-entrant. It uses sysctl and can be run as any
- * user.
  */
 
+#include "conf.h"
+
 #include <sys/param.h>
 #include <sys/sysctl.h>
 
@@ -57,16 +57,15 @@ privinit_sensor()
     fatal("sensor support not available");
 }
 void
-init_sensor(char *s)
+init_sensor(struct stream *st)
 {
     fatal("sensor support not available");
 }
 int
-get_sensor(char *symon_buf, int maxlen, char *s)
+get_sensor(char *symon_buf, int maxlen, struct stream *st)
 {
     fatal("sensor support not available");
-
-    return 0; /* NOT REACHED */
+    return 0;
 }
 
 #else
@@ -77,35 +76,35 @@ get_sensor(char *symon_buf, int maxlen, char *s)
 static int sn_mib[] = {CTL_HW, HW_SENSORS, 0};
 static struct sensor sn_sensor;
 
-/* Prepare if module for first use */
 void
 privinit_sensor()
 {
+    /* EMPTY */
 }
+
 void
-init_sensor(char *s)
+init_sensor(struct stream *st)
 {
-    info("started module sensors(%.200s)", s);
+    long l = strtol(st->arg, NULL, 10);
+    st->parg.sn = (int) (l & SYMON_SENSORMASK);
+
+    info("started module sensors(%.200s)", st->arg);
 }
-/* Get sensor statistics */
+
 int
-get_sensor(char *symon_buf, int maxlen, char *s)
+get_sensor(char *symon_buf, int maxlen, struct stream *st)
 {
     size_t len;
-    long l;
-    int i;
     double t;
 
     bzero((void *) &sn_sensor, sizeof(sn_sensor));
-    l = strtol(s, NULL, 10);
-    i = (int) (l & SYMON_SENSORMASK);
-    sn_mib[2] = i;
+    sn_mib[2] = st->parg.sn;
 
     len = sizeof(sn_sensor);
 
     if (sysctl(sn_mib, 3, &sn_sensor, &len, NULL, 0) == -1) {
 	warning("%s:%d: sensor can't get sensor %.200s -- %.200s",
-		__FILE__, __LINE__, s, strerror(errno));
+		__FILE__, __LINE__, st->arg, strerror(errno));
 
 	return 0;
     } else {
@@ -123,7 +122,7 @@ get_sensor(char *symon_buf, int maxlen, char *s)
 	    t = (double) sn_sensor.value;
 	}
 
-	return snpack(symon_buf, maxlen, s, MT_SENSOR, t);
+	return snpack(symon_buf, maxlen, st->arg, MT_SENSOR, t);
     }
 }
 #endif /* HAS_SENSORS_H */

+ 6 - 6
symon/platform/stub/sm_cpu.c

@@ -1,23 +1,23 @@
-/* $Id: sm_cpu.c,v 1.2 2004/08/08 17:21:18 dijkstra Exp $ */
+/* $Id: sm_cpu.c,v 1.3 2005/10/18 19:58:12 dijkstra Exp $ */
 
 #include <stdlib.h>
 
+#include "sylimits.h"
+#include "data.h"
 #include "error.h"
 
 void
-init_cpu(char *s)
+init_cpu(struct stream *st)
 {
     fatal("cpu module not available");
 }
-
 void
-gets_cpu(char *s)
+gets_cpu()
 {
     fatal("cpu module not available");
 }
-
 int
-get_cpu(char *symon_buf, int maxlen, char *s)
+get_cpu(char *symon_buf, int maxlen, struct stream *st)
 {
     fatal("cpu module not available");
 

+ 5 - 4
symon/platform/stub/sm_debug.c

@@ -1,17 +1,18 @@
-/* $Id: sm_debug.c,v 1.1 2004/08/07 12:21:36 dijkstra Exp $ */
+/* $Id: sm_debug.c,v 1.2 2005/10/18 19:58:12 dijkstra Exp $ */
 
 #include <stdlib.h>
 
+#include "sylimits.h"
+#include "data.h"
 #include "error.h"
 
 void
-init_debug(char *s)
+init_debug(struct stream *st)
 {
     fatal("debug module not available");
 }
-
 int
-get_debug(char *symon_buf, int maxlen, char *s)
+get_debug(char *symon_buf, int maxlen, struct stream *st)
 {
     fatal("debug module not available");
 

+ 26 - 0
symon/platform/stub/sm_df.c

@@ -0,0 +1,26 @@
+/* $Id: sm_df.c,v 1.2 2005/10/18 19:58:12 dijkstra Exp $ */
+
+#include <stdlib.h>
+
+#include "sylimits.h"
+#include "data.h"
+#include "error.h"
+
+void
+init_df(struct stream *st)
+{
+    fatal("df module not available");
+}
+void
+gets_df()
+{
+    fatal("df module not available");
+}
+int
+get_df(char *symon_buf, int maxlen, struct stream *st)
+{
+    fatal("df module not available");
+
+    /* NOT REACHED */
+    return 0;
+}

+ 5 - 5
symon/platform/stub/sm_if.c

@@ -1,23 +1,23 @@
-/* $Id: sm_if.c,v 1.2 2004/08/07 14:48:35 dijkstra Exp $ */
+/* $Id: sm_if.c,v 1.3 2005/10/18 19:58:12 dijkstra Exp $ */
 
 #include <stdlib.h>
 
+#include "sylimits.h"
+#include "data.h"
 #include "error.h"
 
 void
-init_if(char *s)
+init_if(struct stream *st)
 {
     fatal("if module not available");
 }
-
 void
 gets_if()
 {
     fatal("if module not available");
 }
-
 int
-get_if(char *symon_buf, int maxlen, char *s)
+get_if(char *symon_buf, int maxlen, struct stream *st)
 {
     fatal("if module not available");
 

+ 5 - 3
symon/platform/stub/sm_io.c

@@ -1,11 +1,13 @@
-/* $Id: sm_io.c,v 1.1 2004/08/07 12:21:36 dijkstra Exp $ */
+/* $Id: sm_io.c,v 1.2 2005/10/18 19:58:12 dijkstra Exp $ */
 
 #include <stdlib.h>
 
+#include "sylimits.h"
+#include "data.h"
 #include "error.h"
 
 void
-init_io(char *s)
+init_io(struct stream *st)
 {
     fatal("io module not available");
 }
@@ -15,7 +17,7 @@ gets_io()
     fatal("io module not available");
 }
 int
-get_io(char *symon_buf, int maxlen, char *s)
+get_io(char *symon_buf, int maxlen, struct stream *st)
 {
     fatal("io module not available");
 

+ 5 - 3
symon/platform/stub/sm_mbuf.c

@@ -1,17 +1,19 @@
-/* $Id: sm_mbuf.c,v 1.1 2004/08/07 12:21:36 dijkstra Exp $ */
+/* $Id: sm_mbuf.c,v 1.2 2005/10/18 19:58:12 dijkstra Exp $ */
 
 #include <stdlib.h>
 
+#include "sylimits.h"
+#include "data.h"
 #include "error.h"
 
 void
-init_mbuf(char *s)
+init_mbuf(struct stream *st)
 {
     fatal("mbuf module not available");
 }
 
 int
-get_mbuf(char *symon_buf, int maxlen, char *s)
+get_mbuf(char *symon_buf, int maxlen, struct stream *st)
 {
     fatal("mbuf module not available");
 

+ 10 - 4
symon/platform/stub/sm_mem.c

@@ -1,17 +1,23 @@
-/* $Id: sm_mem.c,v 1.1 2004/08/07 12:21:36 dijkstra Exp $ */
+/* $Id: sm_mem.c,v 1.3 2005/10/18 19:58:12 dijkstra Exp $ */
 
 #include <stdlib.h>
 
+#include "sylimits.h"
+#include "data.h"
 #include "error.h"
 
 void
-init_mem(char *s)
+init_mem(struct stream *st)
+{
+    fatal("mem module not available");
+}
+void
+gets_mem()
 {
     fatal("mem module not available");
 }
-
 int
-get_mem(char *symon_buf, int maxlen, char *s)
+get_mem(char *symon_buf, int maxlen, struct stream *st)
 {
     fatal("mem module not available");
 

+ 10 - 5
symon/platform/stub/sm_pf.c

@@ -1,7 +1,9 @@
-/* $Id: sm_pf.c,v 1.1 2004/08/07 12:21:36 dijkstra Exp $ */
+/* $Id: sm_pf.c,v 1.2 2005/10/18 19:58:12 dijkstra Exp $ */
 
 #include <stdlib.h>
 
+#include "sylimits.h"
+#include "data.h"
 #include "error.h"
 
 void
@@ -9,15 +11,18 @@ privinit_pf()
 {
     fatal("pf module not available");
 }
-
 void
-init_pf(char *s)
+init_pf(struct stream *st)
+{
+    fatal("pf module not available");
+}
+void
+gets_pf()
 {
     fatal("pf module not available");
 }
-
 int
-get_pf(char *symon_buf, int maxlen, char *s)
+get_pf(char *symon_buf, int maxlen, struct stream *st)
 {
     fatal("pf module not available");
 

+ 5 - 6
symon/platform/stub/sm_pfq.c

@@ -1,7 +1,9 @@
-/* $Id: sm_pfq.c,v 1.1 2005/03/20 16:17:22 dijkstra Exp $ */
+/* $Id: sm_pfq.c,v 1.2 2005/10/18 19:58:12 dijkstra Exp $ */
 
 #include <stdlib.h>
 
+#include "sylimits.h"
+#include "data.h"
 #include "error.h"
 
 void
@@ -9,21 +11,18 @@ privinit_pfq()
 {
     fatal("pfq module not available");
 }
-
 void
-init_pfq(char *s)
+init_pfq(struct stream *st)
 {
     fatal("pfq module not available");
 }
-
 void
 gets_pfq()
 {
     fatal("pfq module not available");
 }
-
 int
-get_pfq(char *b, int l, char *s)
+get_pfq(char *b, int l, struct stream *st)
 {
     fatal("pfq module not available");
 

+ 11 - 3
symon/platform/stub/sm_proc.c

@@ -1,11 +1,13 @@
-/* $Id: sm_proc.c,v 1.1 2004/08/07 12:21:36 dijkstra Exp $ */
+/* $Id: sm_proc.c,v 1.3 2005/10/19 20:06:07 dijkstra Exp $ */
 
 #include <stdlib.h>
 
+#include "sylimits.h"
+#include "data.h"
 #include "error.h"
 
 void
-init_proc(char *s)
+init_proc(struct stream *st)
 {
     fatal("proc module not available");
 }
@@ -16,8 +18,14 @@ gets_proc()
     fatal("proc module not available");
 }
 
+void
+privinit_proc()
+{
+    fatal("proc module not available");
+}
+
 int
-get_proc(char *symon_buf, int maxlen, char *s)
+get_proc(char *symon_buf, int maxlen, struct stream *st)
 {
     fatal("proc module not available");
 

+ 5 - 3
symon/platform/stub/sm_sensor.c

@@ -1,7 +1,9 @@
-/* $Id: sm_sensor.c,v 1.1 2004/08/07 12:21:36 dijkstra Exp $ */
+/* $Id: sm_sensor.c,v 1.2 2005/10/18 19:58:12 dijkstra Exp $ */
 
 #include <stdlib.h>
 
+#include "sylimits.h"
+#include "data.h"
 #include "error.h"
 
 void
@@ -10,13 +12,13 @@ privinit_sensor()
     fatal("sensor module not available");
 }
 void
-init_sensor(char *s)
+init_sensor(struct stream *st)
 {
     fatal("sensor module not available");
 }
 
 int
-get_sensor(char *symon_buf, int maxlen, char *s)
+get_sensor(char *symon_buf, int maxlen, struct stream *st)
 {
     fatal("sensor module not available");
 

+ 5 - 4
symon/symon/readconf.c

@@ -1,7 +1,7 @@
-/* $Id: readconf.c,v 1.22 2005/03/20 16:17:22 dijkstra Exp $ */
+/* $Id: readconf.c,v 1.23 2005/10/16 15:27:01 dijkstra Exp $ */
 
 /*
- * Copyright (c) 2001-2004 Willem Dijkstra
+ * Copyright (c) 2001-2005 Willem Dijkstra
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -87,7 +87,7 @@ read_host_port(struct muxlist * mul, struct mux * mux, struct lex * l)
 
     return 1;
 }
-/* parse "<cpu(arg)|mem|if(arg)|io(arg)|debug|pf|pfq(arg)|proc(arg)>", end condition == "}" */
+/* parse "<cpu(arg)|df(arg)|mem|if(arg)|io(arg)|debug|pf|pfq(arg)|proc(arg)>", end condition == "}" */
 int
 read_symon_args(struct mux * mux, struct lex * l)
 {
@@ -99,6 +99,7 @@ read_symon_args(struct mux * mux, struct lex * l)
 	while (lex_nexttoken(l) && l->op != LXT_END) {
 	switch (l->op) {
 	case LXT_CPU:
+	case LXT_DF:
 	case LXT_IF:
 	case LXT_IO:
 	case LXT_IO1:
@@ -143,7 +144,7 @@ read_symon_args(struct mux * mux, struct lex * l)
 		return 0;
 	    }
 
-	    break;		/* LXT_CPU/IF/IO/IO1/MEM/PF/PFQ/MBUF/DEBUG/PROC/SENSOR */
+	    break;
 	case LXT_COMMA:
 	    break;
 	default:

+ 9 - 7
symon/symon/symon.8

@@ -1,6 +1,6 @@
 .\"  -*- nroff -*-
 .\"
-.\" Copyright (c) 2001-2004 Willem Dijkstra
+.\" Copyright (c) 2001-2005 Willem Dijkstra
 .\" All rights reserved.
 .\"
 .\" Redistribution and use in source and binary forms, with or without
@@ -106,7 +106,7 @@ monitor-rule = "monitor" "{" resources "}" [every]
 resources    = resource ["(" argument ")"] [ ","|" " resources ]
 argument     = number | interfacename | diskname
 resource     = "cpu" | "mem" | "if" | "io" | "pf" | "pfq" |
-               "debug" | "proc" | "mbuf" | "sensor"
+               "debug" | "proc" | "mbuf" | "sensor" | "df"
 every        = "every" time
 time         = "second" | number "seconds"
 host         = ip4addr | ip6addr | hostname
@@ -131,7 +131,8 @@ information to localhost on port 2100.
 monitor { cpu(0),  mem, pf, if(xl0), if(de0),
 	  if(lo0), if(wi0), io(wd0), io(wd1),
 	  io(wd2), io(wd3), io(cd0), io(cd1),
-	  io(ccd0), debug, proc(httpd) } stream to 127.0.0.1 2100
+	  io(ccd0), df(sd0a), df(sd0d), df(sd0e),
+	  debug, proc(httpd) } stream to 127.0.0.1 2100
 .fi
 .Sh SIGNALS
 .Bl -tag -width Ds
@@ -170,9 +171,10 @@ does not check whether resources mentioned in
 exist.
 .Pp
 .Sh AUTHOR
-Willem Dijkstra <wpd@xs4all.nl>. Daniel Hartmeier <daniel@benzedrine.cx>
-contributed the pf probe and helped to port to big-endian architectures.
-Matthew Gream <matthew.gream@pobox.com> contributed the NetBSD and FreeBSD
-ports.
+Willem Dijkstra <wpd@xs4all.nl>. Daniel Hartmeier helped to port to big-endian
+architectures. Matthew Gream helped to port symon to other BSD platforms.
+
+Port contributors: Marc Balmer, Matthew Gream, Daniel Hartmeier, J. Martin
+Petersen, Fredrik Soderblom and Harm Schotanus.
 .Sh SEE ALSO
 .Xr symux 8

+ 12 - 11
symon/symon/symon.c

@@ -1,4 +1,4 @@
-/* $Id: symon.c,v 1.41 2005/03/20 16:17:22 dijkstra Exp $ */
+/* $Id: symon.c,v 1.43 2005/10/16 15:27:01 dijkstra Exp $ */
 
 /*
  * Copyright (c) 2001-2005 Willem Dijkstra
@@ -57,7 +57,7 @@
 
 __BEGIN_DECLS
 void alarmhandler(int);
-void drop_priviledges();
+void drop_privileges();
 void exithandler(int);
 void huphandler(int);
 void set_stream_use(struct muxlist *);
@@ -71,15 +71,16 @@ int symon_interval = SYMON_DEFAULT_INTERVAL;
 struct funcmap streamfunc[] = {
     {MT_IO1, 0, NULL, init_io, gets_io, get_io},
     {MT_CPU, 0, NULL, init_cpu, gets_cpu, get_cpu},
-    {MT_MEM, 0, NULL, init_mem, NULL, get_mem},
+    {MT_MEM, 0, NULL, init_mem, gets_mem, get_mem},
     {MT_IF, 0, NULL, init_if, gets_if, get_if},
-    {MT_PF, 0, privinit_pf, init_pf, NULL, get_pf},
+    {MT_PF, 0, privinit_pf, init_pf, gets_pf, get_pf},
     {MT_DEBUG, 0, NULL, init_debug, NULL, get_debug},
-    {MT_PROC, 0, NULL, init_proc, gets_proc, get_proc},
+    {MT_PROC, 0, privinit_proc, init_proc, gets_proc, get_proc},
     {MT_MBUF, 0, NULL, init_mbuf, NULL, get_mbuf},
     {MT_SENSOR, 0, privinit_sensor, init_sensor, NULL, get_sensor},
     {MT_IO2, 0, NULL, init_io, gets_io, get_io},
     {MT_PFQ, 0, privinit_pfq, init_pfq, gets_pfq, get_pfq},
+    {MT_DF, 0, NULL, init_df, gets_df, get_df},
     {MT_EOT, 0, NULL, NULL, NULL}
 };
 
@@ -100,14 +101,14 @@ set_stream_use(struct muxlist *mul)
     }
 }
 void
-drop_priviledges(int unsecure)
+drop_privileges(int unsecure)
 {
     struct passwd *pw;
 
     if (unsecure) {
 	if (setegid(getgid()) || setgid(getgid()) ||
 	    seteuid(getuid()) || setuid(getuid()))
-	    fatal("can't drop priviledges: %.200s", strerror(errno));
+	    fatal("can't drop privileges: %.200s", strerror(errno));
     } else {
 	if ((pw = getpwnam(SYMON_USER)) == NULL)
 	    fatal("could not get user information for user '%.200s': %.200s",
@@ -213,7 +214,7 @@ main(int argc, char *argv[])
 
     set_stream_use(&mul);
 
-    /* open resources that might not be available after priviledge drop */
+    /* open resources that might not be available after privilege drop */
     for (i = 0; i < MT_EOT; i++)
 	if (streamfunc[i].used && (streamfunc[i].privinit != NULL))
 	    (streamfunc[i].privinit) ();
@@ -222,7 +223,7 @@ main(int argc, char *argv[])
 	warning("could not open \"%.200s\", %.200s", SYMON_PID_FILE,
 		strerror(errno));
 
-    drop_priviledges(flag_unsecure);
+    drop_privileges(flag_unsecure);
 
     if (flag_debug != 1) {
 	if (daemon(0, 0) != 0)
@@ -255,7 +256,7 @@ main(int argc, char *argv[])
     SLIST_FOREACH(mux, &mul, muxes) {
 	connect2mux(mux);
 	SLIST_FOREACH(stream, &mux->sl, streams) {
-	    (streamfunc[stream->type].init) (stream->args);
+	    (streamfunc[stream->type].init) (stream);
 	}
     }
     set_stream_use(&mul);
@@ -293,7 +294,7 @@ main(int argc, char *argv[])
 		    SLIST_FOREACH(mux, &mul, muxes) {
 			connect2mux(mux);
 			SLIST_FOREACH(stream, &mux->sl, streams) {
-			    (streamfunc[stream->type].init) (stream->args);
+			    (streamfunc[stream->type].init) (stream);
 			}
 		    }
 		    set_stream_use(&mul);

+ 31 - 29
symon/symon/symon.h

@@ -1,4 +1,4 @@
-/* $Id: symon.h,v 1.33 2005/03/20 16:17:22 dijkstra Exp $ */
+/* $Id: symon.h,v 1.35 2005/10/16 15:27:01 dijkstra Exp $ */
 
 /*
  * Copyright (c) 2001-2005 Willem Dijkstra
@@ -38,12 +38,6 @@
 
 #define SYMON_PID_FILE "/var/run/symon.pid"
 #define SYMON_DEFAULT_INTERVAL 5	/* measurement interval */
-#define SYMON_WARN_SENDERR 50	        /* warn every x errors */
-#define SYMON_MAX_DOBJECTS 10000	/* max dynamic allocation; local limit per
-					 * measurement module */
-#define SYMON_MAX_OBJSIZE (_POSIX2_LINE_MAX)
-#define SYMON_SENSORMASK 0xFF           /* sensors 0-255 are allowed */
-#define SYMON_MAXCPUS 4
 
 /* funcmap holds functions to be called for the individual monitors:
  *
@@ -57,9 +51,9 @@ struct funcmap {
     int type;
     int used;
     void (*privinit) ();
-    void (*init) (char *);
+    void (*init) (struct stream *);
     void (*gets) ();
-    int (*get) (char *, int, char *);
+    int (*get) (char *, int, struct stream *);
 };
 extern struct funcmap streamfunc[];
 
@@ -68,52 +62,60 @@ extern int symon_interval;
 /* prototypes */
 __BEGIN_DECLS
 /* sm_cpu.c */
-extern void init_cpu(char *);
+extern void init_cpu(struct stream *);
 extern void gets_cpu();
-extern int get_cpu(char *, int, char *);
+extern int get_cpu(char *, int, struct stream *);
 
 /* sm_mem.c */
-extern void init_mem(char *);
-extern int get_mem(char *, int, char *);
+extern void init_mem(struct stream *);
+extern void gets_mem();
+extern int get_mem(char *, int, struct stream *);
 
 /* sm_if.c */
-extern void init_if(char *);
+extern void init_if(struct stream *);
 extern void gets_if();
-extern int get_if(char *, int, char *);
+extern int get_if(char *, int, struct stream *);
 
 /* sm_io.c */
-extern void init_io(char *);
+extern void init_io(struct stream *);
 extern void gets_io();
-extern int get_io(char *, int, char *);
+extern int get_io(char *, int, struct stream *);
 
 /* sm_pf.c */
 extern void privinit_pf();
-extern void init_pf(char *);
-extern int get_pf(char *, int, char *);
+extern void init_pf(struct stream *);
+extern void gets_pf();
+extern int get_pf(char *, int, struct stream *);
 
 /* sm_pfq.c */
 extern void privinit_pfq();
-extern void init_pfq(char *);
+extern void init_pfq(struct stream *);
 extern void gets_pfq();
-extern int get_pfq(char *, int, char *);
+extern int get_pfq(char *, int, struct stream *);
 
 /* sm_mbuf.c */
-extern void init_mbuf(char *);
-extern int get_mbuf(char *, int, char *);
+extern void init_mbuf(struct stream *);
+extern int get_mbuf(char *, int, struct stream *);
 
 /* sm_debug.c */
-extern void init_debug(char *);
-extern int get_debug(char *, int, char *);
+extern void init_debug(struct stream *);
+extern int get_debug(char *, int, struct stream *);
 
 /* sm_proc.c */
-extern void init_proc(char *);
+extern void privinit_proc();
+extern void init_proc(struct stream *);
 extern void gets_proc();
-extern int get_proc(char *, int, char *);
+extern int get_proc(char *, int, struct stream *);
 
 /* sm_sensor.c */
 extern void privinit_sensor();
-extern void init_sensor(char *);
-extern int get_sensor(char *, int, char *);
+extern void init_sensor(struct stream *);
+extern int get_sensor(char *, int, struct stream *);
+
+/* sm_df.c */
+extern void init_df(struct stream *);
+extern void gets_df();
+extern int get_df(char *, int, struct stream *);
 __END_DECLS
 
 #endif				/* _SYMON_SYMON_H */

+ 2 - 2
symon/symon/symonnet.c

@@ -1,4 +1,4 @@
-/* $Id: symonnet.c,v 1.14 2004/08/07 12:21:36 dijkstra Exp $ */
+/* $Id: symonnet.c,v 1.15 2005/10/16 15:27:01 dijkstra Exp $ */
 
 /*
  * Copyright (c) 2001-2004 Willem Dijkstra
@@ -108,7 +108,7 @@ stream_in_packet(struct stream * stream, struct mux * mux)
     (streamfunc[stream->type].get)	/* call getter of stream */
     (&mux->packet.data[mux->offset],	/* packet buffer */
      sizeof(mux->packet.data) - mux->offset,	/* maxlen */
-     stream->args);
+     stream);
 }
 /* Ready a packet for transmission, set length and crc */
 void

+ 24 - 3
symon/symux/c_smrrds.sh

@@ -1,5 +1,5 @@
 #!/bin/sh
-# $Id: c_smrrds.sh,v 1.30 2005/03/20 16:17:22 dijkstra Exp $
+# $Id: c_smrrds.sh,v 1.32 2005/10/18 19:58:13 dijkstra Exp $
 
 #
 # Copyright (c) 2001-2005 Willem Dijkstra
@@ -126,9 +126,10 @@ Linux)
 	;;
 OpenBSD)
 	DISKS="sd|cd|ch|rd|raid|ss|uk|vnc|wd"
-	INTERFACES="an|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"
+	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)
@@ -191,6 +192,8 @@ 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
 
@@ -204,12 +207,13 @@ RRD_ARGS="--step=$INTERVAL --start=0"
 case $i in
 
 all)
-    echo "Creating rrd files for {cpu0|mem|disks|interfaces|pf|mbuf}"
+    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)
@@ -222,6 +226,11 @@ io|disks)
     sh $this child $config `eval $diskcmd`
     ;;
 
+df)
+    # obtain all ffs partitions
+    sh $this child $config `eval $partcmd`
+    ;;
+
 cpu[0-9].rrd)
     # Build cpu file
     create_rrd $i \
@@ -232,6 +241,18 @@ cpu[0-9].rrd)
 	DS:idle:GAUGE:$INTERVAL:0:100
     ;;
 
+df_*.rrd)
+    # Build df file
+    create_rrd $i \
+	DS:blocks:GAUGE:$INTERVAL:0:U \
+	DS:bfree:GAUGE:$INTERVAL:0:U \
+	DS:bavail:GAUGE:$INTERVAL:0:U \
+	DS:files:GAUGE:$INTERVAL:0:U \
+	DS:ffree:GAUGE:$INTERVAL:0:U \
+	DS:syncwrites:COUNTER:$INTERVAL:U:U \
+	DS:asyncwrites:COUNTER:$INTERVAL:U:U
+    ;;
+
 sensor*.rrd)
     # Build sensor file
     create_rrd $i \

+ 11 - 5
symon/symux/readconf.c

@@ -1,4 +1,4 @@
-/* $Id: readconf.c,v 1.27 2005/03/20 16:17:22 dijkstra Exp $ */
+/* $Id: readconf.c,v 1.28 2005/10/16 15:27:03 dijkstra Exp $ */
 
 /*
  * Copyright (c) 2001-2005 Willem Dijkstra
@@ -65,6 +65,10 @@ insert_filename(char *path, int maxlen, int type, char *args)
 	ts = "cpu";
 	ta = args;
 	break;
+    case MT_DF:
+	ts = "df_";
+	ta = args;
+	break;
     case MT_IF:
 	ts = "if_";
 	ta = args;
@@ -195,6 +199,7 @@ read_source(struct sourcelist * sol, struct lex * l)
 	    while (lex_nexttoken(l) && l->op != LXT_END) {
 		switch (l->op) {
 		case LXT_CPU:
+		case LXT_DF:
 		case LXT_IF:
 		case LXT_IO:
 		case LXT_IO1:
@@ -294,13 +299,13 @@ read_source(struct sourcelist * sol, struct lex * l)
 		    if (!(insert_filename(&path[pc],
 					  _POSIX2_LINE_MAX - pc,
 					  stream->type,
-					  stream->args))) {
-			if (stream->args && strlen(stream->args)) {
+					  stream->arg))) {
+			if (stream->arg && strlen(stream->arg)) {
 			    warning("%.200s:%d: failed to construct stream "
 				    "%.200s(%.200s) filename using datadir '%.200s'",
 				    l->filename, l->cline,
 				    type2str(stream->type),
-				    stream->args, l->token);
+				    stream->arg, l->token);
 			} else {
 			    warning("%.200s:%d: failed to construct stream "
 				    "%.200s) filename using datadir '%.200s'",
@@ -328,6 +333,7 @@ read_source(struct sourcelist * sol, struct lex * l)
 	    lex_nexttoken(l);
 	    switch (l->op) {
 	    case LXT_CPU:
+	    case LXT_DF:
 	    case LXT_IF:
 	    case LXT_IO:
 	    case LXT_IO1:
@@ -481,7 +487,7 @@ read_config_file(struct muxlist * mul, const char *filename)
 		    if (stream->file == NULL) {
 			/* warn, but allow */
 			warning("%.200s: no filename specified for stream '%.200s(%.200s)' in source '%.200s'",
-				l->filename, type2str(stream->type), stream->args, source->addr);
+				l->filename, type2str(stream->type), stream->arg, source->addr);
 		    }
 		}
 	    }

+ 70 - 85
symon/symux/share.c

@@ -1,7 +1,7 @@
-/* $Id: share.c,v 1.18 2004/08/08 19:56:03 dijkstra Exp $ */
+/* $Id: share.c,v 1.20 2005/09/30 14:04:43 dijkstra Exp $ */
 
 /*
- * Copyright (c) 2001-2004 Willem Dijkstra
+ * Copyright (c) 2001-2005 Willem Dijkstra
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -58,48 +58,37 @@
  *
  * The moment the master symux receives a new packet:
  *
- * master calls master_forbidread:
- * - master checks the 'SEM_READ' semaphore to be equal to the number of
- *   children active. If so, all children are up to date. If not, a child is
- *   lagging and will die soon. Reap_clients().
- * - master adds any pending new clients
- * - master resets all semaphores, preventing clients to start reading
+ * master determines the dataslot and issues master_forbidread for that slot:
+ * - checks if the read semaphore for the slot is zero. If not, reap_clients is
+ *   called to reap any stopped clients
+ * - adds any pending new clients
+ * - reset the semaphore for the slot to prevent clients to start reading
  *
- * master calls master_permitread:
+ * master copies new data into the dataslot and calls master_permitread
  * - increment sequence number in the shared region
- * - increment 'SEM_WAIT' with the number of registered clients
+ * - increment read semaphore for the slot with the number of registered clients
  *
  * clients call client_waitread:
- * - block on semaphore 'SEM_WAIT'
- * - set client sequence number to shared region sequence number
+ * - increment client sequence number and determine dataslot
+ * - exit if client sequence number < (shared sequence - max dataslots - 1)
+ * - block on semaphore for dataslot
  *
  * clients do something to the data in the shared region
  *
- * clients call client_doneread:
- * - If the recorded sequence number deviates from the one in the shared region
- *   the client is lagging behind. The client will kill itself.
- * - The client increments 'SEM_READ'.
- *
  */
 
 __BEGIN_DECLS
-int recvfd(int);
-int sendfd(int, int);
 void check_master();
 void check_sem();
 void client_doneread();
 void client_loop();
 void client_signalhandler();
-void client_waitread();
+int client_waitread();
 void exitmaster();
-void master_resetsem();
+void master_resetsem(int);
 void reap_clients();
 __END_DECLS
 
-#define SEM_WAIT     0		/* wait semaphore */
-#define SEM_READ     1		/* have read semaphore */
-#define SEM_TOTAL    2
-
 int realclients;		/* number of clients active */
 int newclients;
 int master;			/* is current process master or child */
@@ -116,33 +105,36 @@ key_t semid;
 enum ipcstat semstat;
 int seqnr;
 /* Get start of data in shared region */
-long *
-shared_getmem()
+char *
+shared_getmem(int slot)
 {
-    return &shm->data;
+    long offset = ((slot % SYMUX_SHARESLOTS) * shm->slotlen);
+    char *data = (char *)&shm->data + offset;
+
+    return data;
 }
 /* Get max length of data stored in shared region */
 long
 shared_getmaxlen()
 {
-    return shm->reglen - sizeof(struct sharedregion);
+    return shm->slotlen;
 }
 /* Set length of data stored in shared region */
 void
-shared_setlen(long length)
+shared_setlen(int slot, long length)
 {
-    if (length > (shm->reglen - (long) sizeof(struct sharedregion)))
+    if (length > shm->slotlen)
 	fatal("%s:%d: internal error:"
 	      "set_length of shared region called with value larger than actual size",
 	      __FILE__, __LINE__);
 
-    shm->ctlen = length;
+    shm->ctlen[slot % SYMUX_SHARESLOTS] = length;
 }
 /* Get length of data stored in shared region */
 long
-shared_getlen()
+shared_getlen(int slot)
 {
-    return shm->ctlen;
+    return shm->ctlen[slot % SYMUX_SHARESLOTS];
 }
 /* Check whether semaphore is available */
 void
@@ -164,7 +156,7 @@ check_master()
 
 /* Reset semaphores before each distribution cycle */
 void
-master_resetsem()
+master_resetsem(int semnum)
 {
     union semun semarg;
 
@@ -173,16 +165,16 @@ master_resetsem()
     check_sem();
     check_master();
 
-    if ((semctl(semid, SEM_WAIT, SETVAL, semarg) != 0) ||
-	(semctl(semid, SEM_READ, SETVAL, semarg) != 0))
-	fatal("%s:%d: internal error: cannot reset semaphores",
-	      __FILE__, __LINE__);
+    if ((semctl(semid, semnum, SETVAL, semarg) != 0))
+	fatal("%s:%d: internal error: cannot reset semaphore %d",
+	      __FILE__, __LINE__, semnum);
 }
 /* Prepare for writing to shm */
-void
+int
 master_forbidread()
 {
-    int clientsread;
+    int slot = (shm->seqnr + 1) % SYMUX_SHARESLOTS;
+    int stalledclients;
     union semun semarg;
 
     check_sem();
@@ -190,43 +182,50 @@ master_forbidread()
 
     /* prepare for a new read */
     semarg.val = 0;
-    if ((clientsread = semctl(semid, SEM_READ, GETVAL, semarg)) < 0)
+    if ((stalledclients = semctl(semid, slot, GETVAL, semarg)) < 0) {
 	fatal("%s:%d: internal error: cannot read semaphore",
 	      __FILE__, __LINE__);
-
-    if (clientsread != realclients) {
+    } else {
 	reap_clients();
-	debug("realclients = %d; clientsread = %d", realclients, clientsread);
+	debug("realclients = %d; stalledclients = %d", realclients, stalledclients);
     }
 
     /* add new clients */
     realclients += newclients;
     newclients = 0;
-    master_resetsem();
+    master_resetsem(slot);
+
+    return slot;
 }
 /* Signal 'permit read' to all clients */
 void
 master_permitread()
 {
+    int slot = ++shm->seqnr % SYMUX_SHARESLOTS;
     union semun semarg;
 
-    shm->seqnr++;
-
     semarg.val = realclients;
 
-    if (semctl(semid, SEM_WAIT, SETVAL, semarg) != 0)
-	fatal("%s:%d: internal error: cannot reset semaphores",
-	      __FILE__, __LINE__);
+    if (semctl(semid, slot, SETVAL, semarg) != 0)
+	fatal("%s:%d: internal error: cannot set semaphore %d",
+	      __FILE__, __LINE__, slot);
 }
 /* Make clients wait until master signals */
-void
+int
 client_waitread()
 {
+    int slot = ++seqnr % SYMUX_SHARESLOTS;
     struct sembuf sops;
 
+    if (seqnr < (shm->seqnr - SYMUX_SHARESLOTS - 1)) {
+	close(clientsock);
+	fatal("%s:%d: client(%d) lagging behind (%d, %d) = high load?",
+	      __FILE__, __LINE__, clientpid, seqnr, shm->seqnr);
+    }
+
     check_sem();
 
-    sops.sem_num = SEM_WAIT;
+    sops.sem_num = slot;
     sops.sem_op = -1;
     sops.sem_flg = 0;
 
@@ -234,30 +233,12 @@ client_waitread()
 	fatal("%s:%d: internal error: client(%d): cannot obtain semaphore (%.200s)",
 	      __FILE__, __LINE__, clientpid, strerror(errno));
 
-    seqnr = shm->seqnr;
+    return slot;
 }
 /* Client signal 'done reading' to master */
 void
 client_doneread()
 {
-    struct sembuf sops;
-
-    check_sem();
-
-    if (seqnr != shm->seqnr) {
-	close(clientsock);
-	fatal("%s:%d: client(%d) lagging behind (%d, %d) = high load?",
-	      __FILE__, __LINE__, clientpid, seqnr, shm->seqnr);
-    }
-
-    sops.sem_num = SEM_READ;
-    sops.sem_op = 1;
-    sops.sem_flg = IPC_NOWAIT;
-
-    if (semop(semid, &sops, 1) != 0)
-	fatal("%s:%d: internal error: cannot release semaphore (%.200s)",
-	      __FILE__, __LINE__, strerror(errno));
-
     /* force scheduling by sleeping a single second */
     sleep(1);
 }
@@ -272,19 +253,22 @@ client_signalhandler(int s)
 void
 initshare(int bufsize)
 {
+    int i;
+    int totalsize;
+
     newclients = 0;
     realclients = 0;
     master = 1;
 
     /* need some extra space for housekeeping */
-    bufsize += sizeof(struct sharedregion);
+    totalsize = (bufsize * SYMUX_SHARESLOTS) + sizeof(struct sharedregion);
 
     /* allocate shared memory region for control information */
     shmstat = semstat = SIPC_FREE;
 
     atexit(exitmaster);
 
-    if ((shmid = shmget(IPC_PRIVATE, bufsize, SHM_R | SHM_W)) < 0)
+    if ((shmid = shmget(IPC_PRIVATE, totalsize, SHM_R | SHM_W)) < 0)
 	fatal("could not get a shared memory identifier");
 
     shmstat = SIPC_KEYED;
@@ -293,16 +277,18 @@ initshare(int bufsize)
 	fatal("could not attach shared memory");
 
     shmstat = SIPC_ATTACHED;
-    bzero(shm, bufsize);
-    shm->reglen = bufsize;
+    bzero(shm, totalsize);
+    debug("shm from 0x%8x to 0x%8x", shm, shm + totalsize);
+    shm->slotlen = bufsize;
 
     /* allocate semaphores */
-    if ((semid = semget(IPC_PRIVATE, SEM_TOTAL, SEM_ARGS)) < 0)
+    if ((semid = semget(IPC_PRIVATE, SYMUX_SHARESLOTS, SEM_ARGS)) < 0)
 	fatal("could not get a semaphore");
 
     semstat = SIPC_KEYED;
 
-    master_resetsem();
+    for (i = 0; i < SYMUX_SHARESLOTS; i++)
+	master_resetsem(i);
 }
 /* Spawn off a new client */
 pid_t
@@ -334,6 +320,7 @@ spawn_client(int sock)
     } else {
 	/* client */
 	master = 0;
+	seqnr = shm->seqnr;
 
 	/* catch signals */
 	signal(SIGHUP, client_signalhandler);
@@ -424,29 +411,27 @@ exitmaster()
 void
 client_loop()
 {
+    int slot;
     int total;
     int sent;
     int written;
 
     for (;;) {			/* FOREVER */
 
-	client_waitread();
-
-	total = shared_getlen();
+	slot = client_waitread();
+	total = shared_getlen(slot);
 	sent = 0;
 
 	while (sent < total) {
 
-	    if ((written = write(clientsock, (char *) (shared_getmem() + sent), total - sent)) == -1) {
+	    if ((written = write(clientsock, (char *) (shared_getmem(slot) + sent), total - sent)) == -1) {
 		info("client(%d): write error. Client will quit.", clientpid);
 		exit(1);
 	    }
 
 	    sent += written;
 
-	    debug("client(%d): written %d bytes of %d total", clientpid, sent, total);
+	    debug("client(%d): written %d bytes of %d total from slot %d", clientpid, sent, total, slot);
 	}
-
-	client_doneread();
     }
 }

+ 10 - 15
symon/symux/share.h

@@ -1,4 +1,4 @@
-/* $Id: share.h,v 1.8 2004/02/26 22:48:08 dijkstra Exp $ */
+/* $Id: share.h,v 1.9 2005/06/26 12:35:40 dijkstra Exp $ */
 
 /*
  * Copyright (c) 2001-2004 Willem Dijkstra
@@ -32,36 +32,31 @@
 
 /* TODO:
  * Dynamically allocate buffer size
- * Check wether one buffer suffices, do some performance tests
  */
 
 #ifndef _SYMUX_SHARE_H
 #define _SYMUX_SHARE_H
 
 #include "data.h"
-
-/* Share contains all routines needed for the ipc between symuxes */
-#define SEM_WAIT     0		/* wait semaphore */
-#define SEM_READ     1		/* have read semaphore */
-#define SEM_TOTAL    2
+#include "symux.h"
 
 struct sharedregion {
     long seqnr;
-    long reglen;		/* size of buffer */
-    long ctlen;			/* amount of content in buffer, assert(<
-				 * size) */
-    long data;
+    long slotlen;
+    long ctlen[SYMUX_SHARESLOTS]; /* amount of content in buffer n, assert(<
+				   * size) */
+    char *data;
 };
 
 /* prototypes */
 __BEGIN_DECLS
-void master_forbidread();
+int master_forbidread();
 void master_permitread();
-long shared_getlen();
+long shared_getlen(int);
 long shared_getmaxlen();
-long *shared_getmem();
+char *shared_getmem(int);
 void initshare();
-void shared_setlen(long);
+void shared_setlen(int, long);
 pid_t spawn_client(int);
 __END_DECLS
 

+ 16 - 10
symon/symux/symux.8

@@ -1,6 +1,6 @@
 .\"  -*- nroff -*-
 .\"
-.\" Copyright (c) 2001-2004 Willem Dijkstra
+.\" Copyright (c) 2001-2005 Willem Dijkstra
 .\" All rights reserved.
 .\"
 .\" Redistribution and use in source and binary forms, with or without
@@ -114,7 +114,7 @@ accept-stmt  = "accept" "{" resources "}"
 resources    = resource version ["(" argument ")"]
                [ ","|" " resources ]
 resource     = "cpu" | "mem" | "if" | "io" | "pf" | "pfq" |
-               "debug" | "proc" | "mbuf" | "sensor"
+               "debug" | "proc" | "mbuf" | "sensor" | "df"
 version      = "" | number
 argument     = number | interfacename | diskname
 datadir-stmt = "datadir" dirname
@@ -146,7 +146,8 @@ statement.
 Here is an example
 .Ar symux.conf
 that listens to udp port 2100 on lo0, and accepts cpu, memory, pf,
-interfaces xl0/de0/lo0/wi0, disks wd[0-3]/cd[0-1] streams from a
+interfaces xl0/de0/lo0/wi0, disks wd[0-3]/cd[0-1], disk free blocks
+of three partition streams from a
 .Xr symon 8
 on localhost.
 .Nm
@@ -159,7 +160,8 @@ source 127.0.0.1 {
 	     if(xl0), if(de0),
 	     if(lo0), if(wi0),
 	     io(wd0), io(wd1), io(wd2),
-	     io(wd3), io(cd0), io(cd1) }
+	     io(wd3), io(cd0), io(cd1),
+	     df(sd0a), df(sd0d), df(sd0e) }
 
     datadir "/var/www/symon/rrds/localhost"
 }
@@ -246,11 +248,14 @@ Mbuf statistics ( totmbufs : mt_data : mt_oobdata : mt_control :
 mt_header : mt_ftable : mt_soname : mt_soopts : pgused : pgtotal :
 totmem : totpct : m_drops : m_wait : m_drain ).
 .It sensor
-Single sensor value. ( value ) Value is a double that is offered with 7.6
-precision. Value depends on sensor type.
+Single sensor measurement offered with 7.6 precision. Value depends on sensor
+type.
 .It pfq
 pf/altq queue statistics ( sent_bytes : sent_packets : drop_bytes :
 drop_packets ). Values are 64 bit unsigned integers.
+.It df
+Disk free statistics ( blocks : bfree : bavail : files :
+ffree : synwrites : asyncwrites). Values are 64 bit unsigned integers.
 .El
 .Sh SIGNALS
 .Bl -tag -width Ds
@@ -324,9 +329,10 @@ to lockup while rrdupdate is updating the rrd file.
 .Nm
 will be unresponsive during this process.
 .Sh AUTHOR
-Willem Dijkstra <wpd@xs4all.nl>. Daniel Hartmeier <daniel@benzedrine.cx>
-contributed the pf probe and helped to port to big-endian architectures.
-Matthew Gream <matthew.gream@pobox.com> contributed the NetBSD and FreeBSD
-ports.
+Willem Dijkstra <wpd@xs4all.nl>. Daniel Hartmeier helped to port to big-endian
+architectures. Matthew Gream helped to port symon to other BSD platforms.
+
+Port contributors: Marc Balmer, Matthew Gream, Daniel Hartmeier, J. Martin
+Petersen, Fredrik Soderblom and Harm Schotanus.
 .Sh SEE ALSO
 .Xr symon 8

+ 11 - 9
symon/symux/symux.c

@@ -1,4 +1,4 @@
-/* $Id: symux.c,v 1.32 2004/08/07 12:21:36 dijkstra Exp $ */
+/* $Id: symux.c,v 1.34 2005/10/16 15:27:03 dijkstra Exp $ */
 
 /*
  * Copyright (c) 2001-2004 Willem Dijkstra
@@ -111,9 +111,10 @@ main(int argc, char *argv[])
     struct mux *mux;
     FILE *f;
     int ch;
+    int churnbuflen;
     int offset;
+    int slot;
     time_t timestamp;
-    int churnbuflen;
 
     SLIST_INIT(&mul);
 
@@ -237,9 +238,10 @@ main(int argc, char *argv[])
 	    offset = mux->offset;
 	    maxstringlen = shared_getmaxlen();
 	    /* put time:ip: into shared region */
-	    master_forbidread();
+	    slot = master_forbidread();
 	    timestamp = (time_t) packet.header.timestamp;
-	    stringbuf = (char *) shared_getmem();
+	    stringbuf = shared_getmem(slot);
+	    debug("stringbuf = 0x%8x", stringbuf);
 	    snprintf(stringbuf, maxstringlen, "%s;", source->addr);
 
 	    /* hide this string region from rrd update */
@@ -251,11 +253,11 @@ main(int argc, char *argv[])
 		offset += sunpack(packet.data + offset, &ps);
 
 		/* find stream in source */
-		stream = find_source_stream(source, ps.type, ps.args);
+		stream = find_source_stream(source, ps.type, ps.arg);
 
 		if (stream != NULL) {
-		    /* put type and args in and hide from rrd */
-		    snprintf(stringptr, maxstringlen, "%s:%s:", type2str(ps.type), ps.args);
+		    /* 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 */
@@ -300,7 +302,7 @@ main(int argc, char *argv[])
 		    stringptr += strlen(stringptr);
 		} else {
 		    debug("ignored unaccepted stream %.16s(%.16s) from %.20s", type2str(ps.type),
-			  ((ps.args == NULL) ? "0" : ps.args), source->addr);
+			  ((ps.arg == NULL) ? "0" : ps.arg), source->addr);
 		}
 	    }
 	    /*
@@ -309,7 +311,7 @@ main(int argc, char *argv[])
 	     */
 	    snprintf(stringptr, maxstringlen, "\n");
 	    stringptr += strlen(stringptr);
-	    shared_setlen((stringptr - stringbuf));
+	    shared_setlen(slot, (stringptr - stringbuf));
 	    debug("churnbuffer used: %d", (stringptr - stringbuf));
 	    master_permitread();
 	}			/* flag_hup == 0 */

+ 4 - 1
symon/symux/symux.h

@@ -1,4 +1,4 @@
-/* $Id: symux.h,v 1.19 2004/02/26 22:48:08 dijkstra Exp $ */
+/* $Id: symux.h,v 1.20 2005/06/26 12:35:41 dijkstra Exp $ */
 
 /*
  * Copyright (c) 2001-2004 Willem Dijkstra
@@ -45,4 +45,7 @@
 /* Number of retries allowed in recvfrom */
 #define SYMUX_MAXREADTRIES 5
 
+/* Number of data slots for clients in shared memory */
+#define SYMUX_SHARESLOTS  20
+
 #endif				/* _SYMUX_SYMUX_H */

+ 8 - 3
symon/symux/symuxnet.c

@@ -1,4 +1,4 @@
-/* $Id: symuxnet.c,v 1.19 2005/02/16 20:24:51 dijkstra Exp $ */
+/* $Id: symuxnet.c,v 1.20 2005/10/21 14:58:47 dijkstra Exp $ */
 
 /*
  * Copyright (c) 2001-2004 Willem Dijkstra
@@ -58,7 +58,7 @@ get_symon_sockets(struct mux * mux)
 {
     struct source *source;
     struct sockaddr_storage sockaddr;
-    int family, nsocks;
+    int family, nsocks, one = 1;
     nsocks = 0;
 
     /* generate the udp listen socket specified in the mux statement */
@@ -76,6 +76,11 @@ get_symon_sockets(struct mux * mux)
 	/* do we have a socket for this type of family */
 	if (mux->symonsocket[family] <= 0) {
 	    if ((mux->symonsocket[family] = socket(family, SOCK_DGRAM, 0)) != -1) {
+		/* attempt to set reuse, ignore errors */
+		if (setsockopt(mux->symonsocket[family], SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) == -1) {
+		    warning ("could set socket options: %.200s", strerror(errno));
+		}
+
 		/*
 		 * does the mux statement specify a specific destination
 		 * address
@@ -132,7 +137,7 @@ get_client_socket(struct mux * mux)
 	fatal("could not obtain socket: %.200s", strerror(errno));
 
     if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) == -1) {
-	fatal ("could set socket options: %.200s", strerror (errno));
+	fatal ("could set socket options: %.200s", strerror(errno));
     }
 
     bzero((void *) &hints, sizeof(struct addrinfo));