summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: ee8d255)
raw | patch | inline | side by side (parent: ee8d255)
author | Bostjan Skufca <bostjan@a2o.si> | |
Fri, 2 Sep 2011 00:35:38 +0000 (20:35 -0400) | ||
committer | Florian Forster <octo@collectd.org> | |
Fri, 2 Sep 2011 01:20:22 +0000 (21:20 -0400) |
Hi all!
I've created a patch that enables collectd to collect all irqs present in
/proc/interrupts, with numeric and string names (NMI, LOC, RES, etc).
Two notices:
a) Unfortunately I was unable to build collectd from git repo (build.sh
failures), therefore I created this patch for latest stable release: 4.10.1
b) I am fairly unexperienced in C programming, so please inform me gently of my
mistakes:) But I am already using a patched version and it works fine.
Any feedback on code quality or recommendations are welcome.
Change-Id: Ia17bd953921051dfe53e838b76672adbef9e73c3
Signed-off-by: Florian Forster <octo@collectd.org>
I've created a patch that enables collectd to collect all irqs present in
/proc/interrupts, with numeric and string names (NMI, LOC, RES, etc).
Two notices:
a) Unfortunately I was unable to build collectd from git repo (build.sh
failures), therefore I created this patch for latest stable release: 4.10.1
b) I am fairly unexperienced in C programming, so please inform me gently of my
mistakes:) But I am already using a patched version and it works fine.
Any feedback on code quality or recommendations are welcome.
Change-Id: Ia17bd953921051dfe53e838b76672adbef9e73c3
Signed-off-by: Florian Forster <octo@collectd.org>
src/irq.c | patch | blob | history |
diff --git a/src/irq.c b/src/irq.c
index 401cc6f9cb3f13e84e1a5e2fd961238565c6632c..70d6b5abe41dfd353ff1574a3035194f9e45654d 100644 (file)
--- a/src/irq.c
+++ b/src/irq.c
# error "No applicable input method."
#endif
-#define BUFSIZE 128
-
/*
* (Module-)Global variables
*/
};
static int config_keys_num = STATIC_ARRAY_SIZE (config_keys);
-static unsigned int *irq_list;
-static unsigned int irq_list_num;
+static char **irq_list;
+static unsigned int irq_list_num = 0;
/*
* irq_list_action:
{
if (strcasecmp (key, "Irq") == 0)
{
- unsigned int *temp;
- unsigned int irq;
- char *endptr;
+ char **temp;
- temp = (unsigned int *) realloc (irq_list, (irq_list_num + 1) * sizeof (unsigned int *));
+ temp = realloc (irq_list, (irq_list_num + 1) * sizeof (*irq_list));
if (temp == NULL)
{
fprintf (stderr, "irq plugin: Cannot allocate more memory.\n");
}
irq_list = temp;
- /* Clear errno, because we need it to see if an error occured. */
- errno = 0;
-
- irq = strtol(value, &endptr, 10);
- if ((endptr == value) || (errno != 0))
+ irq_list[irq_list_num] = strdup (value);
+ if (irq_list[irq_list_num] == NULL)
{
- fprintf (stderr, "irq plugin: Irq value is not a "
- "number: `%s'\n", value);
- ERROR ("irq plugin: Irq value is not a "
- "number: `%s'", value);
+ ERROR ("irq plugin: strdup(3) failed.");
return (1);
}
- irq_list[irq_list_num] = irq;
+
irq_list_num++;
}
else if (strcasecmp (key, "IgnoreSelected") == 0)
* both, `submit' and `write' to give client and server the ability to
* ignore certain stuff..
*/
-static int check_ignore_irq (const unsigned int irq)
+static int check_ignore_irq (const char *irq)
{
- int i;
+ unsigned int i;
if (irq_list_num < 1)
return (0);
- for (i = 0; (unsigned int)i < irq_list_num; i++)
- if (irq == irq_list[i])
+ for (i = 0; i < irq_list_num; i++)
+ if (strcmp (irq, irq_list[i]) == 0)
return (irq_list_action);
return (1 - irq_list_action);
}
-static void irq_submit (unsigned int irq, counter_t value)
+static void irq_submit (const char *irq_name, counter_t value)
{
value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
- int status;
- if (check_ignore_irq (irq))
+ if (check_ignore_irq (irq_name))
return;
values[0].counter = value;
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, "irq", sizeof (vl.plugin));
sstrncpy (vl.type, "irq", sizeof (vl.type));
-
- status = ssnprintf (vl.type_instance, sizeof (vl.type_instance),
- "%u", irq);
- if ((status < 1) || ((unsigned int)status >= sizeof (vl.type_instance)))
- return;
+ sstrncpy (vl.type_instance, irq_name, sizeof (vl.type_instance));
plugin_dispatch_values (&vl);
} /* void irq_submit */
static int irq_read (void)
{
-#undef BUFSIZE
-#define BUFSIZE 256
-
FILE *fh;
- char buffer[BUFSIZE];
- unsigned int irq;
+ char buffer[1024];
unsigned long long irq_value;
unsigned long long value;
char *endptr;
sstrerror (errno, errbuf, sizeof (errbuf)));
return (-1);
}
- while (fgets (buffer, BUFSIZE, fh) != NULL)
+ while (fgets (buffer, sizeof (buffer), fh) != NULL)
{
+ char *irq_name;
+ size_t irq_name_len;
+
fields_num = strsplit (buffer, fields, 64);
if (fields_num < 2)
continue;
- errno = 0; /* To distinguish success/failure after call */
- irq = strtol (fields[0], &endptr, 10);
+ irq_name = fields[0];
+ irq_name_len = strlen (irq_name);
+ if (irq_name_len < 2)
+ continue;
- if ((endptr == fields[0]) || (errno != 0) || (*endptr != ':'))
+ /* Check if irq name ends with colon.
+ * Otherwise it's a header. */
+ if (irq_name[irq_name_len - 1] != ':')
continue;
+ irq_name[irq_name_len - 1] = 0;
+ irq_name_len--;
+
irq_value = 0;
for (i = 1; i < fields_num; i++)
{
errno = 0;
+ endptr = NULL;
value = strtoull (fields[i], &endptr, 10);
- if ((*endptr != '\0') || (errno != 0))
+ /* Ignore all fields following a non-numeric field. */
+ if ((errno != 0) || (endptr == NULL) || (*endptr != 0))
break;
irq_value += value;
} /* for (i) */
+ /* No valid fields -> do not submit anything. */
+ if (i <= 1)
+ continue;
+
/* Force 32bit wrap-around */
- irq_submit (irq, irq_value % 4294967296ULL);
+ irq_submit (irq_name, irq_value % 4294967296ULL);
}
fclose (fh);
config_keys, config_keys_num);
plugin_register_read ("irq", irq_read);
} /* void module_register */
-
-#undef BUFSIZE