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

Reply via email to