[hobbit] Patch not done yet? was RE: rrd-data.log

Henrik Stoerner henrik at hswn.dk
Thu Aug 3 12:23:00 CEST 2006


On Wed, Aug 02, 2006 at 11:07:06AM -0500, Brodie, Kent wrote:
> Hi Henrik:   Below are snippets from rrd that are still causing the
> "Duplicate Error" on my end, even after applying the patch.   In the
> cases where there's netstat and ifstat data shown together, I had to
> include both because those chunks of data came out right at the time the
> duplicate error appeared.    Too hard to time/see which of those 2
> chunks of data cause the problem.   In other cases, only ifstat data
> caused the problem.

It's the ifstat data; or specifically - it is the interface aliases
("eth0:1") that messed up how the data was being parsed. So a somewhat
larger patch was required. Backout the previous patch I sent you, and
apply this one instead.

Or grab the current snapshot if you cannot get it applied without
problems.


Regards,
Henrik

-------------- next part --------------
--- hobbitd/do_rrd.c	2006/07/20 16:06:41	1.36
+++ hobbitd/do_rrd.c	2006/08/03 10:17:27
@@ -225,6 +225,61 @@
 }
 
 
+static pcre **compile_exprs(char *id, const char **patterns, int count)
+{
+	pcre **result = NULL;
+	int i;
+
+	result = (pcre **)calloc(count, sizeof(pcre *));
+	for (i=0; (i < count); i++) {
+		result[i] = compileregex(patterns[i]);
+		if (!result[i]) {
+			errprintf("Internal error: %s pickdata PCRE-compile failed\n", id);
+			for (i=0; (i < count); i++) if (result[i]) pcre_free(result[i]);
+			xfree(result);
+			return NULL;
+		}
+	}
+
+	return result;
+}
+
+static int pickdata(char *buf, pcre *expr, int dupok, ...)
+{
+	int res, i;
+	int ovector[30];
+	va_list ap;
+	char **ptr;
+	char w[100];
+
+	res = pcre_exec(expr, NULL, buf, strlen(buf), 0, 0, ovector, (sizeof(ovector)/sizeof(int)));
+	if (res < 0) return 0;
+
+	va_start(ap, dupok);
+
+	for (i=1; (i < res); i++) {
+		*w = '\0';
+		pcre_copy_substring(buf, ovector, res, i, w, sizeof(w));
+		ptr = va_arg(ap, char **);
+		if (dupok) {
+			if (*ptr) xfree(*ptr);
+			*ptr = strdup(w);
+		}
+		else {
+			if (*ptr == NULL) {
+				*ptr = strdup(w);
+			}
+			else {
+				errprintf("Internal error: Duplicate match ignored\n");
+			}
+		}
+	}
+
+	va_end(ap);
+
+	return 1;
+}
+
 /* Include all of the sub-modules. */
 #include "rrd/do_bbgen.c"
 #include "rrd/do_bbtest.c"
--- hobbitd/rrd/do_ifstat.c	2006/08/01 21:32:37	1.7
+++ hobbitd/rrd/do_ifstat.c	2006/08/03 10:15:38
@@ -20,7 +20,7 @@
 /* eth0   Link encap:                                                 */
 /*        RX bytes: 1829192 (265.8 MiB)  TX bytes: 1827320 (187.7 MiB */
 static const char *ifstat_linux_exprs[] = {
-	"^([a-z]+[0-9]+)\\s",
+	"^([a-z]+[0123456789.:]+|lo)\\s",
 	"^\\s+RX bytes:([0-9]+) .*TX bytes.([0-9]+) "
 };
 
@@ -73,7 +73,7 @@
 */
 static const char *ifstat_aix_exprs[] = {
 	"^ETHERNET STATISTICS \\(([a-z0-9]+)\\) :",
-	"^Bytes:\\s+(\\d+)\\s+(\\d+)"
+	"^Bytes:\\s+(\\d+)\\s+Bytes:\\s+(\\d+)"
 };
 
 
@@ -176,25 +176,39 @@
 		  case OS_LINUX22:
 		  case OS_LINUX:
 		  case OS_RHEL3:
-			if (pickdata(bol, ifstat_linux_pcres[0], &ifname)) dmatch |= 1;
-			else if (pickdata(bol, ifstat_linux_pcres[1], &rxstr, &txstr)) dmatch |= 6;
+			if (pickdata(bol, ifstat_linux_pcres[0], 1, &ifname)) {
+				/*
+				 * Linux' netif aliases mess up things. 
+				 * Clear everything when we see an interface name.
+				 * But we dont want to track the "lo" interface.
+				 */
+				if (strcmp(ifname, "lo") == 0) {
+					xfree(ifname); ifname = NULL;
+				}
+				else {
+					dmatch = 1;
+					if (rxstr) { xfree(rxstr); rxstr = NULL; }
+					if (txstr) { xfree(txstr); txstr = NULL; }
+				}
+			}
+			else if (pickdata(bol, ifstat_linux_pcres[1], 1, &rxstr, &txstr)) dmatch |= 6;
 			break;
 
 		  case OS_FREEBSD:
-			if (pickdata(bol, ifstat_freebsd_pcres[0], &ifname, &rxstr, &txstr)) dmatch = 7;
+			if (pickdata(bol, ifstat_freebsd_pcres[0], 0, &ifname, &rxstr, &txstr)) dmatch = 7;
 			break;
 
 		  case OS_OPENBSD:
-			if (pickdata(bol, ifstat_openbsd_pcres[0], &ifname, &rxstr, &txstr)) dmatch = 7;
+			if (pickdata(bol, ifstat_openbsd_pcres[0], 0, &ifname, &rxstr, &txstr)) dmatch = 7;
 			break;
 
 		  case OS_NETBSD:
-			if (pickdata(bol, ifstat_netbsd_pcres[0], &ifname, &rxstr, &txstr)) dmatch = 7;
+			if (pickdata(bol, ifstat_netbsd_pcres[0], 0, &ifname, &rxstr, &txstr)) dmatch = 7;
 			break;
 
 		  case OS_SOLARIS: 
-			if (pickdata(bol, ifstat_solaris_pcres[0], &ifname, &txstr)) dmatch |= 1;
-			else if (pickdata(bol, ifstat_solaris_pcres[1], &dummy, &rxstr)) dmatch |= 6;
+			if (pickdata(bol, ifstat_solaris_pcres[0], 0, &ifname, &txstr)) dmatch |= 1;
+			else if (pickdata(bol, ifstat_solaris_pcres[1], 0, &dummy, &rxstr)) dmatch |= 6;
 
 			if (ifname && dummy && (strcmp(ifname, dummy) != 0)) {
 				/* They must match, drop the data */
@@ -205,22 +219,32 @@
 			break;
 
 		  case OS_AIX: 
-			if (pickdata(bol, ifstat_aix_pcres[0], &ifname)) dmatch |= 1;
-			else if (pickdata(bol, ifstat_aix_pcres[1], &txstr, &rxstr)) dmatch |= 6;
+			if (pickdata(bol, ifstat_aix_pcres[0], 1, &ifname)) {
+				/* Interface names comes first, so any rx/tx data is discarded */
+				dmatch |= 1;
+				if (rxstr) { xfree(rxstr); rxstr = NULL; }
+				if (txstr) { xfree(txstr); txstr = NULL; }
+			}
+			else if (pickdata(bol, ifstat_aix_pcres[1], 1, &txstr, &rxstr)) dmatch |= 6;
 			break;
 
 		  case OS_HPUX: 
-			if (pickdata(bol, ifstat_hpux_pcres[0], &ifname)) dmatch |= 1;
-			else if (pickdata(bol, ifstat_hpux_pcres[1], &rxstr)) dmatch |= 2;
-			else if (pickdata(bol, ifstat_hpux_pcres[2], &txstr)) dmatch |= 4;
+			if (pickdata(bol, ifstat_hpux_pcres[0], 1, &ifname)) {
+				/* Interface names comes first, so any rx/tx data is discarded */
+				dmatch |= 1;
+				if (rxstr) { xfree(rxstr); rxstr = NULL; }
+				if (txstr) { xfree(txstr); txstr = NULL; }
+			}
+			else if (pickdata(bol, ifstat_hpux_pcres[1], 1, &rxstr)) dmatch |= 2;
+			else if (pickdata(bol, ifstat_hpux_pcres[2], 1, &txstr)) dmatch |= 4;
 			break;
 
 		  case OS_DARWIN:
-			if (pickdata(bol, ifstat_darwin_pcres[0], &ifname, &rxstr, &txstr)) dmatch = 7;
+			if (pickdata(bol, ifstat_darwin_pcres[0], 0, &ifname, &rxstr, &txstr)) dmatch = 7;
 			break;
 			
  		  case OS_SCO_SV:
-		        if (pickdata(bol, ifstat_sco_sv_pcres[0], &ifname, &rxstr, &txstr)) dmatch = 7;
+		        if (pickdata(bol, ifstat_sco_sv_pcres[0], 0, &ifname, &rxstr, &txstr)) dmatch = 7;
 			break;
 			
 		  case OS_OSF:
--- hobbitd/rrd/do_netstat.c	2006/08/01 21:32:37	1.25
+++ hobbitd/rrd/do_netstat.c	2006/08/03 10:01:21
@@ -46,55 +46,6 @@
             *tcpretransbytes = NULL, *tcpretranspackets = NULL;
 
 
-static pcre **compile_exprs(char *id, const char **patterns, int count)
-{
-	pcre **result = NULL;
-	int i;
-
-	result = (pcre **)calloc(count, sizeof(pcre *));
-	for (i=0; (i < count); i++) {
-		result[i] = compileregex(patterns[i]);
-		if (!result[i]) {
-			errprintf("Internal error: %s netstat PCRE-compile failed\n", id);
-			for (i=0; (i < count); i++) if (result[i]) pcre_free(result[i]);
-			xfree(result);
-			return NULL;
-		}
-	}
-
-	return result;
-}
-
-static int pickdata(char *buf, pcre *expr, ...)
-{
-	int res, i;
-	int ovector[30];
-	va_list ap;
-	char **ptr;
-	char w[100];
-
-	res = pcre_exec(expr, NULL, buf, strlen(buf), 0, 0, ovector, (sizeof(ovector)/sizeof(int)));
-	if (res < 0) return 0;
-
-	va_start(ap, expr);
-
-	for (i=1; (i < res); i++) {
-		*w = '\0';
-		pcre_copy_substring(buf, ovector, res, i, w, sizeof(w));
-		ptr = va_arg(ap, char **);
-		if (*ptr == NULL) {
-			*ptr = strdup(w);
-		}
-		else {
-			errprintf("Internal error: Duplicate match ignored\n");
-		}
-	}
-
-	va_end(ap);
-
-	return 1;
-}
-
 static void prepare_update(char *outp)
 {
 	outp += sprintf(outp, ":%s", (udpreceived ? udpreceived : "U")); if (udpreceived) xfree(udpreceived);
@@ -135,20 +86,20 @@
 		else {
 			switch (sect) {
 			  case AT_TCP:
-				if (pickdata(datapart, pcreset[0], &tcpretranspackets, &tcpretransbytes)   ||
-				    pickdata(datapart, pcreset[1], &tcpoutdatapackets, &tcpoutdatabytes)   ||
-				    pickdata(datapart, pcreset[2], &tcpinorderpackets, &tcpinorderbytes)   ||
-				    pickdata(datapart, pcreset[3], &tcpoutorderpackets, &tcpoutorderbytes) ||
-				    pickdata(datapart, pcreset[4], &tcpconnrequests)                       ||
-				    pickdata(datapart, pcreset[5], &tcpconnaccepts)) havedata++;
+				if (pickdata(datapart, pcreset[0],  0, &tcpretranspackets, &tcpretransbytes)   ||
+				    pickdata(datapart, pcreset[1],  0, &tcpoutdatapackets, &tcpoutdatabytes)   ||
+				    pickdata(datapart, pcreset[2],  0, &tcpinorderpackets, &tcpinorderbytes)   ||
+				    pickdata(datapart, pcreset[3],  0, &tcpoutorderpackets, &tcpoutorderbytes) ||
+				    pickdata(datapart, pcreset[4],  0, &tcpconnrequests)                       ||
+				    pickdata(datapart, pcreset[5],  0, &tcpconnaccepts)) havedata++;
 				break;
 
 			  case AT_UDP:
-				if (pickdata(datapart, pcreset[6], &udpreceived)   ||
-				    pickdata(datapart, pcreset[7], &udpsent)       ||
-				    pickdata(datapart, pcreset[8], &udperr1)       ||
-				    pickdata(datapart, pcreset[9], &udperr2)       ||
-				    pickdata(datapart, pcreset[10], &udperr3)) havedata++;
+				if (pickdata(datapart, pcreset[6],  0, &udpreceived)   ||
+				    pickdata(datapart, pcreset[7],  0, &udpsent)       ||
+				    pickdata(datapart, pcreset[8],  0, &udperr1)       ||
+				    pickdata(datapart, pcreset[9],  0, &udperr2)       ||
+				    pickdata(datapart, pcreset[10], 0, &udperr3)) havedata++;
 				break;
 
 			  default:


More information about the Xymon mailing list