[collectd] [PATCH] processes_plugin: added option to account children of processes

Lukas Bednar lbednar at redhat.com
Thu Sep 29 14:22:57 CEST 2011


Hi,

I send patch with improving of process plugin. I tested it on Linux and
FreeBSD. It works. I have no access on AIX and OSX platforms.

 From f56334e2a71131e83d46aa7d9f67dbfb2c0b2eb9 Mon Sep 17 00:00:00 2001
From: Lukas Bednar <lbednar at redhat.com>
Date: Thu, 29 Sep 2011 07:56:52 +0200
Subject: [PATCH] processes_plugin: added option to account children of
  processes

Added AccountChildren option in order measure data from children
of processes.
---
  src/processes.c |  447 
+++++++++++++++++++++++++++++++++++++++++--------------
  src/rrdtool.c   |    3 +-
  2 files changed, 339 insertions(+), 111 deletions(-)

diff --git a/src/processes.c b/src/processes.c
index 8f4eb88..ea1b611 100644
--- a/src/processes.c
+++ b/src/processes.c
@@ -161,6 +161,8 @@ typedef struct procstat
  	regex_t *re;
  #endif

+	unsigned short children;
+
  	unsigned long num_proc;
  	unsigned long num_lwp;
  	unsigned long vmem_size;
@@ -186,6 +188,9 @@ typedef struct procstat
  } procstat_t;

  static procstat_t *list_head_g = NULL;
+static procstat_entry_t *list_childs_head_g = NULL;
+
+static int ps_get_ppid(unsigned int pid);

  #if HAVE_THREAD_INFO
  static mach_port_t port_host_self;
@@ -200,12 +205,14 @@ static long pagesize_g;
  /* #endif KERNEL_LINUX */

  #elif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD
-/* no global variables */
+static struct kinfo_proc *procs_g;
+static int procs_count_g;
  /* #endif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD */

  #elif HAVE_PROCINFO_H
-static  struct procentry64 procentry[MAXPROCENTRY];
-static  struct thrdentry64 thrdentry[MAXTHRDENTRY];
+static struct procentry64 procentry[MAXPROCENTRY];
+static int procentry_count_g;
+static struct thrdentry64 thrdentry[MAXTHRDENTRY];
  static int pagesize;

  #ifndef _AIXVERSION_610
@@ -218,7 +225,7 @@ int getargs (struct procentry64 *processBuffer, int 
bufferLen, char *argsBuffer,
  /* put name of process from config to list_head_g tree
     list_head_g is a list of 'procstat_t' structs with
     processes names we want to watch */
-static void ps_list_register (const char *name, const char *regexp)
+static void ps_list_register (const char *name, const char *regexp, 
unsigned short children)
  {
  	procstat_t *new;
  	procstat_t *ptr;
@@ -233,6 +240,8 @@ static void ps_list_register (const char *name, 
const char *regexp)
  	memset (new, 0, sizeof (procstat_t));
  	sstrncpy (new->name, name, sizeof (new->name));

+	new->children = children;
+
  #if HAVE_REGEX_H
  	if (regexp != NULL)
  	{
@@ -320,40 +329,95 @@ static int ps_list_match (const char *name, const 
char *cmdline, procstat_t *ps)
  	return (0);
  } /* int ps_list_match */

+static procstat_entry_t * ps_new_procstat_entry(procstat_entry_t 
**head, procstat_entry_t *last)
+{
+	procstat_entry_t * new = (procstat_entry_t*) malloc(sizeof 
(procstat_entry_t));
+	if (new != NULL)
+	{
+		memset (new, 0, sizeof (procstat_entry_t));
+
+		if(last == NULL)
+			*head = new;
+		else
+			last->next = new;
+	}
+	else
+		ERROR ("process plugin: ps_new_procstat_entry failed to allocate "
+				"memory for new processes");
+	return new;
+}
+
+static procstat_entry_t *ps_find_procstat_entry(procstat_entry_t *pse, 
unsigned long id)
+{
+	for (;pse != NULL; pse = pse->next)
+	{
+		if (pse->id == id || pse->next == NULL)
+			break;
+	}
+	return pse;
+}
+
  /* add process entry to 'instances' of process 'name' (or refresh it) */
  static void ps_list_add (const char *name, const char *cmdline, 
procstat_entry_t *entry)
  {
  	procstat_t *ps;
  	procstat_entry_t *pse;
+    int current_pid;
+    int ppid;
+    int parent_found;
+    unsigned short children;

  	if (entry->id == 0)
  		return;

  	for (ps = list_head_g; ps != NULL; ps = ps->next)
  	{
+		current_pid = 0;
+		ppid = entry->id;
+		parent_found = 0;
+		children = ps->children;
+
  		if ((ps_list_match (name, cmdline, ps)) == 0)
-			continue;
+		{
+			while (children > 0 && parent_found == 0 && ppid != -1)
+			{
+				current_pid = ppid;
+				for (pse = ps->instances; pse != NULL; pse = pse->next)
+					if (pse->id == current_pid)
+					{
+						parent_found = 1;
+						break;
+					}
+					else if (pse->next == NULL)
+						break;
+					ppid = ps_get_ppid(current_pid);
+					children--;
+			}
+			if (parent_found == 0)
+					continue;

-		for (pse = ps->instances; pse != NULL; pse = pse->next)
-			if ((pse->id == entry->id) || (pse->next == NULL))
-				break;
+			pse = ps_find_procstat_entry(list_childs_head_g, entry->id);
+			if (pse == NULL || (pse->id != entry->id))
+			{
+				pse = ps_new_procstat_entry (&list_childs_head_g, pse);
+				if (pse == NULL)
+					return;

-		if ((pse == NULL) || (pse->id != entry->id))
+				pse->id = entry->id;
+			}
+		}
+		else
  		{
-			procstat_entry_t *new;
-
-			new = (procstat_entry_t *) malloc (sizeof (procstat_entry_t));
-			if (new == NULL)
-				return;
-			memset (new, 0, sizeof (procstat_entry_t));
-			new->id = entry->id;
+			pse = ps_find_procstat_entry(ps->instances, entry->id);
+		}

+		if ((pse == NULL) || (pse->id != entry->id))
+		{
+			pse = ps_new_procstat_entry (&ps->instances, pse);
  			if (pse == NULL)
-				ps->instances = new;
-			else
-				pse->next = new;
+				return;

-			pse = new;
+			pse->id = entry->id;
  		}

  		pse->age = 0;
@@ -418,7 +482,7 @@ static void ps_list_add (const char *name, const 
char *cmdline, procstat_entry_t

  		ps->vmem_minflt_counter += pse->vmem_minflt;
  		ps->vmem_majflt_counter += pse->vmem_majflt;
-
+		
  		if ((entry->cpu_user_counter == 0)
  				&& (entry->cpu_system_counter == 0))
  		{
@@ -458,12 +522,46 @@ static void ps_list_add (const char *name, const 
char *cmdline, procstat_entry_t
  	}
  }

+static void ps_list_procstat_entry_reset(procstat_entry_t **head, const 
char *name)
+{
+	procstat_entry_t *pse = *head;
+	procstat_entry_t *pse_prev = NULL;
+		
+	while (pse != NULL)
+	{
+		if (pse->age > 10)
+		{
+			DEBUG ("Removing this procstat entry cause it's too old: "
+					"id = %lu; name = %s;",
+					pse->id, name);
+
+			if (pse_prev == NULL)
+			{
+				*head = pse->next;
+				free (pse);
+				pse = *head;
+			}
+			else
+			{
+				pse_prev->next = pse->next;
+				free (pse);
+				pse = pse_prev->next;
+			}
+		}
+		else
+		{
+			pse->age++;
+			pse_prev = pse;
+			pse = pse->next;
+		}
+	} /* while (pse != NULL) */
+
+}
+
  /* remove old entries from instances of processes in list_head_g */
  static void ps_list_reset (void)
  {
  	procstat_t *ps;
-	procstat_entry_t *pse;
-	procstat_entry_t *pse_prev;

  	for (ps = list_head_g; ps != NULL; ps = ps->next)
  	{
@@ -479,43 +577,84 @@ static void ps_list_reset (void)
  		ps->io_syscr = -1;
  		ps->io_syscw = -1;

-		pse_prev = NULL;
-		pse = ps->instances;
-		while (pse != NULL)
+		ps_list_procstat_entry_reset (&ps->instances, ps->name);
+	} /* for (ps = list_head_g; ps != NULL; ps = ps->next) */
+
+	ps_list_procstat_entry_reset (&list_childs_head_g, "child of process");
+}
+
+static unsigned short ps_config_tree(oconfig_item_t *c)
+{
+	unsigned short children = 0;
+
+	if (strcasecmp (c->key, "AccountChildren") == 0)
+	{
+		if (c->values_num != 1) {
+			WARNING ("processes plugin: the `AccountChildren' expects "
+					"exactly one boolean or number argument (got %i). "
+					"-- use 'false' option by default", c->values_num);
+		}
+		
+		if (c->children_num != 0)
  		{
-			if (pse->age > 10)
-			{
-				DEBUG ("Removing this procstat entry cause it's too old: "
-						"id = %lu; name = %s;",
-						pse->id, ps->name);
+			WARNING ("processes plugin: the `AccountChildren' config "
+					"option does not expect any child elements -- ignoring "
+					"content (%i elements) of the <Process '%s'> block.",
+					c->children_num, c->values[0].value.string);
+		}

-				if (pse_prev == NULL)
-				{
-					ps->instances = pse->next;
-					free (pse);
-					pse = ps->instances;
-				}
-				else
-				{
-					pse_prev->next = pse->next;
-					free (pse);
-					pse = pse_prev->next;
-				}
+		if (c->values[0].type == OCONFIG_TYPE_STRING)
+		{
+			if (strcmp (c->values[0].value.string, "true") == 0)
+			{
+				children = (unsigned short) -1;
+			}
+			else if (strcmp (c->values[0].value.string, "false") != 0)
+			{
+				WARNING ("processes plugin: the `AccountChildren' option "
+						"expects true|false options. got '%s' -- use "
+						"'false' option by default",
+						c->values[0].value.string);
+			}
+		}
+		else if (c->values[0].type == OCONFIG_TYPE_NUMBER)
+		{
+			if (c->values[0].value.number < 0)
+			{
+				WARNING ("processes plugin: the `AccountChildren' option "
+						"expects positive number, got '%f'. -- use '0' "
+						"option by default.", c->values[0].value.number);
  			}
  			else
  			{
-				pse->age++;
-				pse_prev = pse;
-				pse = pse->next;
+				children = (unsigned short) c->values[0].value.number;
  			}
-		} /* while (pse != NULL) */
-	} /* for (ps = list_head_g; ps != NULL; ps = ps->next) */
+		}
+		else if (c->values[0].type == OCONFIG_TYPE_BOOLEAN)
+		{
+			if (c->values[0].value.boolean == 0)
+				children = 0;
+			else
+				children = (unsigned short) -1;
+		}
+		else
+		{
+			ERROR("processes plugin: unreachable statement");
+		}
+	}
+	else
+	{
+		WARNING("processes plugin: unexpected option '%s' -- ignoring", c->key);
+	}
+
+	return children;
  }

  /* put all pre-defined 'Process' names from config to list_head_g tree */
  static int ps_config (oconfig_item_t *ci)
  {
  	int i;
+	unsigned short children = 0;

  	for (i = 0; i < ci->children_num; ++i) {
  		oconfig_item_t *c = ci->children + i;
@@ -531,13 +670,18 @@ static int ps_config (oconfig_item_t *ci)
  			}

  			if (c->children_num != 0) {
-				WARNING ("processes plugin: the `Process' config option "
-						"does not expect any child elements -- ignoring "
-						"content (%i elements) of the <Process '%s'> block.",
-						c->children_num, c->values[0].value.string);
+				if (c->children_num > 1)
+				{
+					WARNING ("processes plugin: the `Process' config option "
+							"expects at maximal one child elements -- use only "
+							"first element, ignoring content (%i elements) of "
+							"the <Process '%s'> block.",
+							c->children_num - 1, c->values[0].value.string);
+				}
+				children = ps_config_tree(c->children);
  			}

-			ps_list_register (c->values[0].value.string, NULL);
+			ps_list_register (c->values[0].value.string, NULL, children);
  		}
  		else if (strcasecmp (c->key, "ProcessMatch") == 0)
  		{
@@ -552,15 +696,22 @@ static int ps_config (oconfig_item_t *ci)
  			}

  			if (c->children_num != 0) {
-				WARNING ("processes plugin: the `ProcessMatch' config option "
-						"does not expect any child elements -- ignoring "
-						"content (%i elements) of the <ProcessMatch '%s' '%s'> "
-						"block.", c->children_num, c->values[0].value.string,
-						c->values[1].value.string);
+				if (c->children_num > 1)
+				{
+					WARNING ("processes plugin: the `ProcessMatch' config "
+							"option expects at maximal one child element "
+							"-- use only first element, ignoring content "
+							"(%i elements) of the <ProcessMatch '%s' '%s'> "
+							"block.", c->children_num - 1,
+						    c->values[0].value.string,
+							c->values[1].value.string);
+				}
+
+				children = ps_config_tree(c->children);
  			}

  			ps_list_register (c->values[0].value.string,
-					c->values[1].value.string);
+					c->values[1].value.string, children);
  		}
  		else
  		{
@@ -712,7 +863,7 @@ static void ps_submit_proc_list (procstat_t *ps)
  	}

  	DEBUG ("name = %s; num_proc = %lu; num_lwp = %lu; "
-                        "vmem_size = %lu; vmem_rss = %lu; vmem_data = 
%lu; "
+			"vmem_size = %lu; vmem_rss = %lu; vmem_data = %lu; "
  			"vmem_code = %lu; "
  			"vmem_minflt_counter = %"PRIi64"; vmem_majflt_counter = %"PRIi64"; "
  			"cpu_user_counter = %"PRIi64"; cpu_system_counter = %"PRIi64"; "
@@ -728,6 +879,54 @@ static void ps_submit_proc_list (procstat_t *ps)

  /* ------- additional functions for KERNEL_LINUX/HAVE_THREAD_INFO 
------- */
  #if KERNEL_LINUX
+static int ps_read_stat(unsigned int pid, char **fields, int fields_len)
+{
+	char filename[PATH_MAX];
+	char buffer[1024];
+	int i;
+	
+	ssnprintf (filename, sizeof (filename), "/proc/%i/stat", pid);
+
+	i = read_file_contents (filename, buffer, sizeof(buffer) - 1);
+	if (i <= 0)
+		return (-1);
+	buffer[i] = 0;
+
+	fields_len = strsplit (buffer, fields, fields_len);
+	if (fields_len < 24)
+	{
+		DEBUG ("processes plugin: ps_read_process (pid = %i):"
+				" `%s' has only %i fields..",
+				(int) pid, filename, fields_len);
+		return (-1);
+	}
+	return fields_len;
+}
+
+static int ps_get_ppid(unsigned int pid)
+{
+	int ppid;
+	char *fields[64];
+	int fields_len;
+	
+	if (pid != 1)
+	{
+		fields_len = ps_read_stat(pid, fields, STATIC_ARRAY_SIZE(fields));
+		if (fields_len != -1)
+		{
+			ppid = atoi (fields[3]);
+			if (ppid > 0)
+				return ppid;
+		}
+		else
+		{
+			DEBUG ("processes plugin: ps_get_ppid (pid = %i) can't "
+					"retrieve PPID", pid);
+		}
+	}
+	return (-1);
+}
+
  static int ps_read_tasks (int pid)
  {
  	char           dirname[64];
@@ -780,7 +979,7 @@ static procstat_t *ps_read_vmem (int pid, procstat_t 
*ps)
  			continue;

  		numfields = strsplit (buffer, fields,
-                                      STATIC_ARRAY_SIZE (fields));
+										STATIC_ARRAY_SIZE (fields));

  		if (numfields < 2)
  			continue;
@@ -875,14 +1074,9 @@ static procstat_t *ps_read_io (int pid, procstat_t 
*ps)

  int ps_read_process (int pid, procstat_t *ps, char *state)
  {
-	char  filename[64];
-	char  buffer[1024];
-
  	char *fields[64];
  	char  fields_len;

-	int   i;
-
  	int   name_len;

  	derive_t cpu_user_counter;
@@ -892,22 +1086,10 @@ int ps_read_process (int pid, procstat_t *ps, 
char *state)
  	long long unsigned stack_size;

  	memset (ps, 0, sizeof (procstat_t));
-
-	ssnprintf (filename, sizeof (filename), "/proc/%i/stat", pid);
-
-	i = read_file_contents (filename, buffer, sizeof(buffer) - 1);
-	if (i <= 0)
-		return (-1);
-	buffer[i] = 0;
-
-	fields_len = strsplit (buffer, fields, STATIC_ARRAY_SIZE (fields));
-	if (fields_len < 24)
-	{
-		DEBUG ("processes plugin: ps_read_process (pid = %i):"
-				" `%s' has only %i fields..",
-				(int) pid, filename, fields_len);
-		return (-1);
-	}
+	
+	fields_len = ps_read_stat(pid, fields, STATIC_ARRAY_SIZE(fields));
+	if (fields_len == -1)
+		return fields_len;

  	/* copy the name, strip brackets in the process */
  	name_len = strlen (fields[1]) - 2;
@@ -1153,8 +1335,38 @@ static void ps_submit_fork_rate (unsigned long value)

  	plugin_dispatch_values (&vl);
  }
+/* endif KERNEL_LINUX */

-#endif /* KERNEL_LINUX */
+#elif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD
+static int ps_get_ppid(unsigned int pid)
+{
+	int i;
+	if (pid != 1)
+	{
+		for (i = 0; i < procs_count_g; i++)
+		{
+			if (procs_g[i].ki_pid == pid)
+				return procs_g[i].ki_ppid;
+		}
+		DEBUG ("processes plugin: ps_get_ppid (pid = %i) can't retrieve 
PPID", pid);
+	}
+	return (-1);
+}
+#elif HAVE_PROCINFO_H
+static int ps_get_ppid(unsigned int pid)
+{
+	int i;
+	if (pid != 1)
+	{
+		for (i = 0; i < procentry_count_g; i++)
+		{
+			if (procentry[i].pi_pid == pid)
+				return procentry[i].pi_ppid;
+		}
+		DEBUG ("processes plugin: ps_get_ppid (pid = %i) can't retrieve 
PPID", pid);
+	}
+}
+#endif

  #if HAVE_THREAD_INFO
  static int mach_get_task_name (task_t t, int *pid, char *name, size_t 
name_max_len)
@@ -1190,6 +1402,22 @@ static int mach_get_task_name (task_t t, int 
*pid, char *name, size_t name_max_l

  	return (0);
  }
+
+static int ps_get_ppid(unsigned int pid)
+{
+	struct kinfo_proc kp;
+	int ppid = -1;
+
+	if (pid != 1)
+	{
+		if (get_kinfo_proc (pid, &kp) != -1)
+			ppid = kp.kp_eproc.e_ppid;
+		else
+			DEBUG ("processes plugin: ps_get_ppid (pid = %i) can't retrieve 
PPID", pid);
+	}
+	return ppid;
+
+}
  #endif /* HAVE_THREAD_INFO */
  /* ------- end of additional functions for 
KERNEL_LINUX/HAVE_THREAD_INFO ------- */

@@ -1468,7 +1696,6 @@ static int ps_read (void)
  	int stopped  = 0;
  	int paging   = 0;
  	int blocked  = 0;
-
  	struct dirent *ent;
  	DIR           *proc;
  	int            pid;
@@ -1581,9 +1808,9 @@ static int ps_read (void)
  	char errbuf[1024];
  	char cmdline[ARG_MAX];
  	char *cmdline_ptr;
-  	struct kinfo_proc *procs;          /* array of processes */
-  	char **argv;
-  	int count;                         /* returns number of processes */
+	//struct kinfo_proc *procs;          /* array of processes */
+	char **argv;
+	//int count;                         /* returns number of processes */
  	int i;

  	procstat_t *ps_ptr;
@@ -1601,8 +1828,8 @@ static int ps_read (void)
  	}

  	/* Get the list of processes. */
-	procs = kvm_getprocs(kd, KERN_PROC_ALL, 0, &count);
-	if (procs == NULL)
+	procs_g = kvm_getprocs(kd, KERN_PROC_ALL, 0, &procs_count_g);
+	if (procs_g == NULL)
  	{
  		ERROR ("processes plugin: Cannot get kvm processes list: %s",
  				kvm_geterr(kd));
@@ -1611,13 +1838,13 @@ static int ps_read (void)
  	}

  	/* Iterate through the processes in kinfo_proc */
-	for (i = 0; i < count; i++)
+	for (i = 0; i < procs_count_g; i++)
  	{
  		/* retrieve the arguments */
  		cmdline[0] = 0;
  		cmdline_ptr = NULL;

-		argv = kvm_getargv (kd, (const struct kinfo_proc *) &(procs[i]), 0);
+		argv = kvm_getargv (kd, (const struct kinfo_proc *) &(procs_g[i]), 0);
  		if (argv != NULL)
  		{
  			int status;
@@ -1641,30 +1868,30 @@ static int ps_read (void)
  			}
  		}

-		pse.id       = procs[i].ki_pid;
+		pse.id       = procs_g[i].ki_pid;
  		pse.age      = 0;

  		pse.num_proc = 1;
-		pse.num_lwp  = procs[i].ki_numthreads;
+		pse.num_lwp  = procs_g[i].ki_numthreads;

-		pse.vmem_size = procs[i].ki_size;
-		pse.vmem_rss = procs[i].ki_rssize * getpagesize();
-		pse.vmem_data = procs[i].ki_dsize * getpagesize();
-		pse.vmem_code = procs[i].ki_tsize * getpagesize();
-		pse.stack_size = procs[i].ki_ssize * getpagesize();
+		pse.vmem_size = procs_g[i].ki_size;
+		pse.vmem_rss = procs_g[i].ki_rssize * getpagesize();
+		pse.vmem_data = procs_g[i].ki_dsize * getpagesize();
+		pse.vmem_code = procs_g[i].ki_tsize * getpagesize();
+		pse.stack_size = procs_g[i].ki_ssize * getpagesize();
  		pse.vmem_minflt = 0;
-		pse.vmem_minflt_counter = procs[i].ki_rusage.ru_minflt;
+		pse.vmem_minflt_counter = procs_g[i].ki_rusage.ru_minflt;
  		pse.vmem_majflt = 0;
-		pse.vmem_majflt_counter = procs[i].ki_rusage.ru_majflt;
+		pse.vmem_majflt_counter = procs_g[i].ki_rusage.ru_majflt;

  		pse.cpu_user = 0;
-		pse.cpu_user_counter = procs[i].ki_rusage.ru_utime.tv_sec
+		pse.cpu_user_counter = procs_g[i].ki_rusage.ru_utime.tv_sec
  			* 1000
-			+ procs[i].ki_rusage.ru_utime.tv_usec;
+			+ procs_g[i].ki_rusage.ru_utime.tv_usec;
  		pse.cpu_system = 0;
-		pse.cpu_system_counter = procs[i].ki_rusage.ru_stime.tv_sec
+		pse.cpu_system_counter = procs_g[i].ki_rusage.ru_stime.tv_sec
  			* 1000
-			+ procs[i].ki_rusage.ru_stime.tv_usec;
+			+ procs_g[i].ki_rusage.ru_stime.tv_usec;

  		/* no io data */
  		pse.io_rchar = -1;
@@ -1672,7 +1899,7 @@ static int ps_read (void)
  		pse.io_syscr = -1;
  		pse.io_syscw = -1;

-		switch (procs[i].ki_stat)
+		switch (procs_g[i].ki_stat)
  		{
  			case SSTOP: 	stopped++;	break;
  			case SSLEEP:	sleeping++;	break;
@@ -1683,7 +1910,7 @@ static int ps_read (void)
  			case SZOMB:	zombies++;	break;
  		}

-		ps_list_add (procs[i].ki_comm, cmdline_ptr, &pse);
+		ps_list_add (procs_g[i].ki_comm, cmdline_ptr, &pse);
  	}

  	kvm_close(kd);
@@ -1710,19 +1937,19 @@ static int ps_read (void)
  	int blocked  = 0;

  	pid_t pindex = 0;
-	int nprocs;
+	//int nprocs;

  	procstat_t *ps;
  	procstat_entry_t pse;

  	ps_list_reset ();
-	while ((nprocs = getprocs64 (procentry, sizeof(struct procentry64),
+	while ((procentry_count_g = getprocs64 (procentry, sizeof(struct 
procentry64),
  					/* fdsinfo = */ NULL, sizeof(struct fdsinfo64),
  					&pindex, MAXPROCENTRY)) > 0)
  	{
  		int i;

-		for (i = 0; i < nprocs; i++)
+		for (i = 0; i < procentry_count_g; i++)
  		{
  			tid64_t thindex;
  			int nthreads;
@@ -1740,7 +1967,7 @@ static int ps_read (void)
  				if (procentry[i].pi_pid == 0)
  					cmdline = "swapper";
  				cargs = cmdline;
- 			}
+			}
  			else
  			{
  				if (getargs(&procentry[i], sizeof(struct procentry64), arglist, 
MAXARGLN) >= 0)
diff --git a/src/rrdtool.c b/src/rrdtool.c
index 56a82d0..06ca934 100644
--- a/src/rrdtool.c
+++ b/src/rrdtool.c
@@ -892,7 +892,8 @@ static int rrd_write (const data_set_t *ds, const 
value_list_t *vl,
  		return (0);

  	if (0 != strcmp (ds->type, vl->type)) {
-		ERROR ("rrdtool plugin: DS type does not match value list type");
+		ERROR ("rrdtool plugin: DS type does not match value list type: "
+				"'%s' != '%s'", ds->type, vl->type);
  		return -1;
  	}

-- 
1.7.4.4



More information about the collectd mailing list