Hello Steven,
I attached a patch again.
I am not prepared to link status callback but could you merge.
(I am still thinking but not have good idea.)
also, how about I use a "tsafe_off()" and "tsafe_on()"?
I could be wrong because I did not understand it.
Otherwise, I can not attach snmp service for trunk.
Thanks in advance.
yuki sato
Sato-san,
Really nice initial work. I have few comments on the patch which are
nitpicky but which once resolved, can be merged.
first the high level issues:
configure --with-snmp should be --enable-snmp.
The configure.ac SUPPORT_SNMP variable should be enable_snmp
Running configure --enable-snmp should assume a "yes" value
Running configure without --enable-snmp should create a build without
snmp support.
"Features" should print out "snmp" in the configure output ie:
Features = nss snmp
The package should error during the configure step if net-snmp-devel
package is not installed and snmp is enabled. Currently it just doesn't
build snmp support without giving any warning. This is likely confusing
to users.
I get the following after installing when running.
Mar 11 14:43:51 corosync [SERV ] Service engine loaded: corosync
profile loading service
/usr/libexec/lcrso/service_snmp.lcrso: open
failed: /usr/libexec/lcrso/service_snmp.lcrso: undefined symbol:
snmp_send
I looked over the Makefile and the output looks correct on my f11 system
- not sure why its not working.
SNMPLIBS is way overloaded. I manually compiled as follows:
gcc `net-snmp-config --libs` -shared -Wl,-soname=service_snmp.lcros
snmp.o -o service_snmp.lcrso
This gives the dependencies:
[r...@localhost services]# ldd service_snmp.lcrso
linux-gate.so.1 => (0x00ef4000)
libcrypto.so.8 => /usr/lib/libcrypto.so.8 (0x00afc000)
libsensors.so.4 => /usr/lib/libsensors.so.4 (0x00a4e000)
libnetsnmp.so.15 => /usr/lib/libnetsnmp.so.15 (0x007c6000)
libc.so.6 => /lib/libc.so.6 (0x0053b000)
libdl.so.2 => /lib/libdl.so.2 (0x0090a000)
libz.so.1 => /lib/libz.so.1 (0x00297000)
libm.so.6 => /lib/libm.so.6 (0x00110000)
/lib/ld-linux.so.2 (0x003e9000)
SNMPLIBS in my makefile on the other hand has many other unneeded
dependencies:
SNMPLIBS = -lcrypto -lsensors -L/usr/lib -lnetsnmpagent -lnetsnmphelpers
-lnetsnmpmibs -lnetsnmp -lz -Wl,-E
-Wl,-rpath,/usr/lib/perl5/5.10.0/i386-linux-thread-multi/CORE
-L/usr/local/lib -L/usr/lib/perl5/5.10.0/i386-linux-thread-multi/CORE
-lperl -lresolv -lnsl -ldl -lm -lcrypt -lutil -lpthread -lc
Also -rpath is not allowed in corosync.
when running I see:
Mar 11 14:57:10 corosync [SNMP ] ringid:340 nodeid:1 famiry:2
ip:192.168.1.105.
Log SNMP messages at debug level
famiry is a typo - should be family
additional comments inline in the patch.
make distcheck fails. That must work to be able to merge the patch,
since that is part of our release process. There are two ways to solve
this - add the COROSYNC-MIB.txt to EXTRA_DIST in the conf dir, or
alternately (less preferred) add to top level Makefile.am
Really great work! just a few issues to sort out and we should be good
for merge.
Regards
-steve
Index: include/corosync/corodefs.h
===================================================================
--- include/corosync/corodefs.h (revision 2739)
+++ include/corosync/corodefs.h (working copy)
@@ -57,7 +57,8 @@
TMR_SERVICE = 14,
VOTEQUORUM_SERVICE = 15,
NTF_SERVICE = 16,
- AMF_V2_SERVICE = 17
+ AMF_V2_SERVICE = 17,
+ SNMP_SERVICE = 18
};
#ifdef HAVE_SMALL_MEMORY_FOOTPRINT
Index: services/Makefile.am
===================================================================
--- services/Makefile.am (revision 2739)
+++ 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) $(COVERAGE_LCRSO_EXTRA_LDFLAGS) -shared -Wl,-soname=$@
$^ -o $@
service_%.lcrso: %.o
$(CC) $(CFLAGS) $(COVERAGE_LCRSO_EXTRA_LDFLAGS) -shared -Wl,-soname=$@
$^ -o $@
+
+if BUILD_SNMP
+service_snmp.lcrso: snmp.o
+ $(CC) $(CFLAGS) $(COVERAGE_LCRSO_EXTRA_LDFLAGS) $(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,620 @@
+/*
+ * 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>
+
+#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 "../exec/tsafe.h"
+
+/*
+#include <corosync/ipc_cfg.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.35488"
+#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"
+
+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 {
+ corosync_timer_handle_t timeout_timer_handle;
+ unsigned long long snmp_duration;
+};
+
+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 */
+
+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) {
+ tsafe_off();
+ sendsnmp_ifacetrap (snmp_manager, api->totem_nodeid_get(),
status, iface);
+ tsafe_on();
+ my_iface_update (&interface);
+ }
+
+ if (instance != NULL) {
+ api->timer_add_duration (
+ instance->snmp_duration * 1000000000ULL,
+ (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 = 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) {
+ log_printf (LOGSYS_LEVEL_ERROR, "Could not create snmp
transport");
+ }
+ 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 */
+ log_printf (LOGSYS_LEVEL_ERROR, "Could not send SNMP trap");
+ 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 */
+ log_printf (LOGSYS_LEVEL_ERROR, "Could not send SNMP trap");
+ snmp_free_pdu(trap_pdu);
+ }
+}
+
+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);
+ }
+ /* timer handle set*/
+ snmpsvc_instance->snmp_duration = 10ULL;
+ api->timer_add_duration (
+ snmpsvc_instance->snmp_duration * 1000000000ULL,
+ (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;
+
+ api->timer_delete (snmpsvc_instance->timeout_timer_handle);
+
+ nodeid = api->totem_nodeid_get();
+ node = totemip_print (&my_interface.address[0]);
+ if (node != NULL) {
+ tsafe_off();
+ sendsnmp_nodetrap (snmp_manager, nodeid,
SNMP_NODE_STATUS_LEFT, node);
+ tsafe_on();
+ }
+ }
+ 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\tfamily:%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) {
+ tsafe_off();
+ sendsnmp_nodetrap (snmp_manager,
nodeid, SNMP_NODE_STATUS_LEFT, node);
+ tsafe_on();
+ }
+ }
+ }
+
+ 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) {
+ tsafe_off();
+ sendsnmp_nodetrap (snmp_manager,
nodeid, SNMP_NODE_STATUS_JOINED, node);
+ tsafe_on();
+ }
+ }
+ }
+ }
+}
+
+int snmp_lib_exit_fn (void *conn)
+{
+ return (0);
+}
+
+static int snmp_lib_init_fn (void *conn)
+{
+ return (0);
+}
+
Index: exec/service.c
===================================================================
--- exec/service.c (revision 2739)
+++ 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,185 @@
+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"
+ REVISION "201003251209Z"
+ DESCRIPTION
+ "Private Enterprise Number has been assigned."
+ ::= { enterprises 35488 }
+
+--
+-- 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,38 @@
+# 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.
+
+EXTRA_DIST = COROSYNC-MIB.txt
+
+MAINTAINERCLEANFILES = Makefile.in
+
+mibdir = $(datadir)/snmp/mibs
+mib_DATA = COROSYNC-MIB.txt
+
Index: configure.ac
===================================================================
--- configure.ac (revision 2739)
+++ configure.ac (working copy)
@@ -131,7 +131,8 @@
cts/Makefile
cts/agents/Makefile
cts/CTSvars.py
- tools/Makefile])
+ tools/Makefile
+ conf/Makefile])
### Local business
@@ -219,6 +220,9 @@
[ enable_augeas="no" ])
AM_CONDITIONAL(INSTALL_AUGEAS, test x$enable_augeas = xyes)
+AC_ARG_ENABLE([snmp],
+ [ --enable-snmp : SNMP protocol support ],
+ [ default="no" ])
AC_ARG_WITH([initddir],
[ --with-initddir=DIR : path to init script directory. ],
@@ -353,6 +357,61 @@
PACKAGE_FEATURES="$PACKAGE_FEATURES augeas"
fi
+if test "x${enable_snmp}" = xyes; then
+ SNMPCONFIG=""
+ AC_CHECK_HEADERS(net-snmp/net-snmp-config.h)
+
+ if test "x${ac_cv_header_net_snmp_net_snmp_config_h}" != "xyes"; then
+ enable_snmp=no
+ fi
+
+ if test $enable_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.)
+ enable_snmp=no
+ fi
+ fi
+
+ if test $enable_snmp != no; then
+ AC_MSG_CHECKING(for special snmp libraries)
+ SNMPLIBS=`$SNMPCONFIG --libs`
+ AC_MSG_RESULT($SNMPLIBS)
+ fi
+
+ if test $enable_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
+ enable_snmp=no
+ fi
+ else
+ AC_DEFINE_UNQUOTED([NETSNMPV54], $NETSNMP_NEW_SUPPORT,
[have net-snmp5.4 over])
+ fi
+ LIBS=$savedLibs
+ fi
+
+ AC_MSG_CHECKING(for snmp)
+ AC_MSG_RESULT($enable_snmp)
+ if test $enable_snmp = no; then
+ enable_snmp=0
+ AC_MSG_ERROR(Unable to support SNMP)
+ else
+ enable_snmp=1
+ SNMP_LCRSO="snmp"
+ PACKAGE_FEATURES="$PACKAGE_FEATURES snmp"
+ AC_DEFINE_UNQUOTED([ENABLE_SNMP], $enable_snmp, [Build in
support for sending SNMP traps])
+ fi
+else
+ enable_snmp=0
+fi
+AC_SUBST([SNMPLIBS])
+AC_SUBST([SNMP_LCRSO])
+AM_CONDITIONAL(BUILD_SNMP, test "${enable_snmp}" = "1")
+
# extra warnings
EXTRA_WARNINGS=""
Index: Makefile.am
===================================================================
--- Makefile.am (revision 2739)
+++ Makefile.am (working copy)
@@ -58,7 +58,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