hello all.

I am sorry.
I attach a file again.


> hello all.
> 
> I made the prototype of the snmp service. 
> (testing...)
> 
> This service is send traps for the status change of iface and node.
> iface: up/down
> node : joined/left
> 
> install:
> ../configure --with-snmp
> 
> corosync.conf:
> snmp {
>     manager: <manager>
> }
> 
> OID: 5649112
> (OID is draft)
> 
> How about this service?
> I would like to hear any opinion.
> 
> 
> Also, the notification of the interface is not complete.
> Because it do not get status of iface.
> 
> in order to get status, can not I make a "iface_change_fn" usable on 
> "corosync_service_engine" ?
> Or, can not have some function by  "corosync_api_v1" ?
> 
> Is there any other way?
> 
> Thanks in advance.
> 
> yuki sato
> 
> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> Openais mailing list
> [email protected]
> https://lists.linux-foundation.org/mailman/listinfo/openais

Index: include/corosync/corodefs.h
===================================================================
--- include/corosync/corodefs.h (revision 2678)
+++ include/corosync/corodefs.h (working copy)
@@ -58,6 +58,9 @@
        VOTEQUORUM_SERVICE = 15,
        NTF_SERVICE = 16,
        AMF_V2_SERVICE = 17
+#ifdef ENABLE_SNMP
+   ,SNMP_SERVICE = 18
+#endif
 };
 
 #ifdef HAVE_SMALL_MEMORY_FOOTPRINT
Index: include/corosync/snmp.h
===================================================================
--- include/corosync/snmp.h     (revision 0)
+++ include/corosync/snmp.h     (revision 0)
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2009 NIPPON TELEGRAPH AND TELEPHONE CORPORATION
+ *
+ * All rights reserved.
+ *
+ * Author: Yuki Sato ([email protected])
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ *   contributors may be used to endorse or promote products derived from this
+ *   software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef COROSYNC_SNMP_H_DEFINED
+#define COROSYNC_SNMP_H_DEFINED
+
+#include <corosync/corotypes.h>
+#include <corosync/engine/coroapi.h>
+
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/snmpv3_api.h>
+#include <net-snmp/agent/agent_trap.h>
+#include <net-snmp/library/mib.h>
+#include <net-snmp/library/snmp_api.h>
+#include <net-snmp/library/snmp_client.h>
+#include <net-snmp/library/snmp_debug.h>
+
+#define SNMP_OID_COROSYNC                      "1.3.6.1.4.1.5649112"
+#define SNMP_OID_NOTICE_ROOT           SNMP_OID_COROSYNC ".1"
+#define SNMP_OID_NOTICE_NODE_TABLE     SNMP_OID_NOTICE_ROOT ".1"
+#define SNMP_OID_NOTICE_NODE_ENTRY     SNMP_OID_NOTICE_NODE_TABLE ".1"
+#define SNMP_OID_NOTICE_NODE_INDEX     SNMP_OID_NOTICE_NODE_ENTRY ".1"
+#define SNMP_OID_NOTICE_NODE_ID                SNMP_OID_NOTICE_NODE_ENTRY ".2"
+#define SNMP_OID_NOTICE_NODE           SNMP_OID_NOTICE_NODE_ENTRY ".3"
+#define SNMP_OID_NOTICE_NODE_STATE     SNMP_OID_NOTICE_NODE_ENTRY ".4"
+#define SNMP_OID_NOTICE_IFACE_TABLE    SNMP_OID_NOTICE_ROOT ".2"
+#define SNMP_OID_NOTICE_IFACE_ENTRY    SNMP_OID_NOTICE_IFACE_TABLE ".1"
+#define SNMP_OID_NOTICE_IFACE_INDEX    SNMP_OID_NOTICE_IFACE_ENTRY ".1"
+#define SNMP_OID_NOTICE_IFACE          SNMP_OID_NOTICE_IFACE_ENTRY ".2"
+#define SNMP_OID_NOTICE_IFACE_STATE    SNMP_OID_NOTICE_IFACE_ENTRY ".3"
+
+#define SNMP_OID_TRAPS_ROOT                    SNMP_OID_COROSYNC ".100"
+#define SNMP_OID_TRAPS_NODE                    SNMP_OID_TRAPS_ROOT ".1"
+#define SNMP_OID_TRAPS_IFACE           SNMP_OID_TRAPS_ROOT ".2"
+
+/*
+#define SNMPMSG_IFACES         256
+#define SNMPMSG_IFACESTATUS    2048
+*/
+
+enum snmp_node_status {
+       SNMP_NODE_STATUS_UNKNOWN = 0,
+       SNMP_NODE_STATUS_JOINED = 1,
+       SNMP_NODE_STATUS_LEFT = 2
+};
+
+enum snmp_iface_status {
+       SNMP_IFACE_STATUS_UNKNOWN = 0,
+       SNMP_IFACE_STATUS_UP = 1,
+       SNMP_IFACE_STATUS_DOWN = 2
+};
+
+struct my_interface {
+       struct totem_ip_address address[INTERFACE_MAX];
+       char *my_iface_status[INTERFACE_MAX];
+       char **iface_status;
+       unsigned int iface_cnt;
+};
+
+struct snmpsvc_instance {
+       hdb_handle_t snmpsvc_poll_handle;
+       corosync_timer_handle_t timeout_timer_handle;
+       int snmp_duration;
+};
+
+#endif /* COROSYNC_SNMP_H_DEFINED */
Index: include/Makefile.am
===================================================================
--- include/Makefile.am (revision 2678)
+++ include/Makefile.am (working copy)
@@ -33,7 +33,7 @@
 
 CS_H                   = hdb.h cs_config.h cpg.h cfg.h evs.h mar_gen.h swab.h  
\
                        coroipcc.h coroipcs.h coroipc_types.h corodefs.h \
-                       confdb.h list.h corotypes.h quorum.h votequorum.h sam.h
+                       confdb.h list.h corotypes.h quorum.h votequorum.h sam.h 
snmp.h
 
 CS_INTERNAL_H          = ipc_cfg.h ipc_confdb.h ipc_cpg.h ipc_evs.h 
ipc_pload.h ipc_quorum.h   \
                        jhash.h pload.h cs_queue.h quorum.h sq.h 
ipc_votequorum.h coroipc_ipc.h
Index: services/Makefile.am
===================================================================
--- services/Makefile.am        (revision 2678)
+++ services/Makefile.am        (working copy)
@@ -37,7 +37,7 @@
                          -I$(top_builddir)/include/corosync \
                          -I$(top_srcdir)/include/corosync
 
-SERVICE_LCRSO          = evs cfg cpg confdb pload
+SERVICE_LCRSO          = evs cfg cpg confdb pload @SNMP_LCRSO@
 
 QUORUM_LCRSO           = votequorum testquorum
 
@@ -56,6 +56,11 @@
 service_%.lcrso: %.o
        $(CC) $(CFLAGS) -L$(top_builddir)/exec -llogsys -bundle -bundle_loader 
$(top_builddir)/exec/corosync $^ -o $@
 
+if BUILD_SNMP
+service_snmp.lcrso: snmp.o
+   $(CC) $(CFLAGS) $(SNMPLIBS) -L$(top_builddir)/exec -llogsys -bundle 
-bundle_loader $(top_builddir)/exec/corosync $^ -o $@
+endif
+
 else
 
 if BUILD_SOLARIS
@@ -66,16 +71,27 @@
 service_%.lcrso: %.o
        $(LD) $(LDFLAGS) -G $^ -o $@
 
+if BUILD_SNMP
+service_snmp.lcrso: snmp.o
+   $(LD) $(LDFLAGS) $(SNMPLIBS) -G $^ -o $@
+endif
+
 else
 quorum_%.lcrso: %.o
        $(CC) $(CFLAGS) -shared -Wl,-soname=$@ $^ -o $@
 
 service_%.lcrso: %.o
        $(CC) $(CFLAGS) -shared -Wl,-soname=$@ $^ -o $@
+
+if BUILD_SNMP
+service_snmp.lcrso: snmp.o
+   $(CC) $(CFLAGS) $(SNMPLIBS) -shared -Wl,-soname=$@ $^ -o $@
 endif
 
 endif
 
+endif
+
 %.o: %.c
        $(CC) $(AM_CFLAGS) $(CFLAGS) $(CPPFLAGS) $(INCLUDES) -c -o $@ $<
 
Index: services/snmp.c
===================================================================
--- services/snmp.c     (revision 0)
+++ services/snmp.c     (revision 0)
@@ -0,0 +1,582 @@
+/*
+ * Copyright (c) 2009 NIPPON TELEGRAPH AND TELEPHONE CORPORATION
+ *
+ * All rights reserved.
+ *
+ * Author: Yuki Sato ([email protected])
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ *      this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ *      this list of conditions and the following disclaimer in the 
documentation
+ *      and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ *      contributors may be used to endorse or promote products derived from 
this
+ *      software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#ifdef ENABLE_SNMP
+#include <sys/utsname.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <limits.h>
+#include <errno.h>
+#include <string.h>
+
+#include <corosync/corotypes.h>
+#include <corosync/coroipc_types.h>
+#include <corosync/corodefs.h>
+#include <corosync/list.h>
+#include <corosync/mar_gen.h>
+#include <corosync/totem/totemip.h>
+#include <corosync/totem/totem.h>
+#include <corosync/totem/coropoll.h>
+#include <corosync/lcr/lcr_comp.h>
+#include <corosync/engine/logsys.h>
+#include <corosync/engine/coroapi.h>
+
+#include <corosync/snmp.h>
+
+LOGSYS_DECLARE_SUBSYS ("SNMP");
+
+/*
+enum snmp_message_req_types {
+
+};
+*/
+
+static struct list_head trackers_list;
+
+static void snmp_confchg_fn (
+       enum totem_configuration_type configuration_type,
+       const unsigned int *member_list, size_t member_list_entries,
+       const unsigned int *left_list, size_t left_list_entries,
+       const unsigned int *joined_list, size_t joined_list_entries,
+       const struct memb_ring_id *ring_id);
+
+static int snmp_exec_init_fn (struct corosync_api_v1 *corosync_api_v1);
+static int snmp_exec_exit_fn (void);
+
+static struct corosync_api_v1 *api;
+
+static int snmp_lib_init_fn (void *conn);
+
+static int snmp_lib_exit_fn (void *conn);
+
+static char* snmp_manager;
+static int use_snmp;
+static struct my_interface my_interface;
+static struct snmpsvc_instance *snmpsvc_instance = NULL;
+
+static netsnmp_session *snmp_init (
+       const char *target);
+
+static void sendsnmp_nodetrap(
+       const char *target, 
+       unsigned int node_id,
+       unsigned int node_status,
+       const char *node );
+
+static void sendsnmp_ifacetrap(
+       const char *target, 
+       unsigned int node_id,
+       unsigned int iface_status,
+       const char *iface );
+
+/*
+ * Service Handler Definition
+ */
+/*
+static struct corosync_lib_handler snmp_lib_engine[] =
+{
+       {
+               .lib_handler_fn         = NULL,
+               .flow_control           = NULL
+       }
+};
+*/
+/*
+static struct corosync_exec_handler snmp_exec_engine[] =
+{
+       {
+               .exec_handler_fn = NULL
+       }
+};
+*/
+/*
+ * Exports the interface for the service
+ */
+struct corosync_service_engine snmp_service_engine = {
+       .name                                   = "corosync snmp service",
+       .id                                             = SNMP_SERVICE,
+       .priority                               = 1,
+       .private_data_size              = 0, /*sizeof(struct snmp_info)*/
+       .flow_control                   = CS_LIB_FLOW_CONTROL_NOT_REQUIRED,
+       .allow_inquorate                = CS_LIB_ALLOW_INQUORATE,
+       .lib_init_fn                    = snmp_lib_init_fn,
+       .lib_exit_fn                    = snmp_lib_exit_fn,
+       .lib_engine                             = 0, /*snmp_lib_engine,*/
+       .lib_engine_count               = 0, /*sizeof (snmp_lib_engine) / 
sizeof (struct corosync_lib_handler),*/
+       .exec_init_fn                   = snmp_exec_init_fn,
+       .exec_exit_fn                   = snmp_exec_exit_fn,
+       .exec_engine                    = 0, /*snmp_exec_engine,*/
+       .exec_engine_count              = 0, /* sizeof 
(snmp_aisexec_handler_fns) / sizeof (coroync_exec_handler), */
+       .confchg_fn                             = snmp_confchg_fn,
+       .sync_mode                              = CS_SYNC_V1
+};
+
+/*
+ * Dynamic Loader definition
+ */
+static struct corosync_service_engine *snmp_get_service_engine_ver0 (void);
+
+static struct corosync_service_engine_iface_ver0 snmp_service_engine_iface = {
+       .corosync_get_service_engine_ver0       = snmp_get_service_engine_ver0
+};
+
+static struct lcr_iface corosync_snmp_ver0[1] = {
+       {
+               .name                                   = "corosync_snmp",
+               .version                                = 0,
+               .versions_replace               = 0,
+               .versions_replace_count = 0,
+               .dependencies                   = 0,
+               .dependency_count               = 0,
+               .constructor                    = NULL,
+               .destructor                             = NULL,
+               .interfaces                             = NULL
+       }
+};
+
+static struct lcr_comp snmp_comp_ver0 = {
+       .iface_count                    = 1,
+       .ifaces                                 = corosync_snmp_ver0
+};
+
+static struct corosync_service_engine *snmp_get_service_engine_ver0 (void)
+{
+       return (&snmp_service_engine);
+}
+
+#ifdef COROSYNC_SOLARIS
+void corosync_lcr_component_register (void);
+
+void corosync_lcr_component_register (void) {
+#else
+__attribute__ ((constructor)) static void corosync_lcr_component_register 
(void) {
+#endif
+       lcr_interfaces_set (&corosync_snmp_ver0[0], &snmp_service_engine_iface);
+
+       lcr_component_register (&snmp_comp_ver0);
+}
+
+/* IMPL */
+
+#ifdef ENABLE_SNMP
+
+static inline int objdb_get_string(
+       hdb_handle_t object_handle,
+       const char *key,
+       char **value )
+{
+       *value = NULL;
+       if ( !api->object_key_get (object_handle, key, strlen(key), (void 
*)value, NULL) ) {
+
+               if ( *value ) {
+                       return 0;
+               }
+       }
+       return -1;
+}
+
+static inline void iface_get (
+       unsigned int nodeid,
+       struct my_interface *interface )
+{
+       int ret = api->totem_ifaces_get ( 
+                       nodeid
+               ,       interface->address
+               ,       &interface->iface_status
+               ,       &interface->iface_cnt
+       );
+       if ( ret == -1 ) {
+               interface->iface_cnt = 0;
+       }
+}
+
+static inline void my_iface_init (void)
+{
+       int i;
+
+       memset( &my_interface, 0x00, sizeof(struct my_interface) );
+       for( i = 0; i < INTERFACE_MAX; i++ ) {
+               my_interface.my_iface_status[i] = malloc(1024);
+               my_interface.my_iface_status[i][0] = '\0';
+       }
+}
+
+static inline void my_iface_update (
+       struct my_interface *interface )
+{
+       int i;
+
+       if ( interface->iface_cnt > 0 ) {
+               memcpy( &my_interface.address, &interface->address, 
sizeof(struct totem_ip_address) );
+               my_interface.iface_cnt = interface->iface_cnt;
+               for ( i = 0; i < interface->iface_cnt; i++ ) {
+                       strcpy( my_interface.my_iface_status[i], 
interface->iface_status[i] );
+               }
+       }
+}
+
+static void timer_function_iface_check (
+       void* data
+)
+{
+       int i;
+       enum snmp_iface_status status;
+       const char *iface = NULL;
+       struct my_interface interface;
+
+       struct snmpsvc_instance *instance = (struct snmpsvc_instance*)data;
+
+       iface_get( api->totem_nodeid_get(), &interface );
+
+       if ( my_interface.iface_cnt != interface.iface_cnt ) {
+               my_iface_update( &interface );
+       } else {
+               for ( i = 0; i < my_interface.iface_cnt; i++ ) {
+                       if ( strcmp( interface.iface_status[i]
+                                               , 
my_interface.my_iface_status[i]) != 0 ) {
+                               if ( strstr( interface.iface_status[i], 
"FAULTY" ) != NULL ) {
+                                       status  = SNMP_IFACE_STATUS_DOWN;
+                                       iface   = 
totemip_print(&interface.address[i]);
+                               } else if ( strstr( interface.iface_status[i], 
"active with no faults" ) != NULL &&
+                                                       strstr( 
my_interface.my_iface_status[i], "FAULTY" ) != NULL ) {
+                                       status = SNMP_IFACE_STATUS_UP;
+                                       iface   = 
totemip_print(&interface.address[i]);
+                               } else if ( strstr( interface.iface_status[i], 
"active with no faults" ) != NULL ) {
+                                       /* status changed */
+                                       my_iface_update( &interface );
+                               }
+                               break;
+                       }
+               }
+       }
+       if ( iface != NULL ) {
+               sendsnmp_ifacetrap( snmp_manager, api->totem_nodeid_get(), 
status, iface );
+               my_iface_update( &interface );
+       }
+
+       if( instance != NULL ) {
+               poll_timer_add (
+                               instance->snmpsvc_poll_handle
+                       ,       instance->snmp_duration
+                       ,       (void*)instance
+                       ,       timer_function_iface_check
+                       ,       &instance->timeout_timer_handle
+               );
+       }
+}
+
+static netsnmp_session *snmp_init (
+       const char *target )
+{
+       static netsnmp_session *session = NULL;
+#ifndef NETSNMPV54
+       char default_port[128];
+       snprintf(default_port,sizeof(default_port),"%s:162",target);
+#endif
+       if (session) {
+               return session;
+       }
+
+       if(target == NULL) {
+               return NULL;
+       }
+
+       session = malloc( sizeof(netsnmp_session) );
+       snmp_sess_init(session);
+       session->version = SNMP_VERSION_2c;
+/*
+       session->callback = snmp_input;
+*/
+       session->callback = NULL;
+       session->callback_magic = NULL;
+
+       session = snmp_add(session,
+#ifdef NETSNMPV54
+                               netsnmp_transport_open_client("snmptrap", 
target),
+#else
+                               netsnmp_tdomain_transport(default_port, 0, 
"udp"),
+#endif
+                               NULL, NULL);
+
+       if (session == NULL) {
+               snmp_sess_perror("Could not create snmp transport", session);
+       }
+       return session;
+}
+
+static inline void add_field (
+       netsnmp_pdu *trap_pdu,
+       u_char  asn_type,
+       const char *prefix,
+       void *value,
+       size_t value_size )
+{
+       oid             _oid[MAX_OID_LEN];
+       size_t  _oid_len = MAX_OID_LEN;
+       if (snmp_parse_oid(prefix, _oid, &_oid_len)) {
+               snmp_pdu_add_variable(trap_pdu, _oid, _oid_len, asn_type, 
(u_char *) value, value_size);
+       }
+}
+
+static void sendsnmp_nodetrap (
+       const char *target, 
+       unsigned int node_id,
+       enum snmp_node_status node_status,
+       const char *node )
+{
+       int                     ret;
+       char            csysuptime[20];
+       static oid      snmptrap_oid[]  = { 1,3,6,1,6,3,1,1,4,1,0 };
+       static oid      sysuptime_oid[] = { 1,3,6,1,2,1,1,3,0 };
+       time_t now = time(NULL);
+
+       netsnmp_pdu *trap_pdu;
+       netsnmp_session *session = snmp_init(target);
+       if ( session == NULL ) {
+               log_printf(LOGSYS_LEVEL_NOTICE, "Failed to init SNMP 
session.\n");
+               return ;
+       }
+
+       trap_pdu = snmp_pdu_create(SNMP_MSG_TRAP2);
+       if ( !trap_pdu ) {
+               log_printf(LOGSYS_LEVEL_NOTICE, "Failed to create SNMP 
notification.\n");
+               return ;
+       }
+
+       /* send uptime */
+       sprintf(csysuptime, "%ld", now);
+       snmp_add_var(trap_pdu, sysuptime_oid, sizeof(sysuptime_oid) / 
sizeof(oid), 't', csysuptime);
+       snmp_add_var(trap_pdu, snmptrap_oid, sizeof(snmptrap_oid) / 
sizeof(oid), 'o', SNMP_OID_TRAPS_NODE);
+
+       /* Add extries to the trap */
+       
add_field(trap_pdu,ASN_INTEGER,SNMP_OID_NOTICE_NODE_ID,(void*)&node_id,sizeof(node_id));
+       
add_field(trap_pdu,ASN_OCTET_STR,SNMP_OID_NOTICE_NODE,(void*)node,strlen(node));
+       
add_field(trap_pdu,ASN_INTEGER,SNMP_OID_NOTICE_NODE_STATE,(void*)&node_status,sizeof(node_status));
+
+       /* Send and cleanup */
+       ret = snmp_send(session, trap_pdu);
+       if(ret == 0) {
+               /* error */
+               snmp_sess_perror("Could not send SNMP trap", session);
+               snmp_free_pdu(trap_pdu);
+       }
+}
+
+static void sendsnmp_ifacetrap (
+       const char *target, 
+       unsigned int node_id,
+       enum snmp_iface_status iface_status,
+       const char *iface )
+{
+       int                     ret;
+       char            csysuptime[20];
+       static oid      snmptrap_oid[]  = { 1,3,6,1,6,3,1,1,4,1,0 };
+       static oid      sysuptime_oid[] = { 1,3,6,1,2,1,1,3,0 };
+       time_t now = time(NULL);
+
+       netsnmp_pdu *trap_pdu;
+       netsnmp_session *session = snmp_init(target);
+       if ( session == NULL ) {
+               log_printf(LOGSYS_LEVEL_NOTICE, "Failed to init SNMP 
session.\n");
+       }
+
+       trap_pdu = snmp_pdu_create(SNMP_MSG_TRAP2);
+       if ( !trap_pdu ) {
+               log_printf(LOGSYS_LEVEL_NOTICE, "Failed to create SNMP 
notification.\n");
+               return ;
+       }
+
+       /* send uptime */
+       sprintf(csysuptime, "%ld", now);
+       snmp_add_var(trap_pdu, sysuptime_oid, sizeof(sysuptime_oid) / 
sizeof(oid), 't', csysuptime);
+       
+       /* Indicate what the trap is by setting snmpTrapOid.0 */
+       snmp_add_var(trap_pdu, snmptrap_oid, sizeof(snmptrap_oid) / 
sizeof(oid), 'o', SNMP_OID_TRAPS_IFACE);
+
+       /* Add extries to the trap */
+       
add_field(trap_pdu,ASN_INTEGER,SNMP_OID_NOTICE_NODE_ID,(void*)&node_id,sizeof(node_id));
+       
add_field(trap_pdu,ASN_OCTET_STR,SNMP_OID_NOTICE_IFACE,(void*)iface,strlen(iface));
+       
add_field(trap_pdu,ASN_INTEGER,SNMP_OID_NOTICE_IFACE_STATE,(void*)&iface_status,sizeof(iface_status));
+
+       /* Send and cleanup */
+       ret = snmp_send(session, trap_pdu);
+       if(ret == 0) {
+               /* error */
+               snmp_sess_perror("Could not send SNMP trap", session);
+               snmp_free_pdu(trap_pdu);
+       }
+}
+#endif
+
+
+static int snmp_exec_init_fn (
+       struct corosync_api_v1 *corosync_api_v1)
+{
+       hdb_handle_t object_handle,snmp_find_handle;
+       struct my_interface interface;
+
+#ifdef COROSYNC_SOLARIS
+       logsys_subsys_init();
+#endif
+
+       api = corosync_api_v1;
+
+       list_init(&trackers_list);
+
+       use_snmp                = 0;
+       snmp_manager    = NULL;
+
+       /* corosync.conf read */
+       api->object_find_create(OBJECT_PARENT_HANDLE, "snmp", strlen("snmp"), 
&object_handle);
+       if( (api->object_find_next (object_handle, &snmp_find_handle)) == -1 ) {
+               return (-1);
+       }
+
+       if ( !objdb_get_string( snmp_find_handle, "manager", &snmp_manager ) ) {
+                       use_snmp = 1;
+       }
+
+       if ( use_snmp ) {
+               /* node,iface init */
+               my_iface_init();
+               iface_get( api->totem_nodeid_get(), &interface );
+               my_iface_update( &interface );
+
+               snmpsvc_instance = malloc( sizeof(struct snmpsvc_instance) );
+               if( snmpsvc_instance == NULL ) {
+                       use_snmp = 0;
+                       return(-1);
+               }
+               snmpsvc_instance->snmpsvc_poll_handle = api->poll_handle_get();
+               snmpsvc_instance->snmp_duration = 10000;
+
+               /* timer handle set*/
+               poll_timer_add (
+                               snmpsvc_instance->snmpsvc_poll_handle
+                       ,       snmpsvc_instance->snmp_duration
+                       ,       (void*)snmpsvc_instance
+                       ,       timer_function_iface_check
+                       ,       &snmpsvc_instance->timeout_timer_handle
+               );
+       }
+
+       return (0);
+}
+
+static int snmp_exec_exit_fn (void)
+{
+       if ( use_snmp ) {
+               unsigned int nodeid;
+               const char      *node;
+
+               poll_timer_delete (
+                               snmpsvc_instance->snmpsvc_poll_handle
+                       ,       snmpsvc_instance->timeout_timer_handle
+               );
+
+           nodeid = api->totem_nodeid_get();
+               node = totemip_print(&my_interface.address[0]);
+               if ( node != NULL ) {
+                       sendsnmp_nodetrap( snmp_manager, nodeid, 
SNMP_NODE_STATUS_LEFT, node );
+               }
+       }
+       return (0);
+}
+
+static void snmp_confchg_fn (
+       enum totem_configuration_type configuration_type,
+       const unsigned int *member_list, size_t member_list_entries,
+       const unsigned int *left_list, size_t left_list_entries,
+       const unsigned int *joined_list, size_t joined_list_entries,
+       const struct memb_ring_id *ring_id)
+{
+
+       log_printf(LOGSYS_LEVEL_DEBUG, 
"ringid:%lld\tnodeid:%d\tfamiry:%d\tip:%s.\n"
+               , 
ring_id->seq,ring_id->rep.nodeid,ring_id->rep.family,api->totem_ip_print(&ring_id->rep));
+
+       if ( use_snmp ) {
+               int                     i;
+               unsigned int nodeid;
+               const char      *node;
+               struct my_interface interface;
+               
+               timer_function_iface_check( NULL );
+               
+               if ( left_list_entries > 0 ) {
+                       for ( i = 0; i < left_list_entries; ++i ) {
+                           nodeid = left_list[i];
+
+                               iface_get( nodeid, &interface );
+                               node = totemip_print(&interface.address[0]);
+                               if ( node != NULL ) {
+                                       sendsnmp_nodetrap( snmp_manager, 
nodeid, SNMP_NODE_STATUS_LEFT, node );
+                               }
+                       }
+               }
+
+               if ( joined_list_entries > 0 ) {
+                       for ( i = 0; i < joined_list_entries; ++i ) {
+                           nodeid = joined_list[i];
+
+                               iface_get( nodeid, &interface );
+                               node = totemip_print(&interface.address[0]);
+                               if ( node != NULL ) {
+                                       sendsnmp_nodetrap( snmp_manager, 
nodeid, SNMP_NODE_STATUS_JOINED, node );
+                               }
+                       }
+               }
+       }
+}
+
+int snmp_lib_exit_fn (void *conn)
+{
+       return (0);
+}
+
+static int snmp_lib_init_fn (void *conn)
+{
+       return (0);
+}
+
+#endif
Index: exec/service.c
===================================================================
--- exec/service.c      (revision 2678)
+++ exec/service.c      (working copy)
@@ -89,6 +89,12 @@
                .name                    = "corosync_quorum",
                .ver                     = 0,
        }
+#ifdef ENABLE_SNMP
+   ,{
+       .name            = "corosync_snmp",
+       .ver             = 0,
+   }
+#endif
 };
 
 /*
Index: conf/COROSYNC-MIB.txt
===================================================================
--- conf/COROSYNC-MIB.txt       (revision 0)
+++ conf/COROSYNC-MIB.txt       (revision 0)
@@ -0,0 +1,181 @@
+COROSYNC-MIB DEFINITIONS ::= BEGIN
+
+--
+-- MIB objects for the corosync
+--
+
+IMPORTS
+    MODULE-IDENTITY,NOTIFICATION-TYPE,
+    Integer32,enterprises                       FROM SNMPv2-SMI
+    TEXTUAL-CONVENTION                          FROM SNMPv2-TC
+    SnmpAdminString                             FROM SNMP-FRAMEWORK-MIB
+    netSnmp                                     FROM NET-SNMP-MIB
+    InetAddressType, InetAddress                FROM INET-ADDRESS-MIB
+;
+
+corosync MODULE-IDENTITY
+    LAST-UPDATED    "200911061318Z"
+    ORGANIZATION    "www.corosync.org"
+    CONTACT-INFO    "name:  Yuki Sato
+                     email: [email protected]"
+    DESCRIPTION     "MIB objects for the corosync"
+    REVISION        "200911061318Z"
+    DESCRIPTION     "First draft"
+        ::= { enterprises 5649112 }
+
+--
+-- top level structure
+--
+corosyncNotice OBJECT IDENTIFIER ::= { corosync 1 }
+
+--
+--  corosync MIB entries
+--
+
+--
+-- Node Information
+--
+corosyncNoticeNodeStatusTable OBJECT-TYPE
+    SYNTAX      SEQUENCE OF corosyncNoticeNodeEntry
+    MAX-ACCESS  accessible-for-notify
+    STATUS      current
+    DESCRIPTION
+        "The table contains information about the nodes in the corosync."
+::= { corosyncNotice 1 }
+
+corosyncNoticeNodeEntry OBJECT-TYPE
+    SYNTAX      corosyncNoticeNodeEntry
+    MAX-ACCESS  accessible-for-notify
+    STATUS      current
+    DESCRIPTION
+        "The entry containing information about the iface."
+    INDEX   { corosyncNoticeNodeIndex }
+::= { corosyncNoticeNodeStatusTable 1 }
+
+corosyncNoticeNodeEntry ::= SEQUENCE {
+    corosyncNoticeNodeIndex     Integer32,
+    corosyncNoticeNodeid        Integer32,
+    corosyncNoticeNode          OCTET STRING,
+    corosyncNoticeNodeStatus    INTEGER
+}
+
+corosyncNoticeNodeIndex OBJECT-TYPE
+    SYNTAX      Integer32
+    MAX-ACCESS  accessible-for-notify
+    STATUS      current
+    DESCRIPTION "The unique integer of the node."
+::= { corosyncNoticeNodeEntry 1 }
+
+corosyncNoticeNodeid OBJECT-TYPE
+    SYNTAX      Integer32
+    MAX-ACCESS  accessible-for-notify
+    STATUS      current
+    DESCRIPTION "The id of the node."
+::= { corosyncNoticeNodeEntry 2 }
+
+corosyncNoticeNode OBJECT-TYPE
+    SYNTAX      OCTET STRING (SIZE(1..64))
+    MAX-ACCESS  accessible-for-notify
+    STATUS      current
+    DESCRIPTION
+        "The iface of the node."
+::= { corosyncNoticeNodeEntry 3 }
+
+corosyncNoticeNodeStatus OBJECT-TYPE
+    SYNTAX      INTEGER {
+                unknown (0),
+                joined  (1),
+                left    (2)
+            }
+    MAX-ACCESS  accessible-for-notify
+    STATUS      current
+    DESCRIPTION
+        "The status change of the node."
+::= { corosyncNoticeNodeEntry 4 }
+
+--
+-- Iface(s) Information
+--
+corosyncNoticeIfaceStatusTable OBJECT-TYPE
+    SYNTAX      SEQUENCE OF corosyncNoticeIfaceEntry
+    MAX-ACCESS  accessible-for-notify
+    STATUS      current
+    DESCRIPTION
+        "The table describes the iface(s) that are used by the corosync."
+::= { corosyncNotice 2 }
+
+corosyncNoticeIfaceEntry OBJECT-TYPE
+    SYNTAX      corosyncNoticeIfaceEntry
+    MAX-ACCESS  accessible-for-notify
+    STATUS      current
+    DESCRIPTION
+        "The entry containing information about the iface."
+    INDEX   { corosyncNoticeIfaceIndex }
+::= { corosyncNoticeIfaceStatusTable 1 }
+
+corosyncNoticeIfaceEntry ::= SEQUENCE {
+    corosyncNoticeIfaceIndex    INTEGER,
+    corosyncNoticeIface         OCTET STRING,
+    corosyncNoticeIfaceStatus   OCTET STRING
+}
+
+corosyncNoticeIfaceIndex OBJECT-TYPE
+    SYNTAX      Integer32
+    MAX-ACCESS  accessible-for-notify
+    STATUS      current
+    DESCRIPTION
+        "The unique integer of the iface(s)."
+::= { corosyncNoticeIfaceEntry 1 }
+
+corosyncNoticeIface OBJECT-TYPE
+    SYNTAX      OCTET STRING (SIZE(1..64))
+    MAX-ACCESS  accessible-for-notify
+    STATUS      current
+    DESCRIPTION
+        "The iface(s) of the change happened node."
+::= { corosyncNoticeIfaceEntry 2 }
+
+corosyncNoticeIfaceStatus OBJECT-TYPE
+    SYNTAX      INTEGER {
+                unknown (0),
+                up      (1),
+                down    (2)
+            }
+    MAX-ACCESS accessible-for-notify
+    STATUS      current
+    DESCRIPTION
+        "The status change of the iface."
+::= { corosyncNoticeIfaceEntry 3 }
+
+--corosyncNoticeIfaceStatus OBJECT-TYPE
+--   SYNTAX     OCTET STRING (SIZE(1..1024))
+--   MAX-ACCESS accessible-for-notify
+--   STATUS     current
+--   DESCRIPTION
+--       "The iface(s) status of the change happened node."
+--::= { corosyncNoticeIfaceEntry 3 }
+
+--
+-- Trap Information
+--
+corosyncNoticeTrap OBJECT IDENTIFIER ::= { corosync 100 }
+
+corosyncNoticeNodeTrap NOTIFICATION-TYPE
+    OBJECTS
+        { corosyncNoticeNodeid corosyncNoticeNode corosyncNoticeNodeStatus }
+    STATUS      current
+    DESCRIPTION
+        "The node status change event just happened."
+::= { corosyncNoticeTrap 1 }
+
+corosyncNoticeIfaceTrap NOTIFICATION-TYPE
+    OBJECTS
+        { corosyncNoticeNodeid corosyncNoticeIface corosyncNoticeIfaceStatus }
+    STATUS  current
+    DESCRIPTION
+        "The iface status change event just happened."
+::= { corosyncNoticeTrap 2 }
+
+END
+
+
Index: conf/Makefile.am
===================================================================
--- conf/Makefile.am    (revision 0)
+++ conf/Makefile.am    (revision 0)
@@ -0,0 +1,35 @@
+# Copyright (c) 2009 Red Hat, Inc.
+#
+# Authors: Andrew Beekhof
+#         Steven Dake ([email protected])
+#
+# This software licensed under BSD license, the text of which follows:
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# - Redistributions of source code must retain the above copyright notice,
+#   this list of conditions and the following disclaimer.
+# - Redistributions in binary form must reproduce the above copyright notice,
+#   this list of conditions and the following disclaimer in the documentation
+#   and/or other materials provided with the distribution.
+# - Neither the name of the MontaVista Software, Inc. nor the names of its
+#   contributors may be used to endorse or promote products derived from this
+#   software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+MAINTAINERCLEANFILES    = Makefile.in
+
+mibdir = $(datadir)/snmp/mibs
+mib_DATA = COROSYNC-MIB.txt
Index: configure.ac
===================================================================
--- configure.ac        (revision 2678)
+++ configure.ac        (working copy)
@@ -131,7 +131,8 @@
                 cts/Makefile
                 cts/agents/Makefile
                 cts/CTSvars.py
-                tools/Makefile])
+                tools/Makefile
+                conf/Makefile])
 
 ### Local business
 
@@ -232,6 +233,11 @@
        [ SOCKETDIR="$withval" ],
        [ SOCKETDIR="$localstatedir/run" ])
 
+AC_ARG_WITH([snmp],
+    [  --with-snmp             : SNMP protocol support ],
+    [ SUPPORT_SNMP="$withval" ],
+    [ SUPPORT_SNMP="no" ])
+
 # OS detection
 # THIS SECTION MUST DIE!
 CP=cp
@@ -350,6 +356,61 @@
        PACKAGE_FEATURES="$PACKAGE_FEATURES augeas"
 fi
 
+if test "x${SUPPORT_SNMP}" = xyes; then
+
+   SNMPCONFIG=""
+#  AC_MSG_RESULT($SUPPORT_SNMP)
+   AC_CHECK_HEADERS(net-snmp/net-snmp-config.h)
+
+   if test "x${ac_cv_header_net_snmp_net_snmp_config_h}" != "xyes"; then
+       SUPPORT_SNMP=no
+   fi
+
+   if test $SUPPORT_SNMP != no; then
+       AC_PATH_PROGS(SNMPCONFIG, net-snmp-config)
+       if test "X${SNMPCONFIG}" = "X"; then
+           AC_MSG_RESULT(You need the net_snmp development package to 
continue.)
+           SUPPORT_SNMP=no
+       fi
+   fi
+
+   if test $SUPPORT_SNMP != no; then
+       AC_MSG_CHECKING(for special snmp libraries)
+       SNMPLIBS=`$SNMPCONFIG --agent-libs`
+       AC_MSG_RESULT($SNMPLIBS)
+   fi
+
+   if test $SUPPORT_SNMP != no; then
+       savedLibs=$LIBS
+       LIBS="$LIBS $SNMPLIBS"
+       AC_CHECK_FUNCS(netsnmp_transport_open_client)
+       if test $ac_cv_func_netsnmp_transport_open_client != yes; then
+           AC_CHECK_FUNCS(netsnmp_tdomain_transport)
+           if test $ac_cv_func_netsnmp_tdomain_transport != yes; then
+               SUPPORT_SNMP=no
+           fi
+       else
+           AC_DEFINE_UNQUOTED([NETSNMPV54], $NETSNMP_NEW_SUPPORT, [have 
net-snmp5.4 over])
+       fi
+       LIBS=$savedLibs
+   fi
+
+   if test $SUPPORT_SNMP = no; then
+       SUPPORT_SNMP=0
+       AC_MSG_WARN(Unable to support SNMP)
+   else
+       SUPPORT_SNMP=1
+       SNMP_LCRSO="snmp"
+       PACKAGE_FEATURES="$PACKAGE_FEATURES snmp"
+       AC_DEFINE_UNQUOTED([ENABLE_SNMP], $SUPPORT_SNMP, [Build in support for 
sending SNMP traps])
+   fi
+else
+   SUPPORT_SNMP=0
+fi
+AC_SUBST([SNMPLIBS])
+AC_SUBST([SNMP_LCRSO])
+AM_CONDITIONAL(BUILD_SNMP, test "${SUPPORT_SNMP}" = "1")
+
 # extra warnings
 EXTRA_WARNINGS=""
 
Index: Makefile.am
===================================================================
--- Makefile.am (revision 2678)
+++ Makefile.am (working copy)
@@ -57,7 +57,7 @@
 endif
 
 SUBDIRS                        = include lcr lib exec services tools test cts 
pkgconfig \
-                         man init
+                         man init conf
 
 install-exec-local:
        $(INSTALL) -d $(DESTDIR)/${COROSYSCONFDIR}/service.d
_______________________________________________
Openais mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/openais

Reply via email to