wrap potentially non-threadsafe snmp operations in mutex; support snmpwalk in subagent

This commit is contained in:
Daniel Swarbrick 2011-01-25 19:19:17 +01:00
parent 02d1af647b
commit 636c1ecb4e
2 changed files with 77 additions and 94 deletions

View File

@ -38,6 +38,7 @@
static struct { static struct {
switch_memory_pool_t *pool; switch_memory_pool_t *pool;
switch_mutex_t *mutex;
int shutdown; int shutdown;
} globals; } globals;
@ -55,27 +56,13 @@ static int snmp_callback_log(int major, int minor, void *serverarg, void *client
} }
static switch_state_handler_table_t state_handlers = {
/*.on_init */ NULL,
/*.on_routing */ NULL,
/*.on_execute */ NULL,
/*.on_hangup */ NULL,
/*.on_exchange_media */ NULL,
/*.on_soft_execute */ NULL,
/*.on_consume_media */ NULL,
/*.on_hibernate */ NULL,
/*.on_reset */ NULL,
/*.on_park */ NULL,
/*.on_reporting */ NULL
};
static switch_status_t load_config(switch_memory_pool_t *pool) static switch_status_t load_config(switch_memory_pool_t *pool)
{ {
switch_status_t status = SWITCH_STATUS_SUCCESS; switch_status_t status = SWITCH_STATUS_SUCCESS;
memset(&globals, 0, sizeof(globals)); memset(&globals, 0, sizeof(globals));
globals.pool = pool; globals.pool = pool;
switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, globals.pool);
return status; return status;
} }
@ -87,7 +74,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_snmp_load)
load_config(pool); load_config(pool);
switch_core_add_state_handler(&state_handlers);
*module_interface = switch_loadable_module_create_module_interface(pool, modname); *module_interface = switch_loadable_module_create_module_interface(pool, modname);
/* Register callback function so we get Net-SNMP logging handled by FreeSWITCH */ /* Register callback function so we get Net-SNMP logging handled by FreeSWITCH */
@ -114,9 +100,11 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_snmp_load)
SWITCH_MODULE_RUNTIME_FUNCTION(mod_snmp_runtime) SWITCH_MODULE_RUNTIME_FUNCTION(mod_snmp_runtime)
{ {
while (!globals.shutdown) { if (!globals.shutdown) {
/* Block on select() */ /* Block on select() */
switch_mutex_lock(globals.mutex);
agent_check_and_process(1); agent_check_and_process(1);
switch_mutex_unlock(globals.mutex);
} }
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
@ -126,9 +114,12 @@ SWITCH_MODULE_RUNTIME_FUNCTION(mod_snmp_runtime)
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_snmp_shutdown) SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_snmp_shutdown)
{ {
globals.shutdown = 1; globals.shutdown = 1;
switch_core_remove_state_handler(&state_handlers);
switch_mutex_lock(globals.mutex);
snmp_shutdown("mod_snmp"); snmp_shutdown("mod_snmp");
switch_mutex_unlock(globals.mutex);
switch_mutex_destroy(globals.mutex);
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }

View File

@ -63,8 +63,8 @@ void init_subagent(void)
{ {
DEBUGMSGTL(("init_nstAgentSubagentObject", "Initializing\n")); DEBUGMSGTL(("init_nstAgentSubagentObject", "Initializing\n"));
netsnmp_register_handler(netsnmp_create_handler_registration("identity", handle_identity, identity_oid, OID_LENGTH(identity_oid), HANDLER_CAN_RONLY)); netsnmp_register_scalar_group(netsnmp_create_handler_registration("identity", handle_identity, identity_oid, OID_LENGTH(identity_oid), HANDLER_CAN_RONLY), 1, 2);
netsnmp_register_handler(netsnmp_create_handler_registration("systemStats", handle_systemStats, systemStats_oid, OID_LENGTH(systemStats_oid), HANDLER_CAN_RONLY)); netsnmp_register_scalar_group(netsnmp_create_handler_registration("systemStats", handle_systemStats, systemStats_oid, OID_LENGTH(systemStats_oid), HANDLER_CAN_RONLY), 1, 7);
} }
@ -78,7 +78,7 @@ int handle_identity(netsnmp_mib_handler *handler, netsnmp_handler_registration *
switch(reqinfo->mode) { switch(reqinfo->mode) {
case MODE_GET: case MODE_GET:
for (request = requests; request; request = request->next) { for (request = requests; request; request = request->next) {
subid = request->requestvb->name[OID_LENGTH(systemStats_oid)]; subid = request->requestvb->name[reginfo->rootoid_len - 2];
switch (subid) { switch (subid) {
case versionString_oid: case versionString_oid:
@ -95,13 +95,9 @@ int handle_identity(netsnmp_mib_handler *handler, netsnmp_handler_registration *
} }
break; break;
case MODE_GETNEXT:
snmp_log(LOG_ERR, "MODE_GETNEXT not supported (yet)\n");
break;
default: default:
/* we should never get here, so this is a really bad error */ /* we should never get here, so this is a really bad error */
snmp_log(LOG_ERR, "Unknown mode (%d) in handle_versionString\n", reqinfo->mode ); snmp_log(LOG_ERR, "Unknown mode (%d) in handle_identity\n", reqinfo->mode );
return SNMP_ERR_GENERR; return SNMP_ERR_GENERR;
} }
@ -119,7 +115,7 @@ int handle_systemStats(netsnmp_mib_handler *handler, netsnmp_handler_registratio
switch(reqinfo->mode) { switch(reqinfo->mode) {
case MODE_GET: case MODE_GET:
for (request = requests; request; request = request->next) { for (request = requests; request; request = request->next) {
subid = request->requestvb->name[OID_LENGTH(systemStats_oid)]; subid = request->requestvb->name[reginfo->rootoid_len - 2];
switch (subid) { switch (subid) {
case uptime_oid: case uptime_oid:
@ -162,10 +158,6 @@ int handle_systemStats(netsnmp_mib_handler *handler, netsnmp_handler_registratio
} }
break; break;
case MODE_GETNEXT:
snmp_log(LOG_ERR, "MODE_GETNEXT not supported (yet)\n");
break;
default: default:
/* we should never get here, so this is a really bad error */ /* we should never get here, so this is a really bad error */
snmp_log(LOG_ERR, "Unknown mode (%d) in handle_systemStats\n", reqinfo->mode); snmp_log(LOG_ERR, "Unknown mode (%d) in handle_systemStats\n", reqinfo->mode);