Hi Mahesh Ok thanks
Regards Lennart > -----Original Message----- > From: A V Mahesh [mailto:mahesh.va...@oracle.com] > Sent: den 10 augusti 2016 08:14 > 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: Re: [PATCH 2 of 4] lgs: director Cluster Membership (CLM) > integration [#1638] V4 > > Hi Lennar, > > On 8/8/2016 7:06 PM, Lennart Lund wrote: > >> +/** > >> >+ * 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! > > > [AVM] their is #1607 Ticket which is related ERROR handling related > enhancement, so I just added your comment as well in that tickets #1607 > to replace NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE with alternate macro, > if > we change now with different macros or digit , these change will remain > UN-uniform , > so for now I planing to keep as it is , so that while #1607 > addressing can easily find them . > > -AVM > > On 8/8/2016 7:06 PM, Lennart Lund wrote: > > 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; > >> } ------------------------------------------------------------------------------ What NetFlow Analyzer can do for you? Monitors network bandwidth and traffic patterns at an interface-level. Reveals which users, apps, and protocols are consuming the most bandwidth. Provides multi-vendor support for NetFlow, J-Flow, sFlow and other flows. Make informed decisions using capacity planning reports. http://sdm.link/zohodev2dev _______________________________________________ Opensaf-devel mailing list Opensaf-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/opensaf-devel