Hi Mahesh Ack for this part but with comments I really think should be fixed. See comments inline [Lennart]
Thanks Lennart > -----Original Message----- > From: mahesh.va...@oracle.com [mailto:mahesh.va...@oracle.com] > Sent: den 5 augusti 2016 14:58 > To: Lennart Lund <lennart.l...@ericsson.com>; Vu Minh Nguyen > <vu.m.ngu...@dektech.com.au>; Anders Widell > <anders.wid...@ericsson.com> > Cc: opensaf-devel@lists.sourceforge.net > Subject: [PATCH 2 of 4] lgs: director Cluster Membership (CLM) integration > [#1638] V4 > > osaf/services/saf/logsv/lgs/Makefile.am | 7 +- > osaf/services/saf/logsv/lgs/lgs_cb.h | 4 + > osaf/services/saf/logsv/lgs/lgs_clm.cc | 395 > ++++++++++++++++++++++++++++++++ > 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, 523 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 > @@ -68,7 +69,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 \ > @@ -76,4 +78,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> > > @@ -80,6 +81,8 @@ 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 > */ > 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 +97,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 */ > 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,395 @@ > +/* -*- 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; > +static void *clm_node_db; /* used for C++ STL map */ > +typedef std::map<NODE_ID, lgs_clm_node_t *> ClmNodeMap; > + > +/** > + * @brief Checks if LGSV has already initialized with CLM service. > + * > + * @return true/false. > + */ > + static 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 > + */ [Lennart] NOTE: This function is not a NCS function and should therefore not use NCS error codes. Unfortunate this is commonly done all over the code but it would be good not to add more of this! > +uint32_t lgs_clm_node_map_init(lgs_cb_t *lgs_cb) { > + TRACE_ENTER(); > + if (clm_node_db) { > + TRACE("CLM Node map already exists"); > + return NCSCC_RC_FAILURE; > + } > + > + clm_node_db = new ClmNodeMap; > + TRACE_LEAVE(); > + return NCSCC_RC_SUCCESS; > +} > + > + > +/** > + * 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 > + */ > +static uint32_t lgs_clm_node_find(NODE_ID clm_node_id) { > + TRACE_ENTER(); > + uint32_t rc; > + > + ClmNodeMap *clmNodeMap(reinterpret_cast<ClmNodeMap *> > + (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 > + */ > +static uint32_t lgs_clm_node_add(NODE_ID clm_node_id) { > + TRACE_ENTER(); > + uint32_t rc; > + lgs_clm_node_t *clm_node; > + > + clm_node = new lgs_clm_node_t(); > + > + clm_node->clm_node_id = clm_node_id; > + > + ClmNodeMap *clmNodeMap(reinterpret_cast<ClmNodeMap *> > + (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. > + */ > +static uint32_t lgs_clm_node_del(NODE_ID clm_node_id) { > + TRACE_ENTER(); > + uint32_t rc; > + lgs_clm_node_t *clm_node; > + > + ClmNodeMap *clmNodeMap(reinterpret_cast<ClmNodeMap *> > + (clm_node_db)); > + > + if (clmNodeMap) { > + auto it = (clmNodeMap->find(clm_node_id)); > + > + if (it != clmNodeMap->end()) { > + clm_node = it->second; > + clmNodeMap->erase(it); > + delete clm_node; > + 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. > + */ > +static 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. > + */ > +static 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; > +} > + > +static 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. > + */ > +void lgs_init_with_clm(void); > +bool is_client_clm_member(NODE_ID node_id, SaVersionT *ver); > +uint32_t lgs_clm_node_map_init(lgs_cb_t *lgs_cb); > +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 > @@ -24,6 +24,7 @@ > #include "lgs_recov.h" > #include "lgs_imm_gcfg.h" > #include "osaf_extended_name.h" > +#include "lgs_clm.h" > > /* Macro to validate the version */ > #define m_LOG_VER_IS_VALID(ver) \ > @@ -582,6 +583,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; > @@ -597,6 +600,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 CLM Node map*/ > + if (NCSCC_RC_SUCCESS != lgs_clm_node_map_init(lgs_cb)) { > + LOG_ER("LGS: ncs_patricia_tree_init FAILED"); [Lennart] No patricia tree is initiated here. Fix error message > + return NCSCC_RC_FAILURE; [Lennart] Returning without passing TRACE_LEAVE(). Here the common usage of "goto done" could be used (also see above). This actually done in other part of this function. > + } > + > done: > TRACE_LEAVE(); > return rc; > @@ -636,6 +645,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. > @@ -506,6 +515,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 > @@ -518,6 +529,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 > @@ -572,6 +585,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 > @@ -845,11 +845,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; > @@ -1249,6 +1257,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: > @@ -1416,6 +1434,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; > + } > + [Lennart] I still think an explanation is motivated, at least here. But I think that some information in README is in place (with a maintainer as intended reader). It is not obvious that this is done in order to delay initiation of CLM, why this is needed and the thinking behind how it is done > TRACE_LEAVE(); > return rc; > } ------------------------------------------------------------------------------ _______________________________________________ Opensaf-devel mailing list Opensaf-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/opensaf-devel