3 * Copyright (C) 2007 Peter Holik
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 * Peter Holik <peter at holik.at>
26 #include "configfile.h"
28 #define MODULE_NAME "irq"
31 # define IRQ_HAVE_READ 1
33 # define IRQ_HAVE_READ 0
39 * (Module-)Global variables
41 static char *irq_file = "irq-%s.rrd";
43 static char *config_keys[] =
49 static int config_keys_num = 2;
51 static char *ds_def[] =
53 "DS:irq:COUNTER:"COLLECTD_HEARTBEAT":0:U",
56 static int ds_num = 1;
58 static unsigned int *irq_list;
59 static unsigned int irq_list_num;
65 * 0 => default is to collect selected irqs
66 * 1 => ignore selcted irqs
68 static int irq_list_action;
70 static int irq_config (char *key, char *value)
76 if (strcasecmp (key, "Irq") == 0)
78 temp = (unsigned int *) realloc (irq_list, (irq_list_num + 1) * sizeof (unsigned int *));
81 syslog (LOG_EMERG, "Cannot allocate more memory.");
86 irq = strtol(value, &endptr, base);
88 if (endptr == value ||
89 (errno == ERANGE && (irq == LONG_MAX || irq == LONG_MIN)) ||
90 (errno != 0 && irq == 0))
92 syslog (LOG_EMERG, "Irq value is not a number.");
95 irq_list[irq_list_num] = irq;
98 else if (strcasecmp (key, "IgnoreSelected") == 0)
100 if ((strcasecmp (value, "True") == 0)
101 || (strcasecmp (value, "Yes") == 0)
102 || (strcasecmp (value, "On") == 0))
115 * Check if this interface/instance should be ignored. This is called from
116 * both, `submit' and `write' to give client and server the ability to
117 * ignore certain stuff..
119 static int check_ignore_irq (const unsigned int irq)
123 if (irq_list_num < 1)
126 for (i = 0; i < irq_list_num; i++)
127 if (irq == irq_list[i])
128 return (irq_list_action);
130 return (1 - irq_list_action);
133 static void irq_write (char *host, char *inst, char *value)
138 if (check_ignore_irq (atoi(inst)))
141 status = snprintf (file, BUFSIZE, irq_file, inst);
144 else if (status >= BUFSIZE)
147 rrd_update_file (host, file, value, ds_def, ds_num);
151 static void irq_submit (unsigned int irq, unsigned int value, char *devices)
157 if (check_ignore_irq (irq))
160 status = snprintf (buf, BUFSIZE, "%u:%u",
161 (unsigned int) curtime, value);
163 if ((status >= BUFSIZE) || (status < 1))
166 status = snprintf (desc, BUFSIZE, "%d-%s", irq, devices);
168 if ((status >= BUFSIZE) || (status < 1))
171 plugin_submit (MODULE_NAME, desc, buf);
174 static void irq_read (void)
182 char buffer[BUFSIZE];
184 unsigned int irq_value;
188 if ((fh = fopen ("/proc/interrupts", "r")) == NULL)
190 syslog (LOG_WARNING, "irq: fopen: %s", strerror (errno));
193 while (fgets (buffer, BUFSIZE, fh) != NULL)
195 errno = 0; /* To distinguish success/failure after call */
196 irq = strtol(buffer, &endptr, base);
198 if (endptr == buffer ||
199 (errno == ERANGE && (irq == LONG_MAX || irq == LONG_MIN)) ||
200 (errno != 0 && irq == 0)) continue;
202 if (*endptr != ':') continue;
207 /* sum irq's for all CPUs */
211 value = strtol(ptr, &endptr, base);
215 (value == LONG_MAX || value == LONG_MIN)) ||
216 (errno != 0 && value == 0)) break;
221 while (*ptr == ' ') ptr++;
222 while (*ptr && *ptr != ' ') ptr++;
223 while (*ptr == ' ') ptr++;
230 if (!isalnum(*endptr)) *endptr='_';
232 ptr[strlen(ptr)-1] = '\0';
234 irq_submit (irq, irq_value, ptr);
237 #endif /* KERNEL_LINUX */
240 #define irq_read NULL
241 #endif /* IRQ_HAVE_READ */
243 void module_register (void)
245 plugin_register (MODULE_NAME, NULL, irq_read, irq_write);
246 cf_register (MODULE_NAME, irq_config, config_keys, config_keys_num);