X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fsnmp.c;h=352075f26ded8ef75802d020c069de9d53836c0a;hb=6d86a97190a193863aadc252f20f6b9dba61c263;hp=877aafe92b2bf959f8604916776020460b847ea2;hpb=7471e073bff7c9f2542bc1c8ce639b85c5498ba7;p=collectd.git diff --git a/src/snmp.c b/src/snmp.c index 877aafe9..352075f2 100644 --- a/src/snmp.c +++ b/src/snmp.c @@ -22,6 +22,7 @@ #include "collectd.h" #include "common.h" #include "plugin.h" +#include "utils_complain.h" #include @@ -67,6 +68,7 @@ struct host_definition_s char *community; int version; void *sess_handle; + c_complain_t complaint; uint32_t interval; time_t next_update; data_definition_t **data_list; @@ -116,6 +118,7 @@ static pthread_cond_t host_cond = PTHREAD_COND_INITIALIZER; /* * Private functions */ +/* Many functions to handle the configuration. {{{ */ /* First there are many functions which do configuration stuff. It's a big * bloated and messy, I'm afraid. */ @@ -527,9 +530,9 @@ static int csnmp_config_add_host_interval (host_definition_t *hd, oconfig_item_t return (-1); } - hd->interval = (int) ci->values[0].value.number; - if (hd->interval < 0) - hd->interval = 0; + hd->interval = ci->values[0].value.number >= 0 + ? (uint32_t) ci->values[0].value.number + : 0; return (0); } /* int csnmp_config_add_host_interval */ @@ -551,6 +554,7 @@ static int csnmp_config_add_host (oconfig_item_t *ci) return (-1); memset (hd, '\0', sizeof (host_definition_t)); hd->version = 2; + C_COMPLAIN_INIT (&hd->complaint); hd->name = strdup (ci->values[0].value.string); if (hd->name == NULL) @@ -653,7 +657,7 @@ static int csnmp_config (oconfig_item_t *ci) return (0); } /* int csnmp_config */ -/* End of the config stuff. Now the interesting part begins */ +/* }}} End of the config stuff. Now the interesting part begins */ static void csnmp_host_close_session (host_definition_t *host) { @@ -692,6 +696,7 @@ static void csnmp_host_open_session (host_definition_t *host) } } /* void csnmp_host_open_session */ +/* TODO: Check if negative values wrap around. Problem: negative temperatures. */ static value_t csnmp_value_list_to_value (struct variable_list *vl, int type, double scale, double shift) { @@ -729,22 +734,41 @@ static value_t csnmp_value_list_to_value (struct variable_list *vl, int type, if (vl->type == ASN_OCTET_STR) { - char *string; char *endptr; - string = (char *) vl->val.string; endptr = NULL; - - if (string != NULL) + if (vl->val.string != NULL) { + char string[64]; + size_t string_length; + + string_length = sizeof (string) - 1; + if (vl->val_len < string_length) + string_length = vl->val_len; + + /* The strings we get from the Net-SNMP library may not be null + * terminated. That is why we're using `membpy' here and not `strcpy'. + * `string_length' is set to `vl->val_len' which holds the length of the + * string. -octo */ + memcpy (string, vl->val.string, string_length); + string[string_length] = 0; + if (type == DS_TYPE_COUNTER) + { ret.counter = (counter_t) strtoll (string, &endptr, /* base = */ 0); + DEBUG ("snmp plugin: csnmp_value_list_to_value: String to counter: %s -> %llu", + string, (unsigned long long) ret.counter); + } else if (type == DS_TYPE_GAUGE) + { ret.gauge = (gauge_t) strtod (string, &endptr); + DEBUG ("snmp plugin: csnmp_value_list_to_value: String to gauge: %s -> %g", + string, (double) ret.gauge); + } } /* Check if an error occurred */ - if ((string == NULL) || (endptr == string)) + if ((vl->val.string == NULL) || (endptr == (char *) vl->val.string)) { if (type == DS_TYPE_COUNTER) ret.counter = 0; @@ -940,7 +964,6 @@ static int csnmp_dispatch_table (host_definition_t *host, data_definition_t *dat sstrncpy (vl.plugin, "snmp", sizeof (vl.plugin)); vl.interval = host->interval; - vl.time = time (NULL); subid = 0; have_more = 1; @@ -1116,7 +1139,7 @@ static int csnmp_read_table (host_definition_t *host, data_definition_t *data) break; } - for (i = 0; i < oid_list_len; i++) + for (i = 0; (uint32_t) i < oid_list_len; i++) snmp_add_null_var (req, oid_list[i].oid, oid_list[i].oid_len); res = NULL; @@ -1127,7 +1150,9 @@ static int csnmp_read_table (host_definition_t *host, data_definition_t *data) char *errstr = NULL; snmp_sess_error (host->sess_handle, NULL, NULL, &errstr); - ERROR ("snmp plugin: host %s: snmp_sess_synch_response failed: %s", + + c_complain (LOG_ERR, &host->complaint, + "snmp plugin: host %s: snmp_sess_synch_response failed: %s", host->name, (errstr == NULL) ? "Unknown problem" : errstr); if (res != NULL) @@ -1142,6 +1167,9 @@ static int csnmp_read_table (host_definition_t *host, data_definition_t *data) } status = 0; assert (res != NULL); + c_release (LOG_INFO, &host->complaint, + "snmp plugin: host %s: snmp_sess_synch_response successful.", + host->name); vb = res->variables; if (vb == NULL) @@ -1357,7 +1385,6 @@ static int csnmp_read_value (host_definition_t *host, data_definition_t *data) return (-1); } - vl.time = time (NULL); for (vb = res->variables; vb != NULL; vb = vb->next_variable) { @@ -1415,7 +1442,7 @@ static int csnmp_read_host (host_definition_t *host) time_end = time (NULL); DEBUG ("snmp plugin: csnmp_read_host (%s) finished at %u;", host->name, (unsigned int) time_end); - if ((time_end - time_start) > host->interval) + if ((uint32_t) (time_end - time_start) > host->interval) { WARNING ("snmp plugin: Host `%s' should be queried every %i seconds, " "but reading all values takes %u seconds.", @@ -1425,7 +1452,7 @@ static int csnmp_read_host (host_definition_t *host) return (0); } /* int csnmp_read_host */ -static void *csnmp_read_thread (void *data) +static void *csnmp_read_thread (void __attribute__((unused)) *data) { host_definition_t *host; @@ -1478,7 +1505,7 @@ static int csnmp_init (void) { host->interval = interval_g; } - else if (host->interval < interval_g) + else if (host->interval < (uint32_t) interval_g) { host->interval = interval_g; WARNING ("snmp plugin: Data for host `%s' will be collected every %i seconds.", @@ -1607,5 +1634,5 @@ void module_register (void) } /* void module_register */ /* - * vim: shiftwidth=2 softtabstop=2 tabstop=8 + * vim: shiftwidth=2 softtabstop=2 tabstop=8 fdm=marker */