Hi Lennar, I just incorporated possible comments based on the current code base, This My fist patch for LOG :) , so I just followed how existing functions/variables organized like.
I will considered all other inputs while doing complete refracting code to C++ in a separate ticket soon. Please see also inline response [AVM] -AVM On 8/2/2016 6:30 PM, Lennart Lund wrote: > Hi > > My comments for patch 2 > > I have found some things that should be considered in order to get as clean > code as possible: > 1. > Functions for handling CLM can be found in several files. It is better to > collect all CLM handling in the lgs_clm file and just include function calls > in the rest of the code. Also all functions that shall be globally available > should have a prototype in the corresponding lgs_clm.h file [AVM] I will considered all your inputs while doing complete refracting code to C++ in a separate ticket soon. > 2. > New global variables are added to the cb structure. Do not use global > variables try at least to keep the scope of state variables, flags and other > variables within the lgs_clm file. Implement setter and getter functions if > needed or even better functions that are using the variables e.g. like the > is_client_clm_member() function. This also makes it possible to make these > functions thread safe (do not use the global cb lock mutex). which means > that this can be handled in one place instead of all over the code [AVM] I moved the stuff that is possible based on current code base of LOG service , i will take care of your suggestions while doing complete refracting code to C++ in a separate ticket soon. > 3. > Take advantage of C++ and make simpler handling of lists. It's no longer > needed to use patricia tree handling > Maybe even create a LgsClm class? [AVM] Same comment was give by Anders Widell as well. I will do all NCS_PATRICIA_TREE conversion to std::map of Log service in one go in a separate ticket soon. > > See also inline comments [Lennart] > > Thanks > Lennart > >> -----Original Message----- >> From: mahesh.va...@oracle.com [mailto:mahesh.va...@oracle.com] >> Sent: den 2 augusti 2016 10:18 >> To: Vu Minh Nguyen <vu.m.ngu...@dektech.com.au>; Lennart Lund >> <lennart.l...@ericsson.com>; Anders Widell <anders.wid...@ericsson.com> >> Cc: opensaf-devel@lists.sourceforge.net >> Subject: [PATCH 2 of 3] lgs: director Cluster Membership (CLM) integration >> [#1638] V2 >> >> osaf/services/saf/logsv/lgs/Makefile.am | 7 +- >> osaf/services/saf/logsv/lgs/lgs_cb.h | 15 +++ >> osaf/services/saf/logsv/lgs/lgs_clm.cc | 142 >> +++++++++++++++++++++++++++++++ >> osaf/services/saf/logsv/lgs/lgs_clm.h | 25 +++++ >> osaf/services/saf/logsv/lgs/lgs_evt.cc | 143 >> ++++++++++++++++++++++++++++++++ >> osaf/services/saf/logsv/lgs/lgs_evt.h | 2 + >> osaf/services/saf/logsv/lgs/lgs_main.cc | 28 ++++++ >> osaf/services/saf/logsv/lgs/lgs_mds.cc | 38 ++++++++- >> osaf/services/saf/logsv/lgs/lgs_util.cc | 83 ++++++++++++++++++ >> 9 files changed, 480 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> >> >> @@ -55,6 +56,11 @@ typedef struct lgs_stream_list { >> } lgs_stream_list_t; >> >> typedef struct { >> + NCS_PATRICIA_NODE patnode; >> + NODE_ID node_id; >> +} lgs_clm_node_t; >> + > [Lennart] Would it be possible to not add new patricia node handling? Since > the log service is compiled as C++ code C++ list tools could be used instead? > lgs_clm_node_find [AVM] Same comment was give by Anders Widell as well. I will do all NCS_PATRICIA_TREE conversion to std::map of Log service in one go in a separate ticket soon. >> +typedef struct { >> NCS_PATRICIA_NODE pat_node; >> uint32_t client_id; >> uint32_t client_id_net; >> @@ -73,6 +79,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 */ >> + NCS_PATRICIA_TREE clm_node_tree; /* LGA/Library/Client >> instantiation pat. tree */ >> 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 +87,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; > [Lennart] Why adding new globals? At least this one is not needed. This > variable could be declared locally in lgs_clm.cc only if the is_clm_init() > function is moved from lgs_util.cc to lgs_clm.cc. Try to keep CLM handling > code in one place (could be a class) and avoid global varaibles (avoid using > the cb structure as an all-purpose "slask" global if possible) [AVM] clm_initialized is Agent wide information this will used future purposes like all services concurrently starting ect.. >> 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 +104,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 +117,9 @@ 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); >> +extern bool is_client_clm_member(NODE_ID node_id, SaVersionT *ver); > [Lennart] Does the function protoypes really belongs here? The code can be > found in lgs_evt.cc and lgs_util.cc but probably belongs to the lgs_clm.cc > file and the prototypes should be in the lgs_clm.h file? [AVM] Moved. > >> #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,142 @@ >> +/* -*- 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 "lgs.h" >> +#include "lgs_clm.h" >> + >> +/* >> + * @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 node_id; >> + SaClmClusterChangesT cluster_change; >> + 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; >> + } >> + lgs_cb->clm_initialized = true; >> + >> + for (i = 0; i < notificationBuffer->numberOfItems; i++) { >> + switch(step) { >> + case SA_CLM_CHANGE_COMPLETED: >> + is_member = notificationBuffer- >>> notification[i].clusterNode.member; >> + node_id = notificationBuffer- >>> notification[i].clusterNode.nodeId; >> + if (lgs_clm_node_find(node_id) == >> NCSCC_RC_SUCCESS) { >> + TRACE_1("'%x' is present in LGS db", >> node_id); >> + if (!is_member) { >> + TRACE("CLM Node : %x Left >> the cluster", node_id); >> + cluster_change = >> SA_CLM_NODE_LEFT; >> + if >> (lgs_clm_node_del(node_id) == NCSCC_RC_SUCCESS){ >> + if (lgs_cb->ha_state >> == SA_AMF_HA_ACTIVE) >> + >> send_clm_node_status_change(cluster_change, node_id); >> + } >> + } >> + } else { >> + TRACE_1("'%x' is not present in LGS >> db", node_id); >> + if (is_member) { >> + TRACE("CLM Node : %x >> Joined the cluster", node_id); >> + cluster_change = >> SA_CLM_NODE_JOINED; >> + >> if(lgs_clm_node_add(node_id) == NCSCC_RC_SUCCESS) { >> + if (lgs_cb->ha_state >> == SA_AMF_HA_ACTIVE) >> + >> send_clm_node_status_change(cluster_change, node_id); >> + } >> + } >> + } >> + break; >> + default: >> + break; >> + } >> + } >> +done: >> + TRACE_LEAVE(); >> + return; >> +} >> + >> +static const SaClmCallbacksT_4 clm_callbacks = { >> + 0, >> + lgs_clm_track_cbk /*saClmClusterTrackCallback*/ >> +}; >> + >> +/* >> + * @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 = (lgs_cb_t *) cb; >> + SaAisErrorT rc = SA_AIS_OK; >> + 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,25 @@ >> +/* -*- 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 <saClm.h> >> + >> +#define m_LGS_GET_NODE_ID_FROM_ADEST(adest) (NODE_ID) >> ((uint64_t)adest >> 32) >> + >> +/* >> + * @brief Creates a thread to initialize with CLM. >> + */ >> +void lgs_init_with_clm(void); >> 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) \ >> @@ -56,6 +57,94 @@ LGSV_LGS_LGA_API_MSG_HANDLER lgs_lga_api >> }; >> >> /** >> + * Name : lgs_clm_node_tree_init >> + * Description : This routine is used to initialize the clm_node_tree >> + * Arguments : lgs_cb - pointer to the lgs Control Block >> + * Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE >> + * Notes : None >> + */ >> +uint32_t lgs_clm_node_tree_init(lgs_cb_t *lgs_cb) >> +{ >> + TRACE_ENTER(); >> + NCS_PATRICIA_PARAMS param; >> + memset(¶m, 0, sizeof(NCS_PATRICIA_PARAMS)); >> + >> + param.key_size = sizeof(NODE_ID); >> + if (ncs_patricia_tree_init(&lgs_cb->clm_node_tree, ¶m) != >> NCSCC_RC_SUCCESS) { >> + LOG_ER("lgs patricia tee init failed for clm_node_tree"); >> + return NCSCC_RC_FAILURE; >> + } >> + TRACE_LEAVE(); >> + return NCSCC_RC_SUCCESS; >> +} >> + >> +/** >> + * Name : lgs_clm_node_find >> + * Description : This routine finds the clm_node . >> + * Arguments : node_id - CLM Node id >> + * Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE >> + * Notes : None >> + */ >> +uint32_t lgs_clm_node_find(NODE_ID node_id) >> +{ >> + uint32_t rc = NCSCC_RC_FAILURE; >> + lgs_clm_node_t *clm_node = (lgs_clm_node_t *) >> + ncs_patricia_tree_get(&lgs_cb->clm_node_tree, (uint8_t >> *)&node_id); >> + >> + if (clm_node != NULL) >> + rc = NCSCC_RC_SUCCESS; >> + else >> + TRACE("node_id find in DB failed : %x",node_id); >> + >> + return rc; >> +} >> + >> +/** >> + * Name : lgs_clm_node_add >> + * Description : This routine adds the new node to clm_node_tree. >> + * Arguments : node_id - CLM Node id >> + * Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE >> + * Notes : None >> + */ >> +uint32_t lgs_clm_node_add(NODE_ID node_id) >> +{ >> + TRACE_ENTER(); >> + uint32_t rc = NCSCC_RC_FAILURE; >> + lgs_clm_node_t *clm_node; >> + >> + clm_node = (lgs_clm_node_t *) malloc(sizeof(lgs_clm_node_t)); >> + clm_node->node_id = node_id; >> + clm_node->patnode.key_info = (uint8_t *)&clm_node->node_id; >> + rc = ncs_patricia_tree_add(&lgs_cb->clm_node_tree, >> (NCS_PATRICIA_NODE *)&clm_node->patnode); >> + if (rc != NCSCC_RC_SUCCESS) >> + TRACE("node_id add to DB failed : %x",node_id); >> + TRACE_LEAVE(); >> + return rc; >> +} >> + >> +/** >> + * Name : lgs_clm_node_del >> + * Description : Function to Delete the clm_node. >> + * Arguments : node_id - CLM Node id >> + * Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE >> + * Notes : None. >> + */ >> +uint32_t lgs_clm_node_del(NODE_ID node_id) >> +{ >> + TRACE_ENTER(); >> + uint32_t rc = NCSCC_RC_FAILURE; >> + >> + lgs_clm_node_t *clm_node = (lgs_clm_node_t *) >> + ncs_patricia_tree_get(&lgs_cb->clm_node_tree, (uint8_t >> *)&node_id); >> + if (clm_node != NULL) >> + rc = ncs_patricia_tree_del(&lgs_cb->clm_node_tree, >> (NCS_PATRICIA_NODE *)&clm_node->patnode); >> + if (rc != NCSCC_RC_SUCCESS) >> + TRACE("node_id delete to DB failed : %x",node_id); >> + TRACE_LEAVE(); >> + return rc; >> +} >> + >> +/** >> * Get client record from client ID >> * @param client_id >> * >> @@ -583,6 +672,9 @@ 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->clm_initialized = false; >> + lgs_cb->clmSelectionObject = -1; >> >> /* Assign Version. Currently, hardcoded, This will change later */ >> lgs_cb->log_version.releaseCode = LOG_RELEASE_CODE; >> @@ -598,6 +690,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_tree_init(lgs_cb)) { >> + LOG_ER("LGS: ncs_patricia_tree_init FAILED"); >> + return NCSCC_RC_FAILURE; >> + } >> + >> done: >> TRACE_LEAVE(); >> return rc; >> @@ -637,6 +735,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; >> @@ -1451,3 +1555,42 @@ void lgs_process_mbx(SYSF_MBX *mbx) >> lgs_evt_destroy(msg); >> } >> } >> + >> +/** >> + * @brief Sends CLM membership status of the node to all the clients >> + * on the node except A11 clients. >> + * @param cluster_change (CLM membership status of node). >> + * @param NCS node_id. >> + * @return NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE. >> + */ >> +uint32_t >> send_cluster_membership_msg_to_clients(SaClmClusterChangesT >> cluster_change, NODE_ID node_id) { >> + uint32_t rc = NCSCC_RC_SUCCESS; >> + log_client_t *rp = NULL; >> + uint32_t client_id_net; >> + >> + TRACE_ENTER(); >> + TRACE_3("node_id: %x, change:%u", node_id, cluster_change); >> + >> + 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_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_node_id == node_id) >> + rc = send_clm_node_status_lib(cluster_change, 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 >> cluster_change, NODE_ID node_id) { >> + return (send_cluster_membership_msg_to_clients(cluster_change, >> node_id)); >> + >> +} >> + >> diff --git a/osaf/services/saf/logsv/lgs/lgs_evt.h >> b/osaf/services/saf/logsv/lgs/lgs_evt.h >> --- a/osaf/services/saf/logsv/lgs/lgs_evt.h >> +++ b/osaf/services/saf/logsv/lgs/lgs_evt.h >> @@ -77,6 +77,8 @@ extern bool lgs_lga_entry_valid(lgs_cb_t >> extern uint32_t lgs_remove_lga_down_rec(lgs_cb_t *cb, MDS_DEST >> mds_dest); >> extern void lgs_send_write_log_ack(uint32_t client_id, SaInvocationT >> invocation, SaAisErrorT error, MDS_DEST mds_dest); >> extern void lgs_free_write_log(const lgsv_write_log_async_req_t *param); >> +extern uint32_t send_clm_node_status_lib(SaClmClusterChangesT >> cluster_change, unsigned int client_id, MDS_DEST mdsDest); >> +extern uint32_t send_clm_node_status_change(SaClmClusterChangesT >> cluster_change, NODE_ID node_id); >> >> SaAisErrorT create_new_app_stream( >> lgsv_stream_open_req_t *open_sync_param, >> 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; >> } >> diff --git a/osaf/services/saf/logsv/lgs/lgs_util.cc >> b/osaf/services/saf/logsv/lgs/lgs_util.cc >> --- a/osaf/services/saf/logsv/lgs/lgs_util.cc >> +++ b/osaf/services/saf/logsv/lgs/lgs_util.cc >> @@ -415,6 +415,89 @@ void lgs_send_write_log_ack(uint32_t cli >> } >> >> /** >> + * @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 >> cluster_change, unsigned int client_id, MDS_DEST mdsDest) >> +{ >> + uint32_t rc = NCSCC_RC_SUCCESS; >> + NCSMDS_INFO mds_info = {0}; >> + lgsv_msg_t msg; >> + >> + TRACE_ENTER(); >> + TRACE_3("change:%u, client_id: %u", cluster_change, 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 = >> cluster_change; >> + >> + 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 Checks if LGSV has already initialized with CLM service. >> + * >> + * @return true/false. >> + */ >> +bool is_clm_init() >> +{ >> + return (((lgs_cb->clm_hdl != 0) && (lgs_cb->clm_initialized == >> true)) ? >> true : false); >> +} >> + >> +/** >> + * @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 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(node_id) != NCSCC_RC_SUCCESS) >> + return false; >> + else >> + return true; >> +} >> + >> + >> + >> +/** >> * Free all dynamically allocated memory for a WRITE >> * @param param >> */ ------------------------------------------------------------------------------ _______________________________________________ Opensaf-devel mailing list Opensaf-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/opensaf-devel