summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 9e30a0c)
raw | patch | inline | side by side (parent: 9e30a0c)
author | Korynkevych, RomanX <romanx.korynkevych@intel.com> | |
Thu, 16 Mar 2017 17:21:31 +0000 (17:21 +0000) | ||
committer | Korynkevych, RomanX <romanx.korynkevych@intel.com> | |
Fri, 24 Mar 2017 14:24:07 +0000 (14:24 +0000) |
Based on the SNMP rules when table column is represented as a key
of string type, key should be used while generating OID for each row.
When index is not specified, then it's assumed that instance value is
the key for the specified table.
Change-Id: I9f3fbd9aa018bc9037bd3202e2ed107a302fe1b3
Signed-off-by: Korynkevych, RomanX <romanx.korynkevych@intel.com>
of string type, key should be used while generating OID for each row.
When index is not specified, then it's assumed that instance value is
the key for the specified table.
Change-Id: I9f3fbd9aa018bc9037bd3202e2ed107a302fe1b3
Signed-off-by: Korynkevych, RomanX <romanx.korynkevych@intel.com>
src/snmp_agent.c | patch | blob | history |
diff --git a/src/snmp_agent.c b/src/snmp_agent.c
index 5f8ed290a199c19530e1b4df8a763f6cb0d5864f..af223122270d815d696eb7ea2be172bdf93970dc 100644 (file)
--- a/src/snmp_agent.c
+++ b/src/snmp_agent.c
return (0);
}
+static void snmp_agent_generate_oid2string(oid_t *oid, int offset, char *key) {
+ int key_len = oid->oid[offset];
+ int i;
+
+ for (i = 0; i < key_len && offset < oid->oid_len; i++)
+ key[i] = oid->oid[++offset];
+
+ key[i] = '\0';
+}
+
+static int snmp_agent_generate_string2oid(oid_t *oid, const char *key) {
+ int key_len = strlen(key);
+
+ oid->oid[oid->oid_len++] = key_len;
+ for (int i = 0; i < key_len; i++) {
+ oid->oid[oid->oid_len++] = key[i];
+ if (oid->oid_len >= MAX_OID_LEN) {
+ ERROR(PLUGIN_NAME ": Conversion key string %s to OID failed", key);
+ return (-EINVAL);
+ }
+ }
+
+ return 0;
+}
+
+static int snmp_agent_register_oid_string(oid_t *oid, const char *key,
+ Netsnmp_Node_Handler *handler) {
+ oid_t new_oid;
+
+ memcpy(&new_oid, oid, sizeof(*oid));
+ int ret = snmp_agent_generate_string2oid(&new_oid, key);
+ if (ret != 0)
+ return ret;
+
+ return snmp_agent_register_oid(&new_oid, handler);
+}
+
+static int snmp_agent_unregister_oid_string(oid_t *oid, const char *key) {
+ oid_t new_oid;
+
+ memcpy(&new_oid, oid, sizeof(*oid));
+ int ret = snmp_agent_generate_string2oid(&new_oid, key);
+ if (ret != 0)
+ return ret;
+
+ return unregister_mib(new_oid.oid, new_oid.oid_len);
+}
+
static int snmp_agent_table_row_remove(table_definition_t *td,
const char *instance) {
- int *index;
- char *ins;
+ int *index = NULL;
+ char *ins = NULL;
- if ((c_avl_get(td->instance_index, instance, (void **)&index) != 0) ||
- (c_avl_get(td->index_instance, index, (void **)&ins) != 0))
- return (0);
+ if (td->index_oid.oid_len) {
+ if ((c_avl_get(td->instance_index, instance, (void **)&index) != 0) ||
+ (c_avl_get(td->index_instance, index, (void **)&ins) != 0))
+ return (0);
+ } else {
+ if (c_avl_get(td->instance_index, instance, (void **)&ins) != 0)
+ return (0);
+ }
pthread_mutex_lock(&g_agent->agentx_lock);
+ if (td->index_oid.oid_len)
+ snmp_agent_unregister_oid_index(&td->index_oid, *index);
+
for (llentry_t *de = llist_head(td->columns); de != NULL; de = de->next) {
data_definition_t *dd = de->value;
for (int i = 0; i < dd->oids_len; i++)
- snmp_agent_unregister_oid_index(&dd->oids[i], *index);
+ if (td->index_oid.oid_len)
+ snmp_agent_unregister_oid_index(&dd->oids[i], *index);
+ else
+ snmp_agent_unregister_oid_string(&dd->oids[i], ins);
}
- snmp_agent_unregister_oid_index(&td->index_oid, *index);
-
pthread_mutex_unlock(&g_agent->agentx_lock);
- DEBUG(PLUGIN_NAME ": Removed row for '%s' table [%d, %s]", td->name, *index,
- ins);
+ DEBUG(PLUGIN_NAME ": Removed row for '%s' table [%d, %s]", td->name,
+ (index != NULL) ? *index : -1, ins);
notification_t n = {
.severity = NOTIF_WARNING,
sstrncpy(n.plugin_instance, ins, sizeof(n.plugin_instance));
ssnprintf(n.message, sizeof(n.message),
"Removed data row from table %s instance %s index %d", td->name,
- ins, *index);
+ ins, (index != NULL) ? *index : -1);
plugin_dispatch_notification(&n);
- c_avl_remove(td->index_instance, index, NULL, (void **)&ins);
- c_avl_remove(td->instance_index, instance, NULL, (void **)&index);
- sfree(index);
- sfree(ins);
+ if (td->index_oid.oid_len) {
+ c_avl_remove(td->index_instance, index, NULL, (void **)&ins);
+ c_avl_remove(td->instance_index, instance, NULL, (void **)&index);
+ sfree(index);
+ sfree(ins);
+ } else {
+ c_avl_remove(td->instance_index, instance, NULL, (void **)&ins);
+ sfree(ins);
+ }
return (0);
}
if ((*dd)->table == NULL) {
for (int i = 0; i < (*dd)->oids_len; i++)
unregister_mib((*dd)->oids[i].oid, (*dd)->oids[i].oid_len);
+ }
+ if (!(*dd)->table->index_oid.oid_len) {
+ char *instance;
+
+ c_avl_iterator_t *iter = c_avl_get_iterator((*dd)->table->instance_index);
+ while (c_avl_iterator_next(iter, (void *)&instance, (void *)&instance) == 0) {
+ for (int i = 0; i < (*dd)->oids_len; i++)
+ snmp_agent_unregister_oid_string(&(*dd)->oids[i], instance);
+ }
+ c_avl_iterator_destroy(iter);
} else {
/* unregister all table OIDs */
int *index;
if ((*td)->instance_index != NULL) {
while (c_avl_pick((*td)->instance_index, &key, &value) == 0) {
- sfree(key);
+ if (key != value)
+ sfree(key);
sfree(value);
}
c_avl_destroy((*td)->instance_index);
for (llentry_t *te = llist_head(g_agent->tables); te != NULL; te = te->next) {
table_definition_t *td = te->value;
- if (!td->index_oid.oid_len) {
- DEBUG(PLUGIN_NAME ": %s:%d NOT IMPLEMENTED", __FUNCTION__, __LINE__);
- continue;
- }
-
for (llentry_t *de = llist_head(td->columns); de != NULL; de = de->next) {
data_definition_t *dd = de->value;
if (ret != 0)
continue;
- int index = oid.oid[oid.oid_len - 1];
char *instance;
- ret = c_avl_get(td->index_instance, &index, (void **)&instance);
- if (ret != 0) {
- DEBUG(PLUGIN_NAME ": Nonexisting index '%d' requested", index);
- pthread_mutex_unlock(&g_agent->lock);
- return SNMP_NOSUCHINSTANCE;
+ if (!td->index_oid.oid_len) {
+ char key[MAX_OID_LEN];
+
+ memset(key, 0, sizeof(key));
+ snmp_agent_generate_oid2string(&oid, MIN(oid.oid_len,
+ dd->oids[i].oid_len), key);
+
+ ret = c_avl_get(td->instance_index, key, (void **)&instance);
+ if (ret != 0) {
+ DEBUG(PLUGIN_NAME ": Nonexisting index string '%s' requested",
+ key);
+ pthread_mutex_unlock(&g_agent->lock);
+ return SNMP_NOSUCHINSTANCE;
+ }
+ } else {
+ int index = oid.oid[oid.oid_len - 1];
+
+ ret = c_avl_get(td->index_instance, &index, (void **)&instance);
+ if (ret != 0) {
+ DEBUG(PLUGIN_NAME ": Nonexisting index '%d' requested", index);
+ pthread_mutex_unlock(&g_agent->lock);
+ return SNMP_NOSUCHINSTANCE;
+ }
}
if (dd->is_instance) {
}
}
- if (td->index_oid.oid_len == 0) {
- ERROR(PLUGIN_NAME ": Table %s Index OID is not specified", td->name);
- snmp_agent_free_table(&td);
- return (-1);
- }
-
llentry_t *entry = llentry_create(td->name, td);
if (entry == NULL) {
snmp_agent_free_table(&td);
return (0);
int ret;
- int *index;
+ int *index = NULL;
char *ins;
ins = strdup(instance);
if (ins == NULL)
return (-ENOMEM);
- index = calloc(1, sizeof(*index));
- if (index == NULL) {
- sfree(ins);
- return (-ENOMEM);
- }
-
- *index = c_avl_size(td->instance_index) + 1;
-
- ret = c_avl_insert(td->instance_index, ins, index);
- if (ret != 0) {
- sfree(ins);
- sfree(index);
- return ret;
- }
+ /* need to generate index for the table */
+ if (td->index_oid.oid_len) {
+ index = calloc(1, sizeof(*index));
+ if (index == NULL) {
+ sfree(ins);
+ return (-ENOMEM);
+ }
- ret = c_avl_insert(td->index_instance, index, ins);
- if (ret < 0) {
- DEBUG(PLUGIN_NAME ": Failed to update index_instance for '%s' table",
- td->name);
- return ret;
- }
+ *index = c_avl_size(td->instance_index) + 1;
- DEBUG(PLUGIN_NAME ": Updated index for '%s' table [%d, %s]", td->name, *index,
- ins);
+ ret = c_avl_insert(td->instance_index, ins, index);
+ if (ret != 0) {
+ sfree(ins);
+ sfree(index);
+ return ret;
+ }
- /* need to generate index for the table */
- if (td->index_oid.oid_len) {
+ ret = c_avl_insert(td->index_instance, index, ins);
+ if (ret < 0) {
+ DEBUG(PLUGIN_NAME ": Failed to update index_instance for '%s' table",
+ td->name);
+ c_avl_remove(td->instance_index, ins, NULL, (void **)&index);
+ sfree(ins);
+ sfree(index);
+ return ret;
+ }
ret = snmp_agent_register_oid_index(&td->index_oid, *index,
snmp_agent_table_index_oid_handler);
if (ret != 0)
return ret;
+ } else {
+ /* instance as a key is required for any table */
+ ret = c_avl_insert(td->instance_index, ins, ins);
+ if (ret != 0) {
+ sfree(ins);
+ return ret;
+ }
+ }
- /* register new oids for all columns */
- for (llentry_t *de = llist_head(td->columns); de != NULL; de = de->next) {
- data_definition_t *dd = de->value;
+ /* register new oids for all columns */
+ for (llentry_t *de = llist_head(td->columns); de != NULL; de = de->next) {
+ data_definition_t *dd = de->value;
- for (int i = 0; i < dd->oids_len; i++) {
+ for (int i = 0; i < dd->oids_len; i++) {
+ if (td->index_oid.oid_len) {
ret = snmp_agent_register_oid_index(&dd->oids[i], *index,
snmp_agent_table_oid_handler);
- if (ret != 0)
- return ret;
+ } else {
+ ret = snmp_agent_register_oid_string(&dd->oids[i], ins,
+ snmp_agent_table_oid_handler);
}
+
+ if (ret != 0)
+ return ret;
}
}
+ DEBUG(PLUGIN_NAME ": Updated index for '%s' table [%d, %s]", td->name,
+ (index != NULL) ? *index : -1, ins);
+
notification_t n = {
.severity = NOTIF_OKAY,
.time = cdtime(),
sstrncpy(n.plugin_instance, ins, sizeof(n.plugin_instance));
ssnprintf(n.message, sizeof(n.message),
"Data row added to table %s instance %s index %d", td->name, ins,
- *index);
+ (index != NULL) ? *index : -1);
plugin_dispatch_notification(&n);
return (0);