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; + +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; 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); #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