From: Florian Forster Date: Thu, 11 Oct 2012 08:22:53 +0000 (+0200) Subject: Merge branch 'collectd-5.0' into collectd-5.1 X-Git-Tag: collectd-5.1.1~5 X-Git-Url: https://git.octo.it/?a=commitdiff_plain;h=5fb8bff2b2d2d5c61621c6686b343d7e0eea48f0;p=collectd.git Merge branch 'collectd-5.0' into collectd-5.1 Conflicts: src/snmp.c --- 5fb8bff2b2d2d5c61621c6686b343d7e0eea48f0 diff --cc src/snmp.c index b68baf37,b8bbee44..f4966694 --- a/src/snmp.c +++ b/src/snmp.c @@@ -753,14 -800,11 +801,14 @@@ static value_t csnmp_value_list_to_valu #ifdef ASN_NULL if (vl->type == ASN_NULL) INFO ("snmp plugin: OID \"%s\" is undefined (type ASN_NULL)", - oid_buffer); + oid_buffer); else #endif - WARNING ("snmp plugin: I don't know the ASN type \"%i\" (OID: %s)", - (int) vl->type, oid_buffer); + WARNING ("snmp plugin: I don't know the ASN type #%i " + "(OID: \"%s\", data block \"%s\", host block \"%s\")", + (int) vl->type, oid_buffer, + (data_name != NULL) ? data_name : "UNKNOWN", + (host_name != NULL) ? host_name : "UNKNOWN"); defined = 0; } @@@ -1001,9 -1049,16 +1053,16 @@@ static int csnmp_instance_list_add (csn ERROR ("snmp plugin: malloc failed."); return (-1); } - il->subid = vb->name[vb->name_length - 1]; + memset (il, 0, sizeof (*il)); il->next = NULL; - status = csnmp_oid_suffix (&il->suffix, &vb_name, root); ++ status = csnmp_oid_suffix (&il->suffix, &vb_name, &dd->instance.oid); + if (status != 0) + { + sfree (il); + return (status); + } + /* Get instance name */ if ((vb->type == ASN_OCTET_STR) || (vb->type == ASN_BIT_STR)) { @@@ -1022,10 -1077,9 +1081,10 @@@ } else { - value_t val = csnmp_value_list_to_value (vb, DS_TYPE_COUNTER, 1.0, 0.0); + value_t val = csnmp_value_list_to_value (vb, DS_TYPE_COUNTER, + /* scale = */ 1.0, /* shift = */ 0.0, hd->name, dd->name); ssnprintf (il->instance, sizeof (il->instance), - "%llu", val.counter); + "%llu", val.counter); } /* TODO: Debugging output */ @@@ -1310,71 -1391,84 +1396,84 @@@ static int csnmp_read_table (host_defin { /* Allocate a new `csnmp_list_instances_t', insert the instance name and * add it to the list */ - if (csnmp_instance_list_add (&instance_list, &instance_list_ptr, + if (csnmp_instance_list_add (&instance_list_head, &instance_list_tail, - res, &data->instance.oid) != 0) + res, host, data) != 0) { - ERROR ("snmp plugin: csnmp_instance_list_add failed."); - status = -1; - break; + ERROR ("snmp plugin: csnmp_instance_list_add failed."); + status = -1; + break; } - /* Set vb on the last variable */ + /* The instance OID is added to the list of OIDs to GET from the + * snmp agent last, so set vb on the last variable returned and copy + * that OID. */ for (vb = res->variables; - (vb != NULL) && (vb->next_variable != NULL); - vb = vb->next_variable) - /* do nothing */; + (vb != NULL) && (vb->next_variable != NULL); + vb = vb->next_variable) + /* do nothing */; assert (vb != NULL); - /* Copy OID to oid_list[data->values_len] */ + /* Copy the OID of the instance value to oid_list[data->values_len]. + * "oid_list" is used for the next GETNEXT request. */ memcpy (oid_list[data->values_len].oid, vb->name, - sizeof (oid) * vb->name_length); + sizeof (oid) * vb->name_length); oid_list[data->values_len].oid_len = vb->name_length; } + /* Iterate over all the (non-instance) values returned by the agent. The + * (i < value_len) check will make sure we're not handling the instance OID + * twice. */ for (vb = res->variables, i = 0; - (vb != NULL) && (i < data->values_len); - vb = vb->next_variable, i++) + (vb != NULL) && (i < data->values_len); + vb = vb->next_variable, i++) { csnmp_table_values_t *vt; + oid_t vb_name; + oid_t suffix; - /* Check if we left the subtree */ - if (snmp_oid_ncompare (data->values[i].oid, - data->values[i].oid_len, - vb->name, vb->name_length, - data->values[i].oid_len) != 0) + csnmp_oid_init (&vb_name, vb->name, vb->name_length); + + /* Calculate the current suffix. This is later used to check that the + * suffix is increasing. This also checks if we left the subtree */ + status = csnmp_oid_suffix (&suffix, &vb_name, data->values + i); + if (status != 0) { - DEBUG ("snmp plugin: host = %s; data = %s; Value %i left its subtree.", - host->name, data->name, i); - continue; + DEBUG ("snmp plugin: host = %s; data = %s; Value %i failed. " + "It probably left its subtree.", + host->name, data->name, i); + continue; } - if ((value_table_ptr[i] != NULL) - && (vb->name[vb->name_length - 1] <= value_table_ptr[i]->subid)) + /* Make sure the OIDs returned by the agent are increasing. Otherwise our + * table matching algorithm will get confused. */ + if ((value_list_tail[i] != NULL) + && (csnmp_oid_compare (&suffix, &value_list_tail[i]->suffix) <= 0)) { - DEBUG ("snmp plugin: host = %s; data = %s; i = %i; " - "SUBID is not increasing.", - host->name, data->name, i); - continue; + DEBUG ("snmp plugin: host = %s; data = %s; i = %i; " + "Suffix is not increasing.", + host->name, data->name, i); + continue; } - vt = (csnmp_table_values_t *) malloc (sizeof (csnmp_table_values_t)); + vt = malloc (sizeof (*vt)); if (vt == NULL) { - ERROR ("snmp plugin: malloc failed."); - status = -1; - break; + ERROR ("snmp plugin: malloc failed."); + status = -1; + break; } + memset (vt, 0, sizeof (*vt)); - vt->subid = vb->name[vb->name_length - 1]; vt->value = csnmp_value_list_to_value (vb, ds->ds[i].type, - data->scale, data->shift); + data->scale, data->shift, host->name, data->name); + memcpy (&vt->suffix, &suffix, sizeof (vt->suffix)); vt->next = NULL; - if (value_table_ptr[i] == NULL) - value_table[i] = vt; + if (value_list_tail[i] == NULL) + value_list_head[i] = vt; else - value_table_ptr[i]->next = vt; - value_table_ptr[i] = vt; + value_list_tail[i]->next = vt; + value_list_tail[i] = vt; /* Copy OID to oid_list[i + 1] */ memcpy (oid_list[i].oid, vb->name, sizeof (oid) * vb->name_length); @@@ -1516,9 -1610,9 +1615,9 @@@ static int csnmp_read_value (host_defin for (i = 0; i < data->values_len; i++) if (snmp_oid_compare (data->values[i].oid, data->values[i].oid_len, - vb->name, vb->name_length) == 0) + vb->name, vb->name_length) == 0) vl.values[i] = csnmp_value_list_to_value (vb, ds->ds[i].type, - data->scale, data->shift); + data->scale, data->shift, host->name, data->name); } /* for (res->variables) */ if (res != NULL)