commit 9f4c960f94bc70d680400b50a84655f288e7e96d
Author: Gerrie Roos <groos@xiplink.com>
Date:   Tue Jan 10 09:00:42 2012 +0200

    Fixed collectd exec module: incorrectly exited select loop on signal.
    Sometimes dead modules won't be started up correctly or running ones would
    not generate stats anymore.  Problem manifests more often under load and on
    multicore hw

diff --git a/src/exec.c b/src/exec.c
index c64f949..322ff67 100644
--- a/src/exec.c
+++ b/src/exec.c
@@ -584,8 +584,15 @@ static void *exec_read_one (void *arg) /* {{{ */
   /* We use a copy of fdset, as select modifies it */
   copy = fdset;
 
-  while (select(highest_fd + 1, &copy, NULL, NULL, NULL ) > 0)
+  while (1)
   {
+    int e = select(highest_fd + 1, &copy, NULL, NULL, NULL );
+    if (e < 0) {
+      if (errno == EINTR)
+	continue;
+      break;
+    }
+
     int len;
 
     if (FD_ISSET(fd, &copy))

     
     
     
commit 27dd489e1242af63d2df04dfe627c440512e8da1
Author: Gerrie Roos <groos@xiplink.com>
Date:   Tue Dec 20 06:30:59 2011 +0200

    Fixed incorrect collectd warning when configuring network plugin.
    Cosmetic only

diff --git a/src/network.c b/src/network.c
index 412b457..aa1c858 100644
--- a/src/network.c
+++ b/src/network.c
@@ -1685,9 +1685,9 @@ static int network_set_interface (const sockent_t *se, const struct addrinfo *ai
 	}
 
 	/* else: Not a multicast interface. */
-#if defined(HAVE_IF_INDEXTONAME) && HAVE_IF_INDEXTONAME && defined(SO_BINDTODEVICE)
 	if (se->interface != 0)
 	{
+#if defined(HAVE_IF_INDEXTONAME) && HAVE_IF_INDEXTONAME && defined(SO_BINDTODEVICE)
 		char interface_name[IFNAMSIZ];
 
 		if (if_indextoname (se->interface, interface_name) == NULL)
@@ -1704,11 +1704,10 @@ static int network_set_interface (const sockent_t *se, const struct addrinfo *ai
 					sstrerror (errno, errbuf, sizeof (errbuf)));
 			return (-1);
 		}
-	}
 /* #endif HAVE_IF_INDEXTONAME && SO_BINDTODEVICE */
 
 #else
-	WARNING ("network plugin: Cannot set the interface on a unicast "
+		WARNING ("network plugin: Cannot set the interface on a unicast "
 			"socket because "
 # if !defined(SO_BINDTODEVICE)
 			"the the \"SO_BINDTODEVICE\" socket option "
@@ -1718,6 +1717,8 @@ static int network_set_interface (const sockent_t *se, const struct addrinfo *ai
 			"is not available on your system.");
 #endif
 
+	}
+
 	return (0);
 } /* }}} network_set_interface */
 

 
 

commit 641dc2dd4c595ede24c3997e4aa9db5c4528a2cd
Author: Gerrie Roos <groos@xiplink.com>
Date:   Wed May 25 18:28:55 2011 +0200

    Collectd's scale plugin now supports scaling only on specific data sources, yay!

diff --git a/src/target_scale.c b/src/target_scale.c
index 29fecdf..a8d7038 100644
--- a/src/target_scale.c
+++ b/src/target_scale.c
@@ -29,6 +29,9 @@ struct ts_data_s
 {
 	double factor;
 	double offset;
+
+	char **data_sources;
+	size_t data_sources_num;
 };
 typedef struct ts_data_s ts_data_t;
 
@@ -300,6 +303,67 @@ static int ts_config_set_double (double *ret, oconfig_item_t *ci) /* {{{ */
 	return (0);
 } /* }}} int ts_config_set_double */
 
+static int ts_config_add_data_source(ts_data_t *data, /* {{{ */
+		oconfig_item_t *ci)
+{
+	size_t new_data_sources_num;
+	char **temp;
+	int i;
+
+	/* Check number of arbuments. */
+	if (ci->values_num < 1)
+	{
+		ERROR ("`value' match: `%s' needs at least one argument.",
+				ci->key);
+		return (-1);
+	}
+
+	/* Check type of arguments */
+	for (i = 0; i < ci->values_num; i++)
+	{
+		if (ci->values[i].type == OCONFIG_TYPE_STRING)
+			continue;
+
+		ERROR ("`value' match: `%s' accepts only string arguments "
+				"(argument %i is a %s).",
+				ci->key, i + 1,
+				(ci->values[i].type == OCONFIG_TYPE_BOOLEAN)
+				? "truth value" : "number");
+		return (-1);
+	}
+
+	/* Allocate space for the char pointers */
+	new_data_sources_num = data->data_sources_num + ((size_t) ci->values_num);
+	temp = (char **) realloc (data->data_sources,
+			new_data_sources_num * sizeof (char *));
+	if (temp == NULL)
+	{
+		ERROR ("`value' match: realloc failed.");
+		return (-1);
+	}
+	data->data_sources = temp;
+
+	/* Copy the strings, allocating memory as needed.  */
+	for (i = 0; i < ci->values_num; i++)
+	{
+		size_t j;
+
+		/* If we get here, there better be memory for us to write to.  */
+		assert (data->data_sources_num < new_data_sources_num);
+
+		j = data->data_sources_num;
+		data->data_sources[j] = sstrdup (ci->values[i].value.string);
+		if (data->data_sources[j] == NULL)
+		{
+			ERROR ("`value' match: sstrdup failed.");
+			continue;
+		}
+		data->data_sources_num++;
+	}
+
+	return (0);
+} /* }}} int ts_config_add_data_source */
+
 static int ts_destroy (void **user_data) /* {{{ */
 {
 	ts_data_t **data;
@@ -309,6 +373,13 @@ static int ts_destroy (void **user_data) /* {{{ */
 
 	data = (ts_data_t **) user_data;
 
+	if (*data && (*data)->data_sources) {
+		size_t i;
+		for (i = 0; i < (*data)->data_sources_num; i++)
+			free((*data)->data_sources[i]);
+		free((*data)->data_sources);
+	}
+
 	free (*data);
 	*data = NULL;
 
@@ -341,6 +412,8 @@ static int ts_create (const oconfig_item_t *ci, void **user_data) /* {{{ */
 				status = ts_config_set_double (&data->factor, child);
 		else if (strcasecmp ("Offset", child->key) == 0)
 				status = ts_config_set_double (&data->offset, child);
+		else if (strcasecmp ("DataSource", child->key) == 0)
+				status = ts_config_add_data_source(data, child);
 		else
 		{
 			ERROR ("Target `scale': The `%s' configuration option is not understood "
@@ -393,6 +466,18 @@ static int ts_invoke (const data_set_t *ds, value_list_t *vl, /* {{{ */
 
 	for (i = 0; i < ds->ds_num; i++)
 	{
+		/* If we've got a list of data sources, is it in the list? */
+		if (data->data_sources) {
+			size_t j;
+			for (j = 0; j < data->data_sources_num; j++)
+				if (strcasecmp(ds->ds[i].name, data->data_sources[j]) == 0)
+					break;
+
+			/* No match, ignore */
+			if (j >= data->data_sources_num)
+				continue;
+		}
+
 		if (ds->ds[i].type == DS_TYPE_COUNTER)
 			ts_invoke_counter (ds, vl, data, i);
 		else if (ds->ds[i].type == DS_TYPE_GAUGE)


