Module: sems Branch: rco/snmp Commit: 05457ca67b178a042a04a34f7fb367e4865826d9 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sems/?a=commit;h=05457ca67b178a042a04a34f7fb367e4865826d9
Author: Raphael Coeffic <[email protected]> Committer: Raphael Coeffic <[email protected]> Date: Mon Aug 20 11:09:34 2012 +0200 snmp: smoothed shutdown --- apps/snmp/Snmp.cpp | 89 ++++++++++++++++++++++++++++++++++++++++++++++++--- apps/snmp/Snmp.h | 6 +++ 2 files changed, 89 insertions(+), 6 deletions(-) diff --git a/apps/snmp/Snmp.cpp b/apps/snmp/Snmp.cpp index 7982dda..2901551 100644 --- a/apps/snmp/Snmp.cpp +++ b/apps/snmp/Snmp.cpp @@ -2,6 +2,7 @@ #include <net-snmp/net-snmp-config.h> #include <net-snmp/net-snmp-includes.h> +#include <net-snmp/library/large_fd_set.h> #include <net-snmp/agent/net-snmp-agent-includes.h> #include "semsStats.h" #include "log.h" @@ -9,12 +10,21 @@ #define MOD_NAME "snmp" EXPORT_MODULE_FUNC(SnmpFactory); - DEFINE_MODULE_INSTANCE(SnmpFactory, MOD_NAME) SnmpFactory::SnmpFactory(const string& name) : AmPluginFactory(name) { + bzero(wakeup_pipe,sizeof(int)*2); +} + +void SnmpFactory::interrupt_snmp_agent() +{ + unsigned char faked_byte=0; + if(write(wakeup_pipe[1],&faked_byte,1) != 1) { + ERROR("while writing to wakeup pipe: %s\n", + strerror(errno)); + } } int snmp_custom_log_fct(int majorID, int minorID, @@ -31,8 +41,70 @@ int snmp_custom_log_fct(int majorID, int minorID, return 1; } +void fake_wakeup_func(int fd) +{ + unsigned char fake_buf; + read(fd,&fake_buf,1); +} + +int SnmpFactory::check_and_process_snmp(netsnmp_large_fd_set* fdset) +{ + struct timeval timeout = { LONG_MAX, 0 }, *tvp = &timeout; + int numfds; + int count; + int fakeblock = 0; + + NETSNMP_LARGE_FD_ZERO(fdset); + + numfds = wakeup_pipe[0]+1; + NETSNMP_LARGE_FD_SET(wakeup_pipe[0],fdset); + + snmp_select_info2(&numfds, fdset, tvp, &fakeblock); + if (fakeblock != 0) { + /* + * There are no alarms registered, so + * let select() block forever. + */ + + tvp = NULL; + } + + count = select(numfds, fdset->lfs_setptr, 0, 0, tvp); + if (count > 0) { + /* + * packets found, process them + */ + snmp_read2(fdset); + if(NETSNMP_LARGE_FD_ISSET(wakeup_pipe[0],fdset)) { + fake_wakeup_func(wakeup_pipe[0]); + } + } else + switch (count) { + case 0: + snmp_timeout(); + break; + case -1: + if (errno != EINTR) { + snmp_log_perror("select"); + } + return -1; + default: + snmp_log(LOG_ERR, "select returned %d\n", count); + return -1; + } /* endif -- count>0 */ + + /* + * Run requested alarms. + */ + run_alarms(); + + return count; +} + void SnmpFactory::run() { + netsnmp_large_fd_set fdset; + // Start SNMP Agent agent_running.set(true); @@ -57,15 +129,13 @@ void SnmpFactory::run() /* example-demon will be used to read example-demon.conf files. */ init_snmp("sems"); + netsnmp_large_fd_set_init(&fdset, FD_SETSIZE); snmp_log(LOG_INFO,"SEMS SNMP-Agent is up and running.\n"); /* your main loop here... */ while(agent_running.get()) { - /* if you use select(), see snmp_select_info() in snmp_api(3) */ - /* --- OR --- */ - agent_check_and_process(1); /* 0 == don't block */ - //snmp_log(LOG_INFO,"one time.\n"); + check_and_process_snmp(&fdset); } /* at shutdown time */ @@ -76,10 +146,18 @@ void SnmpFactory::run() void SnmpFactory::on_stop() { agent_running.set(false); + interrupt_snmp_agent(); + join(); } int SnmpFactory::onLoad() { + // init wakeup pipe + if(pipe(wakeup_pipe)) { + ERROR("pipe(): %s\n",strerror(errno)); + return -1; + } + start(); return 0; } @@ -87,6 +165,5 @@ int SnmpFactory::onLoad() void SnmpFactory::onUnload() { stop(); - join(); }; diff --git a/apps/snmp/Snmp.h b/apps/snmp/Snmp.h index c6635c5..874a1f8 100644 --- a/apps/snmp/Snmp.h +++ b/apps/snmp/Snmp.h @@ -4,14 +4,20 @@ #include "AmApi.h" #include "AmThread.h" +#include <net-snmp/library/large_fd_set.h> + class SnmpFactory : public AmPluginFactory, public AmThread { + int wakeup_pipe[2]; AmSharedVar<bool> agent_running; SnmpFactory(const string& name); + void interrupt_snmp_agent(); + int check_and_process_snmp(netsnmp_large_fd_set* fdset); + protected: void run(); void on_stop(); _______________________________________________ Semsdev mailing list [email protected] http://lists.iptel.org/mailman/listinfo/semsdev
