osaf/services/saf/logsv/lgs/Makefile.am | 7 +-
osaf/services/saf/logsv/lgs/lgs_cb.h | 9 +
osaf/services/saf/logsv/lgs/lgs_clm.cc | 403 ++++++++++++++++++++++++++++++++
osaf/services/saf/logsv/lgs/lgs_clm.h | 39 +++
osaf/services/saf/logsv/lgs/lgs_evt.cc | 15 +
osaf/services/saf/logsv/lgs/lgs_main.cc | 28 ++
osaf/services/saf/logsv/lgs/lgs_mds.cc | 38 ++-
7 files changed, 536 insertions(+), 3 deletions(-)
diff --git a/osaf/services/saf/logsv/lgs/Makefile.am
b/osaf/services/saf/logsv/lgs/Makefile.am
--- a/osaf/services/saf/logsv/lgs/Makefile.am
+++ b/osaf/services/saf/logsv/lgs/Makefile.am
@@ -37,7 +37,8 @@ noinst_HEADERS = \
lgs_mbcsv_v3.h \
lgs_mbcsv_v5.h \
lgs_recov.h \
- lgs_imm_gcfg.h
+ lgs_imm_gcfg.h \
+ lgs_clm.h
osaf_execbindir = $(pkglibdir)
osaf_execbin_PROGRAMS = osaflogd
@@ -67,7 +68,8 @@ osaflogd_SOURCES = \
lgs_mbcsv_v3.cc \
lgs_mbcsv_v5.cc \
lgs_recov.cc \
- lgs_imm_gcfg.cc
+ lgs_imm_gcfg.cc \
+ lgs_clm.cc
osaflogd_LDADD = \
$(top_builddir)/osaf/tools/safimm/src/libimmutil.la \
@@ -75,4 +77,5 @@ osaflogd_LDADD = \
$(top_builddir)/osaf/libs/saf/libSaAmf/libSaAmf.la \
$(top_builddir)/osaf/libs/saf/libSaImm/libSaImmOi.la \
$(top_builddir)/osaf/libs/saf/libSaImm/libSaImmOm.la \
+ $(top_builddir)/osaf/libs/saf/libSaClm/libSaClm.la \
$(top_builddir)/osaf/libs/agents/infrastructure/rda/librda.la
diff --git a/osaf/services/saf/logsv/lgs/lgs_cb.h
b/osaf/services/saf/logsv/lgs/lgs_cb.h
--- a/osaf/services/saf/logsv/lgs/lgs_cb.h
+++ b/osaf/services/saf/logsv/lgs/lgs_cb.h
@@ -21,6 +21,7 @@
#include <stdbool.h>
#include <saLog.h>
#include <saImmOi.h>
+#include <saClm.h>
#include <mbcsv_papi.h>
#include <ncs_edu_pub.h>
@@ -73,6 +74,7 @@ typedef struct lgs_cb {
MDS_DEST vaddr; /* My identification in MDS */
SaVersionT log_version; /* The version currently supported */
NCS_PATRICIA_TREE client_tree; /* LGA/Library/Client instantiation
pat. tree */
+ void *clm_node_db; /* used for C++ STL map */
SaNameT comp_name; /* Components's name LGS */
SaAmfHandleT amf_hdl; /* AMF handle, obtained thru AMF init */
SaSelectionObjectT amfSelectionObject; /* Selection Object to wait for
AMF events */
@@ -80,6 +82,9 @@ typedef struct lgs_cb {
bool is_quiesced_set;
SaImmOiHandleT immOiHandle; /* IMM OI handle
*/
SaSelectionObjectT immSelectionObject; /* Selection Object to wait for
IMM events */
+ SaSelectionObjectT clmSelectionObject; /* Selection Object to wait for
clms events */
+ SaClmHandleT clm_hdl; /* CLM handle, obtained through CLM init
*/
+// bool clm_initialized; //For CLM init status;
SaAmfHAStateT ha_state; /* present AMF HA state of the component */
uint32_t last_client_id; /* Value of last client_id assigned
*/
uint32_t async_upd_cnt; /* Async Update Count for Warmsync */
@@ -94,6 +99,7 @@ typedef struct lgs_cb {
down events Processing */
LGA_DOWN_LIST *lga_down_list_tail;
+ NCS_SEL_OBJ clm_init_sel_obj; /* Selection object for CLM
initialization.*/
bool nid_started; /**< true if started by NID */
SaUint32T scAbsenceAllowed; /* OpenSAF global configuration for
recovery handling */
lgs_state_t lgs_recovery_state; /* Indicate current recovery state for
the server */
@@ -106,5 +112,8 @@ typedef struct lgs_cb {
extern uint32_t lgs_cb_init(lgs_cb_t *);
extern void lgs_process_mbx(SYSF_MBX *mbx);
extern uint32_t lgs_stream_add(lgs_cb_t *cb, log_stream_t *stream);
+extern uint32_t lgs_clm_node_del(NODE_ID node_id);
+extern uint32_t lgs_clm_node_add(NODE_ID node_id);
+extern uint32_t lgs_clm_node_find(NODE_ID node_id);
#endif
diff --git a/osaf/services/saf/logsv/lgs/lgs_clm.cc
b/osaf/services/saf/logsv/lgs/lgs_clm.cc
new file mode 100644
--- /dev/null
+++ b/osaf/services/saf/logsv/lgs/lgs_clm.cc
@@ -0,0 +1,403 @@
+/* -*- OpenSAF -*-
+ *
+ * (C) Copyright 2016 The OpenSAF Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Author(s): Oracle
+ *
+ */
+#include "osaf/services/saf/logsv/lgs/lgs.h"
+#include "osaf/services/saf/logsv/lgs/lgs_clm.h"
+
+static bool clm_initialized;
+typedef std::map<NODE_ID, lgs_clm_node_t *> ClmNodeMap;
+
+/**
+ * @brief Checks if LGSV has already initialized with CLM service.
+ *
+ * @return true/false.
+ */
+bool is_clm_init() {
+ return (((lgs_cb->clm_hdl != 0)
+ && (clm_initialized == true)) ? true : false);
+}
+
+/**
+ * Name : lgs_clm_node_map_init
+ * Description : This routine is used to initialize the clm_node_map
+ * Arguments : lgs_cb - pointer to the lgs Control Block
+ * Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE
+ * Notes : None
+ */
+uint32_t lgs_clm_node_map_init(lgs_cb_t *lgs_cb) {
+ TRACE_ENTER();
+ if (lgs_cb->clm_node_db) {
+ TRACE("CLM Node map already exists");
+ return NCSCC_RC_FAILURE;
+ }
+
+ lgs_cb->clm_node_db = new ClmNodeMap;
+ TRACE_LEAVE();
+ return NCSCC_RC_SUCCESS;
+}
+
+/**
+ * Name : lgs_clm_node_map_destroy
+ * Description : This routine is used to destroy the clm_node_map
+ * Arguments : lgs_cb - pointer to the lgs Control Block
+ * Return Values : void
+ * Notes : None
+ */
+void lgs_clm_node_map_destroy() {
+ delete reinterpret_cast<ClmNodeMap *>(lgs_cb->clm_node_db);
+ lgs_cb->clm_node_db = 0;
+}
+
+/**
+ * Name : lgs_clm_node_find
+ * Description : This routine finds the clm_node .
+ * Arguments : clm_node_id - CLM Node id
+ * Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE
+ * Notes : None
+ */
+uint32_t lgs_clm_node_find(NODE_ID clm_node_id) {
+ TRACE_ENTER();
+ uint32_t rc;
+
+ ClmNodeMap *clmNodeMap(reinterpret_cast<ClmNodeMap *>
+ (lgs_cb->clm_node_db));
+
+ if (clmNodeMap) {
+ ClmNodeMap::iterator it(clmNodeMap->find(clm_node_id));
+
+ if (it != clmNodeMap->end()) {
+ rc = NCSCC_RC_SUCCESS;
+ } else {
+ rc = NCSCC_RC_FAILURE;
+ TRACE("clm_node_id not exist DB failed : %x", clm_node_id);
+ }
+ } else {
+ TRACE("clmNodeMap DB not exist failed : %x", clm_node_id);
+ rc = NCSCC_RC_FAILURE;
+ // osafassert(false);
+ }
+
+ TRACE_LEAVE();
+ return rc;
+}
+
+/**
+ * Name : lgs_clm_node_add
+ * Description : This routine adds the new node to clm_node_map.
+ * Arguments : clm_node_id - CLM Node id
+ * Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE
+ * Notes : None
+ */
+uint32_t lgs_clm_node_add(NODE_ID clm_node_id) {
+ TRACE_ENTER();
+ uint32_t rc;
+ lgs_clm_node_t *clm_node;
+
+ clm_node = reinterpret_cast<lgs_clm_node_t *>
+ (malloc(sizeof(lgs_clm_node_t)));
+
+ clm_node->clm_node_id = clm_node_id;
+
+ ClmNodeMap *clmNodeMap(reinterpret_cast<ClmNodeMap *>
+ (lgs_cb->clm_node_db));
+
+ if (clmNodeMap) {
+ std::pair<ClmNodeMap::iterator, bool> p(clmNodeMap->insert(
+ std::make_pair(clm_node->clm_node_id, clm_node)));
+
+ if (!p.second) {
+ TRACE("unable to add clm node info map - the id %x already existed",
+ clm_node->clm_node_id);
+ rc = NCSCC_RC_FAILURE;
+ }
+ } else {
+ TRACE("can't find local sec map in lgs_clm_node_add");
+ rc = NCSCC_RC_FAILURE;
+ }
+ TRACE_LEAVE();
+ return rc;
+}
+
+/**
+ * Name : lgs_clm_node_del
+ * Description : Function to Delete the clm_node.
+ * Arguments : clm_node_id - CLM Node id
+ * Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE
+ * Notes : None.
+ */
+uint32_t lgs_clm_node_del(NODE_ID clm_node_id) {
+ TRACE_ENTER();
+ uint32_t rc;
+
+ ClmNodeMap *clmNodeMap(reinterpret_cast<ClmNodeMap *>
+ (lgs_cb->clm_node_db));
+
+ if (clmNodeMap) {
+ ClmNodeMap::iterator it(clmNodeMap->find(clm_node_id));
+
+ if (it != clmNodeMap->end()) {
+ clmNodeMap->erase(it);
+ rc = NCSCC_RC_SUCCESS;
+ } else {
+ TRACE("clm_node_id delete failed : %x", clm_node_id);
+ rc = NCSCC_RC_FAILURE;
+ }
+ } else {
+ TRACE("clm_node_id delete to map not exist failed : %x", clm_node_id);
+ rc = NCSCC_RC_FAILURE;
+ }
+
+ TRACE_LEAVE();
+ return rc;
+}
+
+/**
+ * @brief Send Membership status of node to a lib on that node.
+ *
+ * @param SaClmClusterChangesT (CLM status of node)
+ * @param client_id
+ * @param mdsDest of client
+ *
+ * @return NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE.
+ */
+uint32_t send_clm_node_status_lib(SaClmClusterChangesT clusterChange,
+ unsigned int client_id, MDS_DEST mdsDest) {
+ uint32_t rc;
+ NCSMDS_INFO mds_info = {0};
+ lgsv_msg_t msg;
+ TRACE_ENTER();
+ TRACE_3("change:%u, client_id: %u", clusterChange, client_id);
+
+ memset(&msg, 0, sizeof(lgsv_msg_t));
+ msg.type = LGSV_LGS_CBK_MSG;
+ msg.info.cbk_info.type = LGSV_CLM_NODE_STATUS_CALLBACK;
+ msg.info.cbk_info.lgs_client_id = client_id;
+ msg.info.cbk_info.inv = 0;
+ msg.info.cbk_info.clm_node_status_cbk.clm_node_status = clusterChange;
+
+ mds_info.i_mds_hdl = lgs_cb->mds_hdl;
+ mds_info.i_svc_id = NCSMDS_SVC_ID_LGS;
+ mds_info.i_op = MDS_SEND;
+ mds_info.info.svc_send.i_msg = &msg;
+ mds_info.info.svc_send.i_to_svc = NCSMDS_SVC_ID_LGA;
+ mds_info.info.svc_send.i_priority = MDS_SEND_PRIORITY_HIGH;
+ mds_info.info.svc_send.i_sendtype = MDS_SENDTYPE_SND;
+ mds_info.info.svc_send.info.snd.i_to_dest = mdsDest;
+ rc = ncsmds_api(&mds_info);
+ if (rc != NCSCC_RC_SUCCESS)
+ LOG_NO("Failed (%u) to send of WRITE ack to: %" PRIx64, rc, mdsDest);
+
+ TRACE_LEAVE();
+ return rc;
+}
+
+/**
+ * @brief Sends CLM membership status of the node to all the clients
+ * on the node except A11 clients.
+ * @param clusterChange (CLM membership status of node).
+ * @param NCS clm_node_id.
+ * @return NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE.
+ */
+uint32_t send_cluster_membership_msg_to_clients(
+ SaClmClusterChangesT clusterChange, NODE_ID clm_node_id) {
+ uint32_t rc = NCSCC_RC_SUCCESS;
+ log_client_t *rp = NULL;
+ uint32_t client_id_net;
+
+ TRACE_ENTER();
+ TRACE_3("clm_node_id: %x, change:%u", clm_node_id, clusterChange);
+
+ rp = reinterpret_cast<log_client_t *>
+ (ncs_patricia_tree_getnext(&lgs_cb->client_tree, NULL));
+
+ while (rp != NULL) {
+ /** Store the client_id_net for get Next */
+ client_id_net = rp->client_id_net;
+ NODE_ID tmp_clm_node_id = m_LGS_GET_NODE_ID_FROM_ADEST(rp->mds_dest);
+ // Do not send to A11 client. Send only to specific Node
+ if (tmp_clm_node_id == clm_node_id)
+ rc = send_clm_node_status_lib(clusterChange, rp->client_id,
+ rp->mds_dest);
+
+ rp = reinterpret_cast<log_client_t *>(ncs_patricia_tree_getnext(
+ &lgs_cb->client_tree, reinterpret_cast<uint8_t *>(&client_id_net)));
+ }
+
+ TRACE_LEAVE();
+ return rc;
+}
+
+uint32_t send_clm_node_status_change(SaClmClusterChangesT clusterChange,
+ NODE_ID clm_node_id) {
+ return (send_cluster_membership_msg_to_clients(clusterChange, clm_node_id));
+}
+
+/**
+ * @brief Checks CLM membership status of a client.
+ * A.02.01 clients are always CLM member.
+ * @param Client MDS_DEST
+ * @param Client saf version.
+ * @return NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE.
+ */
+bool is_client_clm_member(NODE_ID clm_node_id, SaVersionT *ver) {
+ // Before CLM init all clients are clm member.
+ if (is_clm_init() == false)
+ return true;
+
+ TRACE("client Version: %d.%d.%d", ver->releaseCode,
+ ver->majorVersion, ver->minorVersion);
+ // CLM integration is supported from A.02.02.
+ // So old clients A.02.01 are always clm member.
+ if ((ver->releaseCode == LOG_RELEASE_CODE_0) &&
+ (ver->majorVersion == LOG_MAJOR_VERSION_0) &&
+ (ver->minorVersion == LOG_MINOR_VERSION_0))
+ return true;
+ /*
+ It means CLM initialization is successful and this is atleast a
A.02.02 client.
+ So check CLM membership status of client's node.
+ */
+ if (lgs_clm_node_find(clm_node_id) != NCSCC_RC_SUCCESS)
+ return false;
+ else
+ return true;
+}
+
+/*
+ * @brief CLM callback for tracking node membership status.
+ * Depending upon the membership status (joining/leaving cluster)
+ * of a node, LGS will add or remove node from its data base.
+ * A node is added when it is part of the cluster and is removed
+ * when it leaves the cluster membership. An update of status is
+ * sent to the clients on that node. Based on this status LGA
+ * will decide return code for different API calls.
+ *
+ */
+static void lgs_clm_track_cbk(
+ const SaClmClusterNotificationBufferT_4 *notificationBuffer,
+ SaUint32T numberOfMembers, SaInvocationT invocation,
+ const SaNameT *rootCauseEntity,
+ const SaNtfCorrelationIdsT *correlationIds,
+ SaClmChangeStepT step, SaTimeT timeSupervision,
+ SaAisErrorT error) {
+
+ NODE_ID clm_node_id;
+ SaClmClusterChangesT clusterChange;
+ SaBoolT is_member;
+ uint32_t i = 0;
+
+ TRACE_ENTER2("'%llu' '%u' '%u'", invocation, step, error);
+ if (error != SA_AIS_OK) {
+ TRACE_1("Error received in ClmTrackCallback");
+ goto done;
+ }
+ clm_initialized = true;
+
+ for (i = 0; i < notificationBuffer->numberOfItems; i++) {
+ switch (step) {
+ case SA_CLM_CHANGE_COMPLETED:
+ is_member = notificationBuffer->notification[i].clusterNode.member;
+ clm_node_id = notificationBuffer->notification[i].clusterNode.nodeId;
+ if (lgs_clm_node_find(clm_node_id) == NCSCC_RC_SUCCESS) {
+ TRACE_1("'%x' is present in LGS db", clm_node_id);
+ if (!is_member) {
+ TRACE("CLM Node : %x Left the cluster", clm_node_id);
+ clusterChange = SA_CLM_NODE_LEFT;
+ if (lgs_clm_node_del(clm_node_id) == NCSCC_RC_SUCCESS) {
+ if (lgs_cb->ha_state == SA_AMF_HA_ACTIVE)
+ send_clm_node_status_change(clusterChange, clm_node_id);
+ }
+ }
+ } else {
+ TRACE_1("'%x' is not present in LGS db", clm_node_id);
+ if (is_member) {
+ TRACE("CLM Node : %x Joined the cluster", clm_node_id);
+ clusterChange = SA_CLM_NODE_JOINED;
+ if (lgs_clm_node_add(clm_node_id) == NCSCC_RC_SUCCESS) {
+ if (lgs_cb->ha_state == SA_AMF_HA_ACTIVE)
+ send_clm_node_status_change(clusterChange, clm_node_id);
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+done:
+ TRACE_LEAVE();
+ return;
+}
+
+/* saClmClusterTrackCallback */
+static const SaClmCallbacksT_4 clm_callbacks = {
+ 0,
+ lgs_clm_track_cbk
+};
+
+/*
+ * @brief Registers with the CLM service (B.04.01).
+ *
+ * @return SaAisErrorT
+ */
+void *lgs_clm_init_thread(void *cb) {
+ static SaVersionT clmVersion = { 'B', 0x04, 0x01 };
+ lgs_cb_t *_lgs_cb = reinterpret_cast<lgs_cb_t *> (cb);
+ SaAisErrorT rc;
+ TRACE_ENTER();
+ rc = saClmInitialize_4(&_lgs_cb->clm_hdl, &clm_callbacks, &clmVersion);
+ if (rc != SA_AIS_OK) {
+ LOG_ER("saClmInitialize failed with error: %d", rc);
+ TRACE_LEAVE();
+ exit(EXIT_FAILURE);
+ }
+ rc = saClmSelectionObjectGet(_lgs_cb->clm_hdl, &lgs_cb->clmSelectionObject);
+ if (rc != SA_AIS_OK) {
+ LOG_ER("saClmSelectionObjectGet failed with error: %d", rc);
+ TRACE_LEAVE();
+ exit(EXIT_FAILURE);
+ }
+
+ /* TODO:subscribe for SA_TRACK_START_STEP also. */
+ rc = saClmClusterTrack_4(_lgs_cb->clm_hdl,
+ (SA_TRACK_CURRENT | SA_TRACK_CHANGES), NULL);
+ if (rc != SA_AIS_OK) {
+ LOG_ER("saClmClusterTrack failed with error: %d", rc);
+ TRACE_LEAVE();
+ exit(EXIT_FAILURE);
+ }
+ TRACE("CLM Initialization SUCCESS......");
+ TRACE_LEAVE();
+ return NULL;
+}
+
+/*
+ * @brief Creates a thread to initialize with CLM.
+ */
+void lgs_init_with_clm(void) {
+ pthread_t thread;
+ pthread_attr_t attr;
+ TRACE_ENTER();
+
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+ if (pthread_create(&thread, &attr, lgs_clm_init_thread, lgs_cb) != 0) {
+ LOG_ER("pthread_create FAILED: %s", strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ pthread_attr_destroy(&attr);
+ TRACE_LEAVE();
+}
diff --git a/osaf/services/saf/logsv/lgs/lgs_clm.h
b/osaf/services/saf/logsv/lgs/lgs_clm.h
new file mode 100644
--- /dev/null
+++ b/osaf/services/saf/logsv/lgs/lgs_clm.h
@@ -0,0 +1,39 @@
+/* -*- OpenSAF -*-
+ *
+ * (C) Copyright 2016 The OpenSAF Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ * Author(s): Oracle
+ *
+ */
+
+#ifndef OSAF_SERVICES_SAF_LOGSV_LGS_LGS_CLM_H_
+#define OSAF_SERVICES_SAF_LOGSV_LGS_LGS_CLM_H_
+
+#include <saClm.h>
+#include <map>
+#include <utility>
+
+#define m_LGS_GET_NODE_ID_FROM_ADEST(adest) (NODE_ID) ((uint64_t)adest >> 32)
+
+typedef struct {
+ NODE_ID clm_node_id;
+} lgs_clm_node_t;
+
+/*
+ * @brief Creates a thread to initialize with CLM.
+ */
+extern void lgs_init_with_clm(void);
+extern bool is_client_clm_member(NODE_ID node_id, SaVersionT *ver);
+extern uint32_t lgs_clm_node_map_init(lgs_cb_t *lgs_cb);
+extern bool is_client_clm_member(NODE_ID node_id, SaVersionT *ver);
+
+#endif // OSAF_SERVICES_SAF_LOGSV_LGS_LGS_CLM_H_
diff --git a/osaf/services/saf/logsv/lgs/lgs_evt.cc
b/osaf/services/saf/logsv/lgs/lgs_evt.cc
--- a/osaf/services/saf/logsv/lgs/lgs_evt.cc
+++ b/osaf/services/saf/logsv/lgs/lgs_evt.cc
@@ -23,6 +23,7 @@
#include "lgs_mbcsv_v2.h"
#include "lgs_recov.h"
#include "lgs_imm_gcfg.h"
+#include "lgs_clm.h"
/* Macro to validate the version */
#define m_LOG_VER_IS_VALID(ver) \
@@ -583,6 +584,8 @@ uint32_t lgs_cb_init(lgs_cb_t *lgs_cb)
lgs_cb->amfSelectionObject = -1;
lgs_cb->immSelectionObject = -1;
lgs_cb->mbcsv_sel_obj = -1;
+ lgs_cb->clm_hdl = 0;
+ lgs_cb->clmSelectionObject = -1;
/* Assign Version. Currently, hardcoded, This will change later */
lgs_cb->log_version.releaseCode = LOG_RELEASE_CODE;
@@ -598,6 +601,12 @@ uint32_t lgs_cb_init(lgs_cb_t *lgs_cb)
if (NCSCC_RC_SUCCESS != ncs_patricia_tree_init(&lgs_cb->client_tree,
®_param))
return NCSCC_RC_FAILURE;
+ /* Initialize patricia tree for CLM Node list */
+ if (NCSCC_RC_SUCCESS != lgs_clm_node_map_init(lgs_cb)) {
+ LOG_ER("LGS: ncs_patricia_tree_init FAILED");
+ return NCSCC_RC_FAILURE;
+ }
+
done:
TRACE_LEAVE();
return rc;
@@ -637,6 +646,12 @@ static uint32_t proc_initialize_msg(lgs_
goto snd_rsp;
}
+ if (is_client_clm_member(evt->fr_node_id, version) != true){
+ ais_rc = SA_AIS_ERR_UNAVAILABLE;
+ TRACE("client not a CLM member FAILED");
+ goto snd_rsp;
+ }
+
if ((client = lgs_client_new(evt->fr_dest, 0, NULL)) == NULL) {
ais_rc = SA_AIS_ERR_NO_MEMORY;
goto snd_rsp;
diff --git a/osaf/services/saf/logsv/lgs/lgs_main.cc
b/osaf/services/saf/logsv/lgs/lgs_main.cc
--- a/osaf/services/saf/logsv/lgs/lgs_main.cc
+++ b/osaf/services/saf/logsv/lgs/lgs_main.cc
@@ -38,6 +38,7 @@
#include "osaf_utility.h"
#include "lgs_recov.h"
#include "immutil.h"
+#include "lgs_clm.h"
/* ========================================================================
* DEFINITIONS
@@ -49,6 +50,7 @@ enum {
FD_MBCSV,
FD_MBX,
FD_CLTIMER,
+ FD_CLM,
FD_IMM, /* Must be the last in the fds array */
FD_NUM
};
@@ -332,6 +334,13 @@ static uint32_t log_initialize(void)
goto done;
}
+ /* Create a CLM selection object */
+ if ((rc = ncs_sel_obj_create(&lgs_cb->clm_init_sel_obj)) !=
NCSCC_RC_SUCCESS)
+ {
+ LOG_ER("lgsv: CLM ncs_sel_obj_create failed");
+ goto done;
+ }
+
/*
* Initialize a signal handler that will use the selection object.
* The signal is sent from our script when AMF does instantiate.
@@ -501,6 +510,8 @@ int main(int argc, char *argv[])
fds[FD_IMM].fd = lgs_cb->immSelectionObject;
fds[FD_IMM].events = POLLIN;
+ lgs_cb->clmSelectionObject = lgs_cb->clm_init_sel_obj.rmv_obj;
+
while (1) {
if (cltimer_fd < 0 && log_rtobj_list_no() != 0) {
/* Needed only if any "lost" objects are found
@@ -513,6 +524,8 @@ int main(int argc, char *argv[])
fds[FD_CLTIMER].events = POLLIN;
fds[FD_MBCSV].fd = lgs_cb->mbcsv_sel_obj;
fds[FD_MBCSV].events = POLLIN;
+ fds[FD_CLM].fd = lgs_cb->clmSelectionObject;
+ fds[FD_CLM].events = POLLIN;
/* Protect since the reinit thread may be in the process of
* changing the values
@@ -567,6 +580,21 @@ int main(int argc, char *argv[])
}
}
+ if (fds[FD_CLM].revents & POLLIN) {
+ if (lgs_cb->clm_hdl != 0) {
+ if ((error = saClmDispatch(lgs_cb->clm_hdl,
SA_DISPATCH_ALL)) != SA_AIS_OK) {
+ LOG_ER("saClmDispatch failed: %u",
error);
+ break;
+ }
+ } else {
+ TRACE("init CLM ");
+ ncs_sel_obj_rmv_ind(&lgs_cb->clm_init_sel_obj,
true, true);
+ ncs_sel_obj_destroy(&lgs_cb->clm_init_sel_obj);
+ lgs_cb->clmSelectionObject = -1;
+ lgs_init_with_clm();
+ }
+ }
+
if (fds[FD_CLTIMER].revents & POLLIN) {
/* To avoid 'stray objects', after a timeout all runtime
* objects that has not been restored shall be deleted
diff --git a/osaf/services/saf/logsv/lgs/lgs_mds.cc
b/osaf/services/saf/logsv/lgs/lgs_mds.cc
--- a/osaf/services/saf/logsv/lgs/lgs_mds.cc
+++ b/osaf/services/saf/logsv/lgs/lgs_mds.cc
@@ -763,11 +763,19 @@ static uint32_t mds_enc(struct ncsmds_ca
goto err;
}
ncs_encode_32bit(&p8,
msg->info.cbk_info.write_cbk.error);
+ TRACE_8("LGSV_WRITE_LOG_CALLBACK_IND");
+ } else if (msg->info.cbk_info.type ==
LGSV_CLM_NODE_STATUS_CALLBACK) {
+ p8 = ncs_enc_reserve_space(uba, 4);
+ if (!p8) {
+ TRACE("ncs_enc_reserve_space failed");
+ goto err;
+ }
+ ncs_encode_32bit(&p8,
msg->info.cbk_info.clm_node_status_cbk.clm_node_status);
+ TRACE_8("LGSV_CLM_NODE_STATUS_CALLBACK");
} else {
TRACE("unknown callback type %d",
msg->info.cbk_info.type);
goto err;
}
- TRACE_8("LGSV_WRITE_LOG_CALLBACK_IND");
} else {
TRACE("unknown msg type %d", msg->type);
goto err;
@@ -1167,6 +1175,16 @@ static uint32_t mds_svc_event(struct ncs
osafassert(rc == NCSCC_RC_SUCCESS);
}
}
+ } else if (info->info.svc_evt.i_svc_id == NCSMDS_SVC_ID_AVD) {
+ if (info->info.svc_evt.i_change == NCSMDS_UP) {
+ TRACE_8("MDS UP dest: %" PRIx64 ", node ID: %x, svc_id:
%d",
+ info->info.svc_evt.i_dest,
info->info.svc_evt.i_node_id, info->info.svc_evt.i_svc_id);
+ //Subscribed for only INTRA NODE, only one ADEST will
come.
+ if (m_MDS_DEST_IS_AN_ADEST(info->info.svc_evt.i_dest)) {
+ TRACE_8("AVD ADEST UP");
+ ncs_sel_obj_ind(&lgs_cb->clm_init_sel_obj);
+ }
+ }
}
done:
@@ -1334,6 +1352,24 @@ uint32_t lgs_mds_init(lgs_cb_t *cb, SaAm
return rc;
}
+
+ svc = NCSMDS_SVC_ID_AVD;
+ /* Now subscribe for AVD events in MDS. This will be
+ used for CLM registration.*/
+ memset(&mds_info, '\0', sizeof(NCSMDS_INFO));
+ mds_info.i_mds_hdl = cb->mds_hdl;
+ mds_info.i_svc_id = NCSMDS_SVC_ID_LGS;
+ mds_info.i_op = MDS_SUBSCRIBE;
+ mds_info.info.svc_subscribe.i_scope = NCSMDS_SCOPE_INTRANODE;
+ mds_info.info.svc_subscribe.i_num_svcs = 1;
+ mds_info.info.svc_subscribe.i_svc_ids = &svc;
+
+ rc = ncsmds_api(&mds_info);
+ if (rc != NCSCC_RC_SUCCESS) {
+ LOG_ER("MDS for AVD subscribe FAILED");
+ return rc;
+ }
+
TRACE_LEAVE();
return rc;
}
------------------------------------------------------------------------------
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel