This is after applying the patch that handles TRY_AGAIN. Also, this patch should get tested after enabling spares(and admin ops around that), i think. Your call as the maintainer.
Thanks, Mathi. On Tue, May 9, 2017 at 11:31 PM, Mathi N P <[email protected]> wrote: > Hi Alex, > > Good work. Ack for patch 1 with some minor comments. > > 1) + ver.releaseCode > 'B') > This condition could be changed to >= ? > > 2) + if (notificationBuffer->notification[i].clusterChange == > SA_CLM_NODE_LEFT) { > > Just a thought ,I think its possible for a node to become unconfigured too? > But perhaps, the usecase would be via a node lock or shutdown which would > eventually translate to NODE_LEFT. > So, i guesss it is okay to handle only SA_CLM_NODE_LEFT only. > > 3) + SaVersionT version = { 'B', 4, 0 }; > > The minor version is irrelevant, but may be we could use use the currently > supported minor version, instead of 0. > > 4) + if (m_GLA_VER_IS_AT_LEAST_B_3(client_info->version) && > > This is a generic comment about use of macros. May be we could begin to > move away from such macros. > But, i understand GLSv is one of those services still heavily using macros. > > Cheers, > Mathi. > > > On Wed, Apr 12, 2017 at 6:43 PM, Alex Jones <[email protected]> > wrote: > >> This patch integrates LCK with CLM. >> --- >> src/lck/Makefile.am | 8 +- >> src/lck/agent/gla_api.c | 96 +++++++++++++++++ >> src/lck/agent/gla_cb.h | 4 + >> src/lck/agent/gla_evt.h | 11 +- >> src/lck/agent/gla_init.c | 27 +++++ >> src/lck/agent/gla_mds.c | 56 ++++++++++ >> src/lck/common/glsv_defs.h | 9 +- >> src/lck/lckd/gld_api.c | 29 ++++- >> src/lck/lckd/gld_cb.h | 2 +- >> src/lck/lckd/gld_clm.cc | 131 +++++++++++++++++++++++ >> src/lck/lckd/gld_clm.h | 17 +++ >> src/lck/lckd/gld_evt.c | 115 +++++++++++--------- >> src/lck/lckd/gld_evt.h | 16 +++ >> src/lck/lcknd/glnd_agent.c | 23 ++++ >> src/lck/lcknd/glnd_api.c | 35 ++++-- >> src/lck/lcknd/glnd_cb.c | 10 ++ >> src/lck/lcknd/glnd_cb.h | 12 +++ >> src/lck/lcknd/glnd_client.c | 92 ++++++++++++++++ >> src/lck/lcknd/glnd_client.h | 10 ++ >> src/lck/lcknd/glnd_clm.cc | 183 +++++++++++++++++++++++++++++++ >> src/lck/lcknd/glnd_clm.h | 17 +++ >> src/lck/lcknd/glnd_evt.c | 250 ++++++++++++++++++++++++++++++ >> +++++++------ >> src/lck/lcknd/glnd_mds.c | 39 +++++++ >> src/lck/lcknd/glnd_mds.h | 8 ++ >> src/lck/lcknd/glnd_res.c | 4 + >> src/lck/lcknd/glnd_res_req.c | 50 +++++++++ >> 26 files changed, 1159 insertions(+), 95 deletions(-) >> create mode 100644 src/lck/lckd/gld_clm.cc >> create mode 100644 src/lck/lckd/gld_clm.h >> create mode 100644 src/lck/lcknd/glnd_clm.cc >> create mode 100644 src/lck/lcknd/glnd_clm.h >> >> diff --git a/src/lck/Makefile.am b/src/lck/Makefile.am >> index b7fb47b..fe8a34c 100644 >> --- a/src/lck/Makefile.am >> +++ b/src/lck/Makefile.am >> @@ -152,11 +152,13 @@ bin_osaflcknd_SOURCES = \ >> src/lck/lcknd/glnd_res_req.c \ >> src/lck/lcknd/glnd_restart.c \ >> src/lck/lcknd/glnd_shm.c \ >> - src/lck/lcknd/glnd_tmr.c >> + src/lck/lcknd/glnd_tmr.c \ >> + src/lck/lcknd/glnd_clm.cc >> >> bin_osaflcknd_LDADD = \ >> lib/liblck_common.la \ >> lib/libSaAmf.la \ >> + lib/libSaClm.la \ >> lib/libopensaf_core.la >> >> bin_osaflckd_CPPFLAGS = \ >> @@ -175,11 +177,13 @@ bin_osaflckd_SOURCES = \ >> src/lck/lckd/gld_red.c \ >> src/lck/lckd/gld_rsc.c \ >> src/lck/lckd/gld_standby.c \ >> - src/lck/lckd/gld_tmr.c >> + src/lck/lckd/gld_tmr.c \ >> + src/lck/lckd/gld_clm.cc >> >> bin_osaflckd_LDADD = \ >> lib/liblck_common.la \ >> lib/libSaAmf.la \ >> + lib/libSaClm.la \ >> lib/libosaf_common.la \ >> lib/libSaImmOi.la \ >> lib/libSaImmOm.la \ >> diff --git a/src/lck/agent/gla_api.c b/src/lck/agent/gla_api.c >> index 539c71b..dbe75cd 100644 >> --- a/src/lck/agent/gla_api.c >> +++ b/src/lck/agent/gla_api.c >> @@ -145,6 +145,9 @@ SaAisErrorT saLckInitialize(SaLckHandleT *lckHandle, >> } >> rc = out_evt->error; >> if (rc == SA_AIS_OK) { >> + /* if the call succeeds we know glnd is a member of the cluster */ >> + gla_cb->isClusterMember = true; >> + >> /* create the client node and populate it */ >> client_info = >> gla_client_tree_find_and_add(gla_cb, >> out_evt->handle, true); >> @@ -154,6 +157,9 @@ SaAisErrorT saLckInitialize(SaLckHandleT *lckHandle, >> goto err; >> } >> >> + client_info->isStale = false; >> + memcpy(&client_info->version, version, sizeof(SaVersionT)); >> + >> /* copy the callbacks */ >> if (lckCallbacks) >> memcpy((void *)&client_info->lckCallbk, >> @@ -259,6 +265,14 @@ SaAisErrorT saLckSelectionObjectGet(SaLckHandleT >> lckHandle, >> goto done; >> } >> >> + /* are we a member of the cluster? */ >> + if (m_GLA_VER_IS_AT_LEAST_B_3(client_info->version)) { >> + if (!gla_cb->isClusterMember || client_info->isStale) { >> + rc = SA_AIS_ERR_UNAVAILABLE; >> + goto done; >> + } >> + } >> + >> /* everything's fine.. pass the sel obj to the appl */ >> *o_sel_obj = (SaSelectionObjectT)m_GET_FD_FROM_SEL_OBJ( >> m_NCS_IPC_GET_SEL_OBJ(&client_info->callbk_mbx)); >> @@ -319,6 +333,14 @@ SaAisErrorT saLckOptionCheck(SaLckHandleT hdl, >> SaLckOptionsT *lckOptions) >> goto done; >> } >> >> + /* are we a member of the cluster? */ >> + if (m_GLA_VER_IS_AT_LEAST_B_3(client_info->version)) { >> + if (!gla_cb->isClusterMember || client_info->isStale) { >> + rc = SA_AIS_ERR_UNAVAILABLE; >> + goto done; >> + } >> + } >> + >> /* populate the options - as this implementation support both >> Deadlock >> and orphan , set the values */ >> *lckOptions = SA_LCK_OPT_ORPHAN_LOCKS | >> SA_LCK_OPT_DEADLOCK_DETECTION; >> @@ -377,6 +399,14 @@ SaAisErrorT saLckDispatch(SaLckHandleT lckHandle, >> const SaDispatchFlagsT flags) >> goto done; >> } >> >> + /* are we a member of the cluster? */ >> + if (m_GLA_VER_IS_AT_LEAST_B_3(client_info->version)) { >> + if (!gla_cb->isClusterMember || client_info->isStale) { >> + rc = SA_AIS_ERR_UNAVAILABLE; >> + goto done; >> + } >> + } >> + >> switch (flags) { >> case SA_DISPATCH_ONE: >> rc = gla_hdl_callbk_dispatch_one(gla_cb, client_info); >> @@ -599,6 +629,14 @@ SaAisErrorT saLckResourceOpen(SaLckHandleT lckHandle, >> goto done; >> } >> >> + /* are we a member of the cluster? */ >> + if (m_GLA_VER_IS_AT_LEAST_B_3(client_info->version)) { >> + if (!gla_cb->isClusterMember || client_info->isStale) { >> + rc = SA_AIS_ERR_UNAVAILABLE; >> + goto done; >> + } >> + } >> + >> /* check whether GLND is up or not */ >> if (!gla_cb->glnd_svc_up) { >> ncshm_give_hdl(client_info->lcl_lock_handle_id); >> @@ -763,6 +801,15 @@ SaAisErrorT saLckResourceOpenAsync(SaLckHandleT >> lckHandle, >> rc = SA_AIS_ERR_INIT; >> goto done; >> } >> + >> + /* are we a member of the cluster? */ >> + if (m_GLA_VER_IS_AT_LEAST_B_3(client_info->version)) { >> + if (!gla_cb->isClusterMember || client_info->isStale) { >> + rc = SA_AIS_ERR_UNAVAILABLE; >> + goto done; >> + } >> + } >> + >> /* check whether GLND is up or not */ >> if (!gla_cb->glnd_svc_up) { >> ncshm_give_hdl(client_info->lcl_lock_handle_id); >> @@ -887,6 +934,14 @@ SaAisErrorT saLckResourceClose(SaLckResourceHandleT >> lockResourceHandle) >> goto done; >> } >> >> + /* are we a member of the cluster? */ >> + if (m_GLA_VER_IS_AT_LEAST_B_3(client_info->version)) { >> + if (!gla_cb->isClusterMember || client_info->isStale) { >> + rc = SA_AIS_ERR_UNAVAILABLE; >> + goto done; >> + } >> + } >> + >> /* check whether GLND is up or not */ >> if (!gla_cb->glnd_svc_up) { >> ncshm_give_hdl(lockResourceHandle); >> @@ -1060,6 +1115,15 @@ SaAisErrorT saLckResourceLock(SaLckResourceHandleT >> lockResourceHandle, >> rc = SA_AIS_ERR_BAD_HANDLE; >> goto done; >> } >> + >> + /* are we a member of the cluster? */ >> + if (m_GLA_VER_IS_AT_LEAST_B_3(client_info->version)) { >> + if (!gla_cb->isClusterMember || client_info->isStale) { >> + rc = SA_AIS_ERR_UNAVAILABLE; >> + goto done; >> + } >> + } >> + >> /* check whether GLND is up or not */ >> if (!gla_cb->glnd_svc_up) { >> ncshm_give_hdl(lockResourceHandle); >> @@ -1252,6 +1316,14 @@ SaAisErrorT >> saLckResourceLockAsync(SaLckResourceHandleT >> lockResourceHandle, >> goto done; >> } >> >> + /* are we a member of the cluster? */ >> + if (m_GLA_VER_IS_AT_LEAST_B_3(client_info->version)) { >> + if (!gla_cb->isClusterMember || client_info->isStale) { >> + rc = SA_AIS_ERR_UNAVAILABLE; >> + goto done; >> + } >> + } >> + >> /* check whether GLND is up or not */ >> if (!gla_cb->glnd_svc_up) { >> ncshm_give_hdl(lockResourceHandle); >> @@ -1409,6 +1481,14 @@ SaAisErrorT saLckResourceUnlock(SaLckLockIdT >> lockId, SaTimeT timeout) >> goto done; >> } >> >> + /* are we a member of the cluster? */ >> + if (m_GLA_VER_IS_AT_LEAST_B_3(client_info->version)) { >> + if (!gla_cb->isClusterMember || client_info->isStale) { >> + rc = SA_AIS_ERR_UNAVAILABLE; >> + goto done; >> + } >> + } >> + >> /* check whether GLND is up or not */ >> if (!gla_cb->glnd_svc_up) { >> ncshm_give_hdl(lockId); >> @@ -1548,6 +1628,14 @@ SaAisErrorT saLckResourceUnlockAsync(SaInvocationT >> invocation, >> goto done; >> } >> >> + /* are we a member of the cluster? */ >> + if (m_GLA_VER_IS_AT_LEAST_B_3(client_info->version)) { >> + if (!gla_cb->isClusterMember || client_info->isStale) { >> + rc = SA_AIS_ERR_UNAVAILABLE; >> + goto done; >> + } >> + } >> + >> /* check whether GLND is up or not */ >> if (!gla_cb->glnd_svc_up) { >> ncshm_give_hdl(lockId); >> @@ -1671,6 +1759,14 @@ SaAisErrorT saLckLockPurge(SaLckResourceHandleT >> lockResourceHandle) >> goto done; >> } >> >> + /* are we a member of the cluster? */ >> + if (m_GLA_VER_IS_AT_LEAST_B_3(client_info->version)) { >> + if (!gla_cb->isClusterMember || client_info->isStale) { >> + rc = SA_AIS_ERR_UNAVAILABLE; >> + goto done; >> + } >> + } >> + >> /* check whether GLND is up or not */ >> if (!gla_cb->glnd_svc_up) { >> ncshm_give_hdl(lockResourceHandle); >> diff --git a/src/lck/agent/gla_cb.h b/src/lck/agent/gla_cb.h >> index 961c252..c99e0ac 100644 >> --- a/src/lck/agent/gla_cb.h >> +++ b/src/lck/agent/gla_cb.h >> @@ -40,6 +40,8 @@ typedef struct gla_client_info_tag { >> uint32_t client_context_id; >> SaLckCallbacksT lckCallbk; >> SaTimeT lcktimer; >> + bool isStale; >> + SaVersionT version; >> /* Mailbox Queue to store the messages for the clients */ >> SYSF_MBX callbk_mbx; >> NCS_PATRICIA_TREE client_res_tree; >> @@ -108,6 +110,7 @@ typedef struct gla_cb_tag { >> MDS_DEST glnd_mds_dest; >> bool glnd_svc_up; >> bool glnd_crashed; >> + bool isClusterMember; >> >> /* GLA data */ >> NCS_PATRICIA_TREE gla_client_tree; /* GLA_CLIENT_INFO - node */ >> @@ -134,6 +137,7 @@ void gla_client_tree_destroy(GLA_CB *gla_cb); >> void gla_client_tree_cleanup(GLA_CB *gla_cb); >> GLA_CLIENT_INFO *gla_client_tree_find_and_add(GLA_CB *gla_cb, >> SaLckHandleT hdl_id, bool >> flag); >> +GLA_CLIENT_INFO *gla_client_tree_find_next(GLA_CB *gla_cb, SaLckHandleT >> hdl_id); >> uint32_t gla_client_tree_delete_node(GLA_CB *gla_cb, >> GLA_CLIENT_INFO *client_info, >> bool give_hdl); >> diff --git a/src/lck/agent/gla_evt.h b/src/lck/agent/gla_evt.h >> index 3b341d2..864bdf1 100644 >> --- a/src/lck/agent/gla_evt.h >> +++ b/src/lck/agent/gla_evt.h >> @@ -34,6 +34,7 @@ >> typedef enum glsv_gla_evt_type { >> GLSV_GLA_CALLBK_EVT, >> GLSV_GLA_API_RESP_EVT, >> + GLSV_GLA_CLM_EVT, >> GLSV_GLA_EVT_MAX >> } GLSV_GLA_EVT_TYPE; >> >> @@ -45,7 +46,9 @@ typedef enum glsv_gla_api_resp_evt_type_tag { >> GLSV_GLA_LOCK_SYNC_LOCK, >> GLSV_GLA_LOCK_SYNC_UNLOCK, >> GLSV_GLA_NODE_OPERATIONAL, >> - GLSV_GLA_LOCK_PURGE >> + GLSV_GLA_LOCK_PURGE, >> + GLSV_GLA_NODE_LEFT, >> + GLSV_GLA_NODE_JOINED >> } GLSV_GLA_API_RESP_EVT_TYPE; >> >> typedef struct glsv_gla_evt_lock_initialise_param_tag { >> @@ -87,6 +90,11 @@ typedef struct glsv_gla_api_resp_info { >> } param; >> } GLSV_GLA_API_RESP_INFO; >> >> +/* CLM param definitions */ >> +typedef struct glsv_gla_clm_info { >> + bool isClusterMember; >> +} GLSV_GLA_CLM_INFO; >> + >> /* For GLND to GLA communication */ >> typedef struct glsv_gla_evt { >> SaLckHandleT handle; >> @@ -95,6 +103,7 @@ typedef struct glsv_gla_evt { >> union { >> GLSV_GLA_CALLBACK_INFO gla_clbk_info; /* callbk info */ >> GLSV_GLA_API_RESP_INFO gla_resp_info; /* api response info */ >> + GLSV_GLA_CLM_INFO gla_clm_info; /* clm info */ >> } info; >> } GLSV_GLA_EVT; >> >> diff --git a/src/lck/agent/gla_init.c b/src/lck/agent/gla_init.c >> index 8a81669..ee81d6a 100644 >> --- a/src/lck/agent/gla_init.c >> +++ b/src/lck/agent/gla_init.c >> @@ -473,6 +473,33 @@ end: >> } >> >> /********************************************************** >> ****************** >> + Name : gla_client_tree_find_next >> + >> + Description : This routine returns the next client >> + >> + Arguments : >> + gla_cb : pointer to the gla control block. >> + hdl_id : the handle id. >> + >> + Return Values : returns the client_info node. >> + >> + Notes : None >> +*********************************************************** >> *******************/ >> +GLA_CLIENT_INFO *gla_client_tree_find_next(GLA_CB *gla_cb, SaLckHandleT >> hdl_id) >> +{ >> + GLA_CLIENT_INFO *client_info = NULL; >> + TRACE_ENTER(); >> + >> + /* take the cb lock */ >> + m_NCS_LOCK(&gla_cb->cb_lock, NCS_LOCK_READ); >> + client_info = (GLA_CLIENT_INFO *)ncs_patricia_tree_getnext( >> + &gla_cb->gla_client_tree, (uint8_t *)&hdl_id); >> + m_NCS_UNLOCK(&gla_cb->cb_lock, NCS_LOCK_READ); >> + >> + return client_info; >> +} >> + >> +/********************************************************** >> ****************** >> Name : gla_client_info_send >> >> Description : >> diff --git a/src/lck/agent/gla_mds.c b/src/lck/agent/gla_mds.c >> index b910f69..5f6e6f5 100644 >> --- a/src/lck/agent/gla_mds.c >> +++ b/src/lck/agent/gla_mds.c >> @@ -60,6 +60,7 @@ static uint32_t glsv_gla_dec_callbk_evt(NCS_UBAID *uba, >> GLSV_GLA_CALLBACK_INFO *evt); >> static uint32_t glsv_gla_dec_api_resp_evt(NCS_UBAID *uba, >> GLSV_GLA_API_RESP_INFO *evt); >> +static uint32_t glsv_gla_dec_clm_evt(NCS_UBAID *uba, GLSV_GLA_CLM_INFO >> *evt); >> >> uint32_t gla_mds_get_handle(GLA_CB *cb); >> >> @@ -520,6 +521,10 @@ static uint32_t gla_mds_dec(GLA_CB *cb, >> MDS_CALLBACK_DEC_INFO *info) >> >> &evt->info.gla_resp_info); >> break; >> >> + case GLSV_GLA_CLM_EVT: >> + glsv_gla_dec_clm_evt(uba, >> &evt->info.gla_clm_info); >> + break; >> + >> default: >> goto end; >> } >> @@ -648,6 +653,21 @@ static uint32_t gla_mds_rcv(GLA_CB *cb, >> MDS_CALLBACK_RECEIVE_INFO *rcv_info) >> m_MMGR_FREE_GLA_CALLBACK_INFO(gla_callbk_info); >> } >> goto end; >> + } else if (evt->type == GLSV_GLA_CLM_EVT) { >> + cb->isClusterMember = evt->info.gla_clm_info.isClusterMember; >> + >> + if (!cb->isClusterMember) { >> + /* tell all clients they are stale now */ >> + GLA_CLIENT_INFO *client_info; >> + SaLckHandleT lckHandle = 0; >> + for (client_info = gla_client_tree_find_next(cb, lckHandle); >> + client_info; >> + client_info = gla_client_tree_find_next( >> + cb, client_info->lock_handle_id)) { >> + client_info->isStale = true; >> + } >> + } >> + m_MMGR_FREE_GLA_EVT(evt); >> } else { >> if (evt) >> m_MMGR_FREE_GLA_EVT(evt); >> @@ -1462,3 +1482,39 @@ end: >> TRACE_LEAVE(); >> return rc; >> } >> + >> +/********************************************************** >> ****************** >> + Name : glsv_gla_DEC_clm_evt >> + >> + Description : This routine decodes clm info. >> + >> + Arguments : uba , clm info. >> + >> + Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE >> + >> + Notes : None. >> +*********************************************************** >> *******************/ >> +static uint32_t glsv_gla_dec_clm_evt(NCS_UBAID *uba, GLSV_GLA_CLM_INFO >> *evt) >> +{ >> + uint8_t *p8, local_data[20], size; >> + uint32_t rc = NCSCC_RC_SUCCESS; >> + TRACE_ENTER(); >> + >> + do { >> + /** decode the type of message **/ >> + size = (4); >> + p8 = ncs_dec_flatten_space(uba, local_data, size); >> + if (!p8) { >> + TRACE_2("GLA mds dec failure"); >> + rc = NCSCC_RC_FAILURE; >> + break; >> + } >> + >> + osaf_decode_bool(uba, &evt->isClusterMember); >> + >> + ncs_dec_skip_space(uba, size); >> + } while (false); >> + >> + TRACE_LEAVE(); >> + return rc; >> +} >> diff --git a/src/lck/common/glsv_defs.h b/src/lck/common/glsv_defs.h >> index a638965..60fa910 100644 >> --- a/src/lck/common/glsv_defs.h >> +++ b/src/lck/common/glsv_defs.h >> @@ -42,13 +42,18 @@ typedef unsigned int GLSV_TIMER_ID; >> >> /* Version Constants */ >> #define REQUIRED_RELEASECODE 'B' >> -#define REQUIRED_MAJORVERSION 01 >> -#define REQUIRED_MINORVERSION 01 >> +#define REQUIRED_MAJORVERSION 3 >> +#define REQUIRED_MINORVERSION 1 >> >> #define m_GLA_VER_IS_VALID(ver) \ >> ((ver->releaseCode == REQUIRED_RELEASECODE) && \ >> (ver->majorVersion <= REQUIRED_MAJORVERSION)) >> >> +#define m_GLA_VER_IS_AT_LEAST_B_3(ver) \ >> + ((ver.releaseCode == 'B' && \ >> + ver.majorVersion >= 3) || \ >> + ver.releaseCode > 'B') >> + >> #define MSG_FRMT_VER uint32_t >> /*** Macro used to get the AMF version used ****/ >> #define m_GLSV_GET_AMF_VER(amf_ver) \ >> diff --git a/src/lck/lckd/gld_api.c b/src/lck/lckd/gld_api.c >> index ad1ec6c..256a180 100644 >> --- a/src/lck/lckd/gld_api.c >> +++ b/src/lck/lckd/gld_api.c >> @@ -29,12 +29,13 @@ >> #include <string.h> >> #include <stdlib.h> >> #include "gld_imm.h" >> +#include "gld_clm.h" >> >> uint32_t gl_gld_hdl; >> >> void gld_main_process(SYSF_MBX *mbx); >> >> -enum { FD_TERM = 0, FD_AMF, FD_MBCSV, FD_MBX, FD_IMM, NUM_FD }; >> +enum { FD_TERM = 0, FD_AMF, FD_MBCSV, FD_MBX, FD_IMM, FD_CLM, NUM_FD }; >> >> static struct pollfd fds[NUM_FD]; >> static nfds_t nfds = NUM_FD; >> @@ -199,6 +200,13 @@ uint32_t gld_se_lib_init(NCS_LIB_REQ_INFO *req_info) >> } else >> TRACE_1("AMF Health Check started"); >> >> + amf_error = gld_clm_init(gld_cb); >> + if (amf_error != SA_AIS_OK) { >> + LOG_ER("CLM Init Failed %u", amf_error); >> + res = NCSCC_RC_FAILURE; >> + goto end; >> + } >> + >> if ((res = initialize_for_assignment(gld_cb, gld_cb->ha_state)) >> != >> NCSCC_RC_SUCCESS) { >> LOG_ER("initialize_for_assignment FAILED %u", >> (unsigned)res); >> @@ -501,7 +509,7 @@ void gld_main_process(SYSF_MBX *mbx) >> SaAisErrorT error = SA_AIS_OK; >> GLSV_GLD_CB *gld_cb = NULL; >> NCS_MBCSV_ARG mbcsv_arg; >> - SaSelectionObjectT amf_sel_obj; >> + SaSelectionObjectT amf_sel_obj, clm_sel_obj; >> int term_fd; >> >> TRACE_ENTER(); >> @@ -520,6 +528,13 @@ void gld_main_process(SYSF_MBX *mbx) >> goto end; >> } >> >> + error = saClmSelectionObjectGet(gld_cb->clm_hdl, &clm_sel_obj); >> + >> + if (error != SA_AIS_OK) { >> + LOG_ER("CLM Selection object get error: %i", error); >> + goto end; >> + } >> + >> daemon_sigterm_install(&term_fd); >> >> /* Set up all file descriptors to listen to */ >> @@ -531,6 +546,8 @@ void gld_main_process(SYSF_MBX *mbx) >> fds[FD_MBX].events = POLLIN; >> fds[FD_IMM].fd = gld_cb->imm_sel_obj; >> fds[FD_IMM].events = POLLIN; >> + fds[FD_CLM].fd = clm_sel_obj; >> + fds[FD_CLM].events = POLLIN; >> >> while (1) { >> fds[FD_MBCSV].fd = gld_cb->mbcsv_sel_obj; >> @@ -622,6 +639,14 @@ void gld_main_process(SYSF_MBX *mbx) >> break; >> } >> } >> + >> + if (fds[FD_CLM].revents & POLLIN) { >> + /* dispatch all the CLM pending function */ >> + error = saClmDispatch(gld_cb->clm_hdl, SA_DISPATCH_ALL); >> + if (error != SA_AIS_OK) { >> + LOG_ER("CLM dispatch failed: %i", error); >> + } >> + } >> } >> end: >> TRACE_LEAVE(); >> diff --git a/src/lck/lckd/gld_cb.h b/src/lck/lckd/gld_cb.h >> index c35961e..fabd39c 100644 >> --- a/src/lck/lckd/gld_cb.h >> +++ b/src/lck/lckd/gld_cb.h >> @@ -81,7 +81,7 @@ typedef struct glsv_gld_cb_tag { >> uint8_t hm_poolid; /* For use with handle manager */ >> NCSCONTEXT task_hdl; >> uint32_t my_hdl; /* Handle manager handle */ >> - uint32_t clm_hdl; /* Handle manager handle */ >> + SaClmHandleT clm_hdl; /* CLM handle */ >> NCS_MBCSV_HDL mbcsv_handle; >> NCS_MBCSV_CKPT_HDL o_ckpt_hdl; >> SaSelectionObjectT mbcsv_sel_obj; >> diff --git a/src/lck/lckd/gld_clm.cc b/src/lck/lckd/gld_clm.cc >> new file mode 100644 >> index 0000000..3ed82aa >> --- /dev/null >> +++ b/src/lck/lckd/gld_clm.cc >> @@ -0,0 +1,131 @@ >> +#include "clm/saf/saClm.h" >> +#include "lck/lckd/gld_clm.h" >> +#include "base/osaf_time.h" >> + >> +static void handleClmNodeUpdate(GLSV_GLD_CB& cb, >> + SaClmNodeIdT nodeId, >> + bool isClusterMember) { >> + TRACE_ENTER(); >> + >> + GLSV_GLD_EVT *evt(m_MMGR_ALLOC_GLSV_GLD_EVT); >> + >> + if (evt == GLSV_GLD_EVT_NULL) { >> + LOG_CR("Event alloc failed: Error %s", strerror(errno)); >> + assert(false); >> + } >> + >> + memset(evt, 0, sizeof(GLSV_GLD_EVT)); >> + evt->gld_cb = &cb; >> + evt->evt_type = GLSV_GLD_EVT_GLND_DOWN_CLM; >> + evt->info.glnd_clm_info.nodeId = nodeId; >> + >> + // Push the event and we are done >> + if (m_NCS_IPC_SEND(&cb.mbx, evt, NCS_IPC_PRIORITY_NORMAL) == >> NCSCC_RC_FAILURE) { >> + LOG_ER("IPC send failed"); >> + gld_evt_destroy(evt); >> + } >> + >> + TRACE_LEAVE(); >> +} >> + >> +static void clusterTrackCallback( >> + const SaClmClusterNotificationBufferT_4 *notificationBuffer, >> + SaUint32T numberOfMembers, >> + SaInvocationT invocation, >> + const SaNameT *rootCauseEntity, >> + const SaNtfCorrelationIdsT *correlationIds, >> + SaClmChangeStepT step, >> + SaTimeT timeSupervision, >> + SaAisErrorT error) { >> + >> + TRACE_ENTER(); >> + >> + do { >> + if (error != SA_AIS_OK) { >> + LOG_ER("clusterTrackCallback sent failure: %i", error); >> + break; >> + } >> + >> + GLSV_GLD_CB *cb(static_cast<GLSV_GLD_CB >> *>(m_GLSV_GLD_RETRIEVE_GLD_CB)); >> + >> + if (!cb) { >> + LOG_ER("GLD cb take handle failed"); >> + break; >> + } >> + >> + TRACE("number of items: %i", notificationBuffer->numberOfItems); >> + >> + for (SaUint32T i(0); i < notificationBuffer->numberOfItems; i++) { >> + TRACE("cluster change: %i", notificationBuffer->notificati >> on[i].clusterChange); >> + /* >> + * We only care about nodes leaving; lcknd will send an up message >> when >> + * it is operational >> + */ >> + if (notificationBuffer->notification[i].clusterChange == >> SA_CLM_NODE_LEFT) { >> + handleClmNodeUpdate( >> + *cb, >> + notificationBuffer->notification[i].clusterNode.nodeId, >> + false); >> + } >> + } >> + >> + m_GLSV_GLD_GIVEUP_GLD_CB; >> + >> + } while (false); >> + >> + TRACE_LEAVE(); >> +} >> + >> +SaAisErrorT gld_clm_init(GLSV_GLD_CB *cb) { >> + TRACE_ENTER(); >> + >> + SaAisErrorT rc(SA_AIS_OK); >> + >> + do { >> + SaClmCallbacksT_4 callbacks = { >> + 0, >> + clusterTrackCallback >> + }; >> + >> + SaVersionT version = { 'B', 4, 0 }; >> + >> + while (true) { >> + rc = saClmInitialize_4(&cb->clm_hdl, &callbacks, &version); >> + >> + if (rc == SA_AIS_ERR_TRY_AGAIN) { >> + osaf_nanosleep(&kHundredMilliseconds); >> + continue; >> + } else if (rc != SA_AIS_OK) { >> + LOG_ER("saClmInitialize_4 failed: %i", rc); >> + break; >> + } else { >> + break; >> + } >> + } >> + >> + rc = saClmClusterTrack_4(cb->clm_hdl, SA_TRACK_CHANGES_ONLY, 0); >> + >> + if (rc != SA_AIS_OK) { >> + LOG_ER("saClmClusterTrack failed: %i", rc); >> + break; >> + } >> + } while (false); >> + >> + if (rc != SA_AIS_OK && cb->clm_hdl) >> + gld_clm_deinit(cb); >> + >> + TRACE_LEAVE(); >> + return rc; >> +} >> + >> +SaAisErrorT gld_clm_deinit(GLSV_GLD_CB *cb) >> +{ >> + SaAisErrorT rc(saClmFinalize(cb->clm_hdl)); >> + >> + if (rc != SA_AIS_OK) >> + LOG_ER("saClmFinalize failed: %i", rc); >> + >> + cb->clm_hdl = 0; >> + >> + return rc; >> +} >> diff --git a/src/lck/lckd/gld_clm.h b/src/lck/lckd/gld_clm.h >> new file mode 100644 >> index 0000000..407b9a8 >> --- /dev/null >> +++ b/src/lck/lckd/gld_clm.h >> @@ -0,0 +1,17 @@ >> +#ifndef LCK_LCKD_GLD_CLM_H_ >> +#define LCK_LCKD_GLD_CLM_H_ >> + >> +#include "lck/lckd/gld.h" >> + >> +#ifdef __cplusplus >> +extern "C" { >> +#endif >> + >> +SaAisErrorT gld_clm_init(GLSV_GLD_CB *); >> +SaAisErrorT gld_clm_deinit(GLSV_GLD_CB *); >> + >> +#ifdef __cplusplus >> +} >> +#endif >> + >> +#endif // LCK_LCKND_GLND_CLM_H_ >> diff --git a/src/lck/lckd/gld_evt.c b/src/lck/lckd/gld_evt.c >> index aea7579..dc85179 100644 >> --- a/src/lck/lckd/gld_evt.c >> +++ b/src/lck/lckd/gld_evt.c >> @@ -45,6 +45,7 @@ static uint32_t gld_process_send_non_master_status( >> static uint32_t gld_process_send_non_master_info( >> GLSV_GLD_CB *gld_cb, GLSV_GLD_GLND_RSC_REF *glnd_rsc, >> GLSV_GLD_GLND_DETAILS *node_details, uint32_t status); >> +static uint32_t gld_clm_glnd_down(GLSV_GLD_EVT *evt); >> >> /* GLD dispatch table */ >> static const GLSV_GLD_EVT_HANDLER >> @@ -57,7 +58,8 @@ static const GLSV_GLD_EVT_HANDLER >> gld_debug_dump_cb, >> gld_process_tmr_resource_reelection_wait_timeout, >> gld_process_tmr_node_restart_wait_timeout, >> - gld_quisced_process}; >> + gld_quisced_process, >> + gld_clm_glnd_down}; >> >> /********************************************************** >> ****************** >> * Name : gld_process_evt >> @@ -683,8 +685,6 @@ end: >> static uint32_t gld_mds_glnd_down(GLSV_GLD_EVT *evt) >> { >> GLSV_GLD_CB *gld_cb = evt->gld_cb; >> - GLSV_GLD_GLND_DETAILS *node_details = NULL; >> - GLSV_GLD_RSC_INFO *rsc_info; >> uint32_t node_id; >> uint32_t rc = NCSCC_RC_FAILURE; >> TRACE_ENTER2("mds identification %u", gld_cb->my_dest_id); >> @@ -692,54 +692,11 @@ static uint32_t gld_mds_glnd_down(GLSV_GLD_EVT *evt) >> node_id = >> m_NCS_NODE_ID_FROM_MDS_DEST(evt->info.glnd_mds_info.mds_dest >> _id); >> >> - if ((evt == GLSV_GLD_EVT_NULL) || (gld_cb == NULL)) >> - goto end; >> - >> - memcpy(&evt->fr_dest_id, &evt->info.glnd_mds_info.mds_dest_id, >> - sizeof(MDS_DEST)); >> + evt->info.glnd_clm_info.nodeId = node_id; >> + evt->info.glnd_clm_info.isClusterMember = false; >> >> - if ((node_details = (GLSV_GLD_GLND_DETAILS >> *)ncs_patricia_tree_get( >> - &gld_cb->glnd_details, (uint8_t *)&node_id)) == NULL) { >> - TRACE_1("Resource details is empty for glnd on node_id %u >> ", >> - node_id); >> - rc = NCSCC_RC_SUCCESS; >> - goto end; >> - } >> - node_details->status = GLND_RESTART_STATE; >> - >> - TRACE("EVT Processing MDS GLND DOWN: node_id %u", >> - node_details->node_id); >> - memcpy(&node_details->restart_timer.mdest_id, >> &node_details->dest_id, >> - sizeof(MDS_DEST)); >> - >> - /* Start GLSV_GLD_GLND_RESTART_TIMEOUT timer */ >> - gld_start_tmr(gld_cb, &node_details->restart_timer, >> - GLD_TMR_NODE_RESTART_TIMEOUT, >> GLD_NODE_RESTART_TIMEOUT, >> - 0); >> - >> - /* Check whether this node is master for any resource, if yes >> send the >> - status to all the non master nodes */ >> - if (gld_cb->ha_state == SA_AMF_HA_ACTIVE) { >> - /* Check whether this node is master for any resource, if >> yes >> - * send the status to all the non master nodes */ >> - rsc_info = gld_cb->rsc_info; >> - while (rsc_info != NULL) { >> - if (rsc_info->node_list) { >> - if (rsc_info->node_list->node_id == >> - node_details->node_id) >> - gld_snd_master_status( >> - gld_cb, rsc_info, >> - GLND_RESOURCE_MASTER_RESTARTE >> D); >> - } >> - rsc_info = rsc_info->next; >> - } >> + gld_clm_glnd_down(evt); >> >> - /* If this node is non master for any resource, then send >> node >> - * status to the master */ >> - gld_process_send_non_master_status(gld_cb, node_details, >> - GLND_RESTART_STATE); >> - } >> -end: >> TRACE_LEAVE2("Return value: %u", rc); >> return rc; >> } >> @@ -1073,3 +1030,63 @@ end: >> TRACE_LEAVE(); >> return res; >> } >> + >> +/********************************************************** >> ****************** >> + * Name : gld_clm_glnd_down >> + * >> + * Description : CLM indicated that a glnd has gone down >> + * >> + * Arguments : evt - Event structure >> + * >> + * Return Values : NCSCC_RC_SUCCESS/ NCSCC_RC_FAILURE >> + * >> + * Notes : None. >> + ************************************************************ >> *****************/ >> +static uint32_t gld_clm_glnd_down(GLSV_GLD_EVT *evt) >> +{ >> + GLSV_GLD_CB *gld_cb = evt->gld_cb; >> + GLSV_GLD_GLND_DETAILS *node_details = NULL; >> + GLSV_GLD_RSC_INFO *rsc_info; >> + uint32_t node_id; >> + uint32_t rc = NCSCC_RC_FAILURE; >> + TRACE_ENTER2("mds identification %u",gld_cb->my_dest_id ); >> + >> + node_id = evt->info.glnd_clm_info.nodeId; >> + >> + if ((node_details = (GLSV_GLD_GLND_DETAILS >> *)ncs_patricia_tree_get(&gld_cb->glnd_details, >> + >> (uint8_t *)&node_id)) == NULL) { >> + TRACE_1("Resource details is empty for glnd on node_id %u >> ", node_id); >> + rc = NCSCC_RC_SUCCESS; >> + goto end; >> + } >> + node_details->status = GLND_RESTART_STATE; >> + >> + TRACE("EVT Processing CLM GLND DOWN: node_id %u", >> node_details->node_id); >> + memcpy(&node_details->restart_timer.mdest_id, >> &node_details->dest_id, sizeof(MDS_DEST)); >> + >> + /* Start GLSV_GLD_GLND_RESTART_TIMEOUT timer */ >> + gld_start_tmr(gld_cb, &node_details->restart_timer, >> GLD_TMR_NODE_RESTART_TIMEOUT, GLD_NODE_RESTART_TIMEOUT, 0); >> + >> + /* Check whether this node is master for any resource, if yes >> send the status to all >> + the >> + non master nodes */ >> + if (gld_cb->ha_state == SA_AMF_HA_ACTIVE) { >> + /* Check whether this node is master for any resource, if >> yes send the status to all the non master nodes */ >> + rsc_info = gld_cb->rsc_info; >> + while (rsc_info != NULL) { >> + if (rsc_info->node_list) { >> + if (rsc_info->node_list->node_id == >> node_details->node_id) >> + gld_snd_master_status(gld_cb, >> rsc_info, GLND_RESOURCE_MASTER_RESTARTED); >> + } >> + rsc_info = rsc_info->next; >> + } >> + >> + /* If this node is non master for any resource, then send >> node status to the master */ >> + gld_process_send_non_master_status(gld_cb, node_details, >> GLND_RESTART_STATE); >> + >> + } >> + end: >> + TRACE_LEAVE2("Return value: %u", rc); >> + return rc; >> +} >> + >> diff --git a/src/lck/lckd/gld_evt.h b/src/lck/lckd/gld_evt.h >> index 1484fb0..9a2e7f6 100644 >> --- a/src/lck/lckd/gld_evt.h >> +++ b/src/lck/lckd/gld_evt.h >> @@ -18,6 +18,10 @@ >> #ifndef LCK_LCKD_GLD_EVT_H_ >> #define LCK_LCKD_GLD_EVT_H_ >> >> +#ifdef __cplusplus >> +extern "C" { >> +#endif >> + >> /********************************************************** >> ******************* >> * Message Type of GLND >> ************************************************************ >> *****************/ >> @@ -36,6 +40,8 @@ typedef enum glsv_gld_evt_type { >> GLSV_GLD_EVT_RESTART_TIMEOUT, >> GLSV_GLD_EVT_QUISCED_STATE, >> >> + GLSV_GLD_EVT_GLND_DOWN_CLM, >> + >> GLSV_GLD_EVT_MAX >> } GLSV_GLD_EVT_TYPE; >> >> @@ -66,6 +72,11 @@ typedef struct gld_evt_tmr_tag { >> uint32_t opq_hdl; >> } GLD_EVT_TMR; >> >> +typedef struct gld_evt_node_info { >> + uint32_t nodeId; >> + bool isClusterMember; >> +} GLSV_GLD_GLND_NODE_INFO; >> + >> /********************************************************** >> ******************* >> * GLD msg data structure. >> ************************************************************ >> *****************/ >> @@ -79,6 +90,7 @@ typedef struct glsv_gld_evt_tag { >> GLSV_RSC_DETAILS rsc_details; >> GLSV_GLD_GLND_MDS_INFO glnd_mds_info; >> GLD_EVT_TMR tmr; >> + GLSV_GLD_GLND_NODE_INFO glnd_clm_info; >> } info; >> } GLSV_GLD_EVT; >> >> @@ -90,4 +102,8 @@ typedef uint32_t (*GLSV_GLD_EVT_HANDLER)(struct >> glsv_gld_evt_tag *evt); >> void gld_evt_destroy(GLSV_GLD_EVT *evt); >> uint32_t gld_process_evt(GLSV_GLD_EVT *evt); >> >> +#ifdef __cplusplus >> +} >> +#endif >> + >> #endif // LCK_LCKD_GLD_EVT_H_ >> diff --git a/src/lck/lcknd/glnd_agent.c b/src/lck/lcknd/glnd_agent.c >> index 36e5668..a7f7a79 100644 >> --- a/src/lck/lcknd/glnd_agent.c >> +++ b/src/lck/lcknd/glnd_agent.c >> @@ -55,6 +55,29 @@ GLND_AGENT_INFO *glnd_agent_node_find(GLND_CB >> *glnd_cb, MDS_DEST agent_mds_dest) >> } >> >> /********************************************************** >> ******************* >> + PROCEDURE NAME : glnd_agent_node_find_next >> + >> + DESCRIPTION : Finds the Agent info node from the tree. >> + >> + ARGUMENTS :glnd_cb - ptr to the GLND control block >> + mds_handle_id - vcard id of the agent. >> + >> + RETURNS :The pointer to the agent info node >> + >> + NOTES : None >> +*********************************************************** >> ******************/ >> +GLND_AGENT_INFO *glnd_agent_node_find_next(GLND_CB *glnd_cb, >> + MDS_DEST agent_mds_dest) >> +{ >> + GLND_AGENT_INFO *agent_info; >> + >> + /* search for the agent id */ >> + agent_info = (GLND_AGENT_INFO *)ncs_patricia_tree_getnext( >> + &glnd_cb->glnd_agent_tree, (uint8_t *)&agent_mds_dest); >> + >> + return agent_info; >> +} >> +/********************************************************** >> ******************* >> PROCEDURE NAME : glnd_agent_node_add >> >> DESCRIPTION : Adds the Agent node to the Agent tree. >> diff --git a/src/lck/lcknd/glnd_api.c b/src/lck/lcknd/glnd_api.c >> index 93723c3..7534386 100644 >> --- a/src/lck/lcknd/glnd_api.c >> +++ b/src/lck/lcknd/glnd_api.c >> @@ -33,7 +33,7 @@ >> #include "lck/lcknd/glnd.h" >> #include "base/osaf_poll.h" >> >> -enum { FD_TERM = 0, FD_AMF, FD_MBX, NUM_FD }; >> +enum { FD_TERM = 0, FD_AMF, FD_MBX, FD_CLM, NUM_FD }; >> >> void glnd_main_process(SYSF_MBX *mbx); >> >> @@ -192,9 +192,10 @@ void glnd_main_process(SYSF_MBX *mbx) >> TRACE_ENTER(); >> >> SaAmfHandleT amf_hdl; >> + SaClmHandleT clm_hdl; >> >> - SaSelectionObjectT amf_sel_obj; >> - SaAisErrorT amf_error; >> + SaSelectionObjectT amf_sel_obj, clm_sel_obj; >> + SaAisErrorT ais_error; >> >> struct pollfd sel[NUM_FD]; >> int term_fd; >> @@ -207,16 +208,23 @@ void glnd_main_process(SYSF_MBX *mbx) >> } >> >> amf_hdl = glnd_cb->amf_hdl; >> + clm_hdl = glnd_cb->clm_hdl; >> >> /*giveup the handle */ >> m_GLND_GIVEUP_GLND_CB; >> >> - amf_error = saAmfSelectionObjectGet(amf_hdl, &amf_sel_obj); >> - if (amf_error != SA_AIS_OK) { >> + ais_error = saAmfSelectionObjectGet(amf_hdl, &amf_sel_obj); >> + if (ais_error != SA_AIS_OK) { >> LOG_ER("GLND amf get sel obj error"); >> goto end; >> } >> >> + ais_error = saClmSelectionObjectGet(clm_hdl, &clm_sel_obj); >> + if (ais_error != SA_AIS_OK) { >> + LOG_ER("GLND clm get sel obj error: %i", ais_error); >> + goto end; >> + } >> + >> daemon_sigterm_install(&term_fd); >> >> sel[FD_TERM].fd = term_fd; >> @@ -225,6 +233,8 @@ void glnd_main_process(SYSF_MBX *mbx) >> sel[FD_AMF].events = POLLIN; >> sel[FD_MBX].fd = m_GET_FD_FROM_SEL_OBJ(mbx_fd); >> sel[FD_MBX].events = POLLIN; >> + sel[FD_CLM].fd = clm_sel_obj; >> + sel[FD_CLM].events = POLLIN; >> >> while (osaf_poll(&sel[0], NUM_FD, -1) > 0) { >> >> @@ -232,7 +242,7 @@ void glnd_main_process(SYSF_MBX *mbx) >> daemon_exit(); >> } >> >> - if (((sel[FD_AMF].revents | sel[FD_MBX].revents) & >> + if (((sel[FD_AMF].revents | sel[FD_MBX].revents | >> sel[FD_CLM].revents) & >> (POLLERR | POLLHUP | POLLNVAL)) != 0) { >> LOG_ER("GLND poll() failure: %hd %hd", >> sel[FD_AMF].revents, sel[FD_MBX].revents); >> @@ -242,8 +252,8 @@ void glnd_main_process(SYSF_MBX *mbx) >> /* process all the AMF messages */ >> if (sel[FD_AMF].revents & POLLIN) { >> /* dispatch all the AMF pending function */ >> - amf_error = saAmfDispatch(amf_hdl, >> SA_DISPATCH_ALL); >> - if (amf_error != SA_AIS_OK) { >> + ais_error = saAmfDispatch(amf_hdl, >> SA_DISPATCH_ALL); >> + if (ais_error != SA_AIS_OK) { >> TRACE_2("GLND amf dispatch failure"); >> } >> } >> @@ -257,6 +267,15 @@ void glnd_main_process(SYSF_MBX *mbx) >> } else >> break; >> } >> + >> + /* process all the AMF messages */ >> + if (sel[FD_CLM].revents & POLLIN) { >> + /* dispatch all the CLM pending function */ >> + ais_error = saClmDispatch(clm_hdl, >> SA_DISPATCH_ALL); >> + if (ais_error != SA_AIS_OK) { >> + TRACE_2("GLND clm dispatch failure: %i", >> ais_error); >> + } >> + } >> } >> >> TRACE("DANGER: Exiting the Select loop of GLND"); >> diff --git a/src/lck/lcknd/glnd_cb.c b/src/lck/lcknd/glnd_cb.c >> index 8928825..ebf917b 100644 >> --- a/src/lck/lcknd/glnd_cb.c >> +++ b/src/lck/lcknd/glnd_cb.c >> @@ -27,6 +27,7 @@ >> *********************************************************** >> *******************/ >> >> #include "lck/lcknd/glnd.h" >> +#include "lck/lcknd/glnd_clm.h" >> >> uint32_t gl_glnd_hdl; >> NCSCONTEXT gl_glnd_task_hdl; >> @@ -119,6 +120,13 @@ GLND_CB *glnd_cb_create(uint32_t pool_id) >> } else >> TRACE_1("GLND mds register success"); >> >> + /* Initialise with the CLM service */ >> + if (glnd_clm_init(glnd_cb) != NCSCC_RC_SUCCESS) { >> + LOG_ER("GLND clm init failed"); >> + goto clm_init_err; >> + } else >> + TRACE_1("GLND clm init success"); >> + >> /* Initialise with the AMF service */ >> if (glnd_amf_init(glnd_cb) != NCSCC_RC_SUCCESS) { >> LOG_ER("GLND amf init failed"); >> @@ -179,6 +187,8 @@ amf_reg_err: >> glnd_amf_de_init(glnd_cb); >> amf_init_err: >> glnd_mds_unregister(glnd_cb); >> +clm_init_err: >> + glnd_clm_deinit(glnd_cb); >> mds_err: >> m_NCS_EDU_HDL_FLUSH(&glnd_cb->glnd_edu_hdl); >> m_NCS_IPC_DETACH(&glnd_cb->glnd_mbx, glnd_cleanup_mbx, glnd_cb); >> diff --git a/src/lck/lcknd/glnd_cb.h b/src/lck/lcknd/glnd_cb.h >> index 2c96e72..3c38b12 100644 >> --- a/src/lck/lcknd/glnd_cb.h >> +++ b/src/lck/lcknd/glnd_cb.h >> @@ -23,6 +23,10 @@ >> #include "glnd_tmr.h" >> #include "lck/lcknd/glnd_evt.h" >> >> +#ifdef __cplusplus >> +extern "C" { >> +#endif >> + >> /* global variables */ >> uint32_t gl_glnd_hdl; >> NCSCONTEXT gl_glnd_task_hdl; >> @@ -178,6 +182,7 @@ typedef struct glnd_cb_tag { >> /* Information about the GLD */ >> MDS_DEST gld_mdest_id; >> bool gld_card_up; >> + bool isClusterMember; >> >> /* GLND data */ >> NCS_PATRICIA_TREE glnd_client_tree; /* GLND_CLIENT_INFO - node */ >> @@ -189,6 +194,7 @@ typedef struct glnd_cb_tag { >> struct glsv_glnd_evt >> *evt_bckup_q; /* backup the events incase of mastership change */ >> >> + SaClmHandleT clm_hdl; /* CLM handle, obtained thru CLM init >> */ >> SaAmfHandleT amf_hdl; /* AMF handle, obtained thru AMF init */ >> SaAmfHAStateT ha_state; /* present AMF HA state of the component */ >> EDU_HDL glnd_edu_hdl; /* edu handle used for encode/decode */ >> @@ -203,6 +209,7 @@ typedef struct glnd_cb_tag { >> /* prototypes */ >> GLND_AGENT_INFO *glnd_agent_node_find(GLND_CB *glnd_cb, >> MDS_DEST agent_mds_dest); >> +GLND_AGENT_INFO *glnd_agent_node_find_next(GLND_CB *, MDS_DEST); >> GLND_AGENT_INFO *glnd_agent_node_add(GLND_CB *glnd_cb, MDS_DEST >> agent_mds_dest, >> uint32_t process_id); >> void glnd_agent_node_del(GLND_CB *glnd_cb, GLND_AGENT_INFO *agent_info); >> @@ -219,6 +226,7 @@ GLND_RESOURCE_REQ_LIST *glnd_resource_req_node_add( >> MDS_SYNC_SND_CTXT *mds_ctxt, SaLckResourceIdT lcl_resource_id); >> GLND_RESOURCE_REQ_LIST *glnd_resource_req_node_find(GLND_CB *glnd_cb, >> SaNameT >> *resource_name); >> +void glnd_resource_req_node_down(GLND_CB *glnd_cb); >> void glnd_resource_req_node_del(GLND_CB *glnd_cb, uint32_t res_req_hdl); >> >> /* Amf prototypes */ >> @@ -244,4 +252,8 @@ uint8_t glnd_cpsv_initilize(GLND_CB *glnd_cb); >> uint32_t glnd_shm_create(GLND_CB *cb); >> uint32_t glnd_shm_destroy(GLND_CB *cb, char shm_name[]); >> >> +#ifdef __cplusplus >> +} >> +#endif >> + >> #endif // LCK_LCKND_GLND_CB_H_ >> diff --git a/src/lck/lcknd/glnd_client.c b/src/lck/lcknd/glnd_client.c >> index 86659c0..02f1358 100644 >> --- a/src/lck/lcknd/glnd_client.c >> +++ b/src/lck/lcknd/glnd_client.c >> @@ -138,6 +138,98 @@ GLND_CLIENT_INFO *glnd_client_node_add(GLND_CB >> *glnd_cb, >> } >> >> /********************************************************** >> ******************* >> + PROCEDURE NAME : glnd_client_node_down >> + >> + DESCRIPTION : Sends responses to any waiting calls since the node >> is down. >> + >> + ARGUMENTS :glnd_cb - ptr to the GLND control block >> + agent_mds_dest - mds dest id for the agent. >> + >> + >> + RETURNS :None >> + >> + NOTES : None >> +*********************************************************** >> ******************/ >> +void glnd_client_node_down(GLND_CB *glnd_cb, GLND_CLIENT_INFO >> *client_info) >> +{ >> + GLND_CLIENT_LIST_RESOURCE *res_list; >> + TRACE_ENTER(); >> + >> + for (res_list = client_info->res_list; >> + res_list != NULL; >> + res_list = res_list->next) { >> + GLND_CLIENT_LIST_RESOURCE_LOCK_REQ *lckList; >> + >> + for (lckList = res_list->lck_list; lckList; lckList = lckList->next) >> { >> + GLND_RES_LOCK_LIST_INFO *lckListInfo = lckList->lck_req; >> + >> + if (lckListInfo) { >> + GLSV_GLA_EVT gla_evt; >> + >> + // respond to any blocked unlock calls >> + if (lckListInfo->unlock_call_type == GLSV_SYNC_CALL) { >> + glnd_stop_tmr(&lckListInfo->timeout_tmr); >> + >> + gla_evt.error = SA_AIS_ERR_UNAVAILABLE; >> + gla_evt.handle = lckListInfo->lock_info.handleId; >> + gla_evt.type = GLSV_GLA_API_RESP_EVT; >> + gla_evt.info.gla_resp_info.type = GLSV_GLA_LOCK_SYNC_UNLOCK; >> + >> + glnd_mds_msg_send_rsp_gla(glnd_cb, >> + &gla_evt, >> + lckListInfo->lock_info.agent_m >> ds_dest, >> + &lckListInfo->glnd_res_lock_md >> s_ctxt); >> + } else if (lckListInfo->unlock_call_type == GLSV_ASYNC_CALL) { >> + m_GLND_RESOURCE_ASYNC_LCK_UNLOCK_FILL( >> + gla_evt, >> + SA_AIS_ERR_UNAVAILABLE, >> + lckListInfo->lock_info.invocation, >> + lckListInfo->lcl_resource_id, >> + lckListInfo->lock_info.lcl_lockid, >> + 0); >> + gla_evt.handle = lckListInfo->lock_info.handleId; >> + >> + glnd_mds_msg_send_gla(glnd_cb, >> + &gla_evt, >> + lckListInfo->lock_info.agent_mds_dest); >> + } >> + >> + // respond to any blocked lock calls >> + if (lckListInfo->lock_info.call_type == GLSV_SYNC_CALL) { >> + glnd_stop_tmr(&lckListInfo->timeout_tmr); >> + >> + gla_evt.error = SA_AIS_ERR_UNAVAILABLE; >> + gla_evt.handle = lckListInfo->lock_info.handleId; >> + gla_evt.type = GLSV_GLA_API_RESP_EVT; >> + gla_evt.info.gla_resp_info.type = GLSV_GLA_LOCK_SYNC_LOCK; >> + >> + glnd_mds_msg_send_rsp_gla(glnd_cb, >> + &gla_evt, >> + lckListInfo->lock_info.agent_m >> ds_dest, >> + &lckListInfo->glnd_res_lock_md >> s_ctxt); >> + } else if (lckListInfo->lock_info.call_type == GLSV_ASYNC_CALL) >> { >> + m_GLND_RESOURCE_ASYNC_LCK_GRANT_FILL( >> + gla_evt, >> + SA_AIS_ERR_UNAVAILABLE, >> + 0, >> + lckListInfo->lock_info.lcl_lockid, >> + lckListInfo->lock_info.lock_type, >> + lckListInfo->lcl_resource_id, >> + lckListInfo->lock_info.invocation, >> + 0, >> + lckListInfo->lock_info.handleId); >> + >> + glnd_mds_msg_send_gla(glnd_cb, >> + &gla_evt, >> + lckListInfo->lock_info.agent_mds_dest); >> + } >> + } >> + } >> + } >> + >> + TRACE_LEAVE(); >> +} >> +/********************************************************** >> ******************* >> PROCEDURE NAME : glnd_client_node_del >> >> DESCRIPTION : Deletes the client node from the tree. >> diff --git a/src/lck/lcknd/glnd_client.h b/src/lck/lcknd/glnd_client.h >> index 025a352..fff2342 100644 >> --- a/src/lck/lcknd/glnd_client.h >> +++ b/src/lck/lcknd/glnd_client.h >> @@ -18,6 +18,10 @@ >> #ifndef LCK_LCKND_GLND_CLIENT_H_ >> #define LCK_LCKND_GLND_CLIENT_H_ >> >> +#ifdef __cplusplus >> +extern "C" { >> +#endif >> + >> typedef struct glnd_client_list_resource_lock_req_tag { >> GLND_RES_LOCK_LIST_INFO *lck_req; >> struct glnd_client_list_resource_lock_req_tag *prev, *next; >> @@ -53,6 +57,8 @@ GLND_CLIENT_INFO *glnd_client_node_add(GLND_CB *glnd_cb, >> MDS_DEST agent_mds_dest, >> SaLckHandleT app_handle_id); >> >> +void glnd_client_node_down(GLND_CB *glnd_cb, GLND_CLIENT_INFO >> *client_info); >> + >> uint32_t glnd_client_node_del(GLND_CB *glnd_cb, GLND_CLIENT_INFO >> *client_info); >> >> uint32_t glnd_client_node_resource_add(GLND_CLIENT_INFO *client_info, >> @@ -86,4 +92,8 @@ uint32_t glnd_client_node_resource_lock >> _find_duplicate_ex( >> GLND_CLIENT_INFO *client_info, SaLckResourceIdT res_id, >> SaLckResourceIdT lcl_res_id); >> >> +#ifdef __cplusplus >> +} >> +#endif >> + >> #endif // LCK_LCKND_GLND_CLIENT_H_ >> diff --git a/src/lck/lcknd/glnd_clm.cc b/src/lck/lcknd/glnd_clm.cc >> new file mode 100644 >> index 0000000..5ee8596 >> --- /dev/null >> +++ b/src/lck/lcknd/glnd_clm.cc >> @@ -0,0 +1,183 @@ >> +#include "clm/saf/saClm.h" >> +#include "lck/lcknd/glnd_clm.h" >> +#include "base/osaf_time.h" >> + >> +static void handleClmNodeUpdate(GLND_CB& cb, bool isClusterMember) { >> + TRACE_ENTER(); >> + cb.isClusterMember = isClusterMember; >> + >> + GLSV_GLA_EVT gla_evt; >> + >> + gla_evt.error = SA_AIS_OK; >> + gla_evt.type = GLSV_GLA_CLM_EVT; >> + gla_evt.info.gla_clm_info.isClusterMember = isClusterMember; >> + >> + >> + // send replies to outstanding callbacks first, then notify all the >> agents >> + glnd_resource_req_node_down(&cb); >> + >> + for (GLND_AGENT_INFO *agentInfo(glnd_agent_node_find_next(&cb, 0)); >> + agentInfo; >> + agentInfo = glnd_agent_node_find_next(&cb, >> agentInfo->agent_mds_id)) { >> + if (!isClusterMember) { >> + // behave internally as if all clients went down >> + for (GLND_CLIENT_INFO *clientInfo( >> + glnd_client_node_find_next(&cb, 0, >> agentInfo->agent_mds_id)); >> + clientInfo; >> + clientInfo = glnd_client_node_find_next(&cb, >> + >> clientInfo->app_handle_id, >> + >> agentInfo->agent_mds_id)) { >> + glnd_client_node_down(&cb, clientInfo); >> + glnd_client_node_del(&cb, clientInfo); >> + } >> + } >> + >> + glnd_mds_msg_send_gla(&cb, &gla_evt, agentInfo->agent_mds_id); >> + } >> + >> + TRACE_LEAVE(); >> +} >> + >> +static void clusterNodeGetCallback( >> + SaInvocationT invocation, >> + const SaClmClusterNodeT_4 *clusterNode, >> + SaAisErrorT error) { >> + >> + TRACE_ENTER(); >> + >> + do { >> + if (error != SA_AIS_OK) { >> + LOG_ER("clusterNodeGetCallback sent failure: %i", error); >> + break; >> + } >> + >> + GLND_CB *cb(static_cast<GLND_CB *>(m_GLND_TAKE_GLND_CB)); >> + >> + if (!cb) { >> + LOG_ER("GLND cb take handle failed"); >> + break; >> + } >> + >> + cb->glnd_node_id = clusterNode->nodeId; >> + >> + m_GLND_GIVEUP_GLND_CB; >> + >> + // now that we know our node id start the tracking >> + SaAisErrorT rc(saClmClusterTrack_4(cb->clm_hdl, >> + SA_TRACK_CURRENT | >> SA_TRACK_CHANGES, >> + 0)); >> + >> + if (rc != SA_AIS_OK) { >> + LOG_ER("saClmClusterTrack failed: %i", rc); >> + break; >> + } >> + } while (false); >> + >> + TRACE_LEAVE(); >> +} >> + >> +static void clusterTrackCallback( >> + const SaClmClusterNotificationBufferT_4 *notificationBuffer, >> + SaUint32T numberOfMembers, >> + SaInvocationT invocation, >> + const SaNameT *rootCauseEntity, >> + const SaNtfCorrelationIdsT *correlationIds, >> + SaClmChangeStepT step, >> + SaTimeT timeSupervision, >> + SaAisErrorT error) { >> + >> + TRACE_ENTER(); >> + >> + do { >> + if (error != SA_AIS_OK) { >> + LOG_ER("clusterTrackCallback sent failure: %i", error); >> + break; >> + } >> + >> + GLND_CB *cb(static_cast<GLND_CB *>(m_GLND_TAKE_GLND_CB)); >> + >> + if (!cb) { >> + LOG_ER("GLND cb take handle failed"); >> + break; >> + } >> + >> + TRACE("number of items: %i", notificationBuffer->numberOfItems); >> + >> + for (SaUint32T i(0); i < notificationBuffer->numberOfItems; i++) { >> + TRACE("our node id: %i clm node id: %i", cb->glnd_node_id, >> notificationBuffer->notification[i].clusterNode.nodeId); >> + TRACE("cluster change: %i", notificationBuffer->notificati >> on[i].clusterChange); >> + // don't care about other nodes >> + if (cb->glnd_node_id == >> notificationBuffer->notification[i].clusterNode.nodeId) >> { >> + if (notificationBuffer->notification[i].clusterChange == >> SA_CLM_NODE_LEFT) { >> + handleClmNodeUpdate(*cb, false); >> + } else if (notificationBuffer->notification[i].clusterChange == >> + SA_CLM_NODE_JOINED || >> + notificationBuffer->notification[i].clusterChange == >> + SA_CLM_NODE_NO_CHANGE) { >> + handleClmNodeUpdate(*cb, true); >> + } >> + } >> + } >> + >> + m_GLND_GIVEUP_GLND_CB; >> + >> + } while (false); >> + >> + TRACE_LEAVE(); >> +} >> + >> +SaAisErrorT glnd_clm_init(GLND_CB *cb) { >> + TRACE_ENTER(); >> + >> + SaAisErrorT rc(SA_AIS_OK); >> + >> + do { >> + SaClmCallbacksT_4 callbacks = { >> + clusterNodeGetCallback, >> + clusterTrackCallback >> + }; >> + >> + SaVersionT version = { 'B', 4, 0 }; >> + >> + while (true) { >> + rc = saClmInitialize_4(&cb->clm_hdl, &callbacks, &version); >> + >> + if (rc == SA_AIS_ERR_TRY_AGAIN) { >> + osaf_nanosleep(&kHundredMilliseconds); >> + continue; >> + } else if (rc != SA_AIS_OK) { >> + LOG_ER("saClmInitialize_4 failed: %i", rc); >> + break; >> + } else { >> + break; >> + } >> + } >> + >> + rc = saClmClusterNodeGetAsync(cb->clm_hdl, >> + 1, >> + SA_CLM_LOCAL_NODE_ID); >> + >> + if (rc != SA_AIS_OK) { >> + LOG_ER("saClmClusterNodeGetAsync failed: %i", rc); >> + break; >> + } >> + } while (false); >> + >> + if (rc != SA_AIS_OK && cb->clm_hdl) >> + glnd_clm_deinit(cb); >> + >> + return rc; >> + TRACE_LEAVE(); >> +} >> + >> +SaAisErrorT glnd_clm_deinit(GLND_CB *cb) >> +{ >> + SaAisErrorT rc(saClmFinalize(cb->clm_hdl)); >> + >> + if (rc != SA_AIS_OK) >> + LOG_ER("saClmFinalize failed: %i", rc); >> + >> + cb->clm_hdl = 0; >> + >> + return rc; >> +} >> diff --git a/src/lck/lcknd/glnd_clm.h b/src/lck/lcknd/glnd_clm.h >> new file mode 100644 >> index 0000000..dd8ec14 >> --- /dev/null >> +++ b/src/lck/lcknd/glnd_clm.h >> @@ -0,0 +1,17 @@ >> +#ifndef LCK_LCKND_GLND_CLM_H_ >> +#define LCK_LCKND_GLND_CLM_H_ >> + >> +#include "lck/lcknd/glnd.h" >> + >> +#ifdef __cplusplus >> +extern "C" { >> +#endif >> + >> +SaAisErrorT glnd_clm_init(GLND_CB *); >> +SaAisErrorT glnd_clm_deinit(GLND_CB *); >> + >> +#ifdef __cplusplus >> +} >> +#endif >> + >> +#endif // LCK_LCKND_GLND_CLM_H_ >> diff --git a/src/lck/lcknd/glnd_evt.c b/src/lck/lcknd/glnd_evt.c >> index 75351c9..7eaea3a 100644 >> --- a/src/lck/lcknd/glnd_evt.c >> +++ b/src/lck/lcknd/glnd_evt.c >> @@ -71,6 +71,7 @@ dump the cb. >> *********************************************************** >> *******************/ >> >> #include "lck/lcknd/glnd.h" >> +#include "lck/common/glsv_defs.h" >> >> /********************************************************** >> ********************/ >> >> @@ -529,6 +530,20 @@ static uint32_t >> glnd_process_gla_client_initialize(GLND_CB >> *glnd_cb, >> memset(&gla_evt, 0, sizeof(GLSV_GLA_EVT)); >> gla_evt.type = GLSV_GLA_API_RESP_EVT; >> >> + if (m_GLA_VER_IS_AT_LEAST_B_3(client_info->version) && >> + !glnd_cb->isClusterMember) { >> + TRACE_2("gla client initialize failed, node is not >> cluster member"); >> + /* initialise the gla_evt */ >> + gla_evt.error = SA_AIS_ERR_UNAVAILABLE; >> + gla_evt.type = GLSV_GLA_API_RESP_EVT; >> + gla_evt.info.gla_resp_info.type = >> GLSV_GLA_LOCK_INITIALIZE; >> + >> + /* send the evt */ >> + glnd_mds_msg_send_rsp_gla(glnd_cb, &gla_evt, >> client_info->agent_mds_dest, &evt->mds_context); >> + >> + goto end; >> + } >> + >> if (glnd_cb->node_state != GLND_OPERATIONAL_STATE || >> glnd_cb->gld_card_up != true) { >> TRACE_2("gla client initialize failed, glnd state %d", >> @@ -680,6 +695,7 @@ static uint32_t glnd_process_gla_resource_open(GLND_CB >> *glnd_cb, >> GLSV_GLND_EVT *evt) >> { >> GLSV_EVT_RSC_INFO *rsc_info; >> + GLND_CLIENT_INFO *client_info; >> GLND_RESOURCE_INFO *resource_node; >> GLND_RESOURCE_REQ_LIST *res_req_node; >> GLSV_GLA_EVT gla_evt; >> @@ -689,6 +705,52 @@ static uint32_t glnd_process_gla_resource_open(GLND_CB >> *glnd_cb, >> >> rsc_info = (GLSV_EVT_RSC_INFO *)&evt->info.rsc_info; >> >> + /* get the client handle */ >> + client_info = glnd_client_node_find(glnd_cb, >> rsc_info->client_handle_id); >> + if (!client_info) { >> + /* initialise the gla_evt */ >> + memset(&gla_evt, 0, sizeof(GLSV_GLA_EVT)); >> + >> + gla_evt.error = SA_AIS_ERR_BAD_HANDLE; >> + gla_evt.handle = rsc_info->client_handle_id; >> + gla_evt.type = GLSV_GLA_API_RESP_EVT; >> + gla_evt.info.gla_resp_info.type = >> GLSV_GLA_LOCK_RES_CLOSE; >> + glnd_mds_msg_send_rsp_gla(glnd_cb, &gla_evt, >> rsc_info->agent_mds_dest, &evt->mds_context); >> + >> + TRACE_2("GLND Client node find failed"); >> + rc = NCSCC_RC_FAILURE; >> + goto end; >> + } >> + >> + if (m_GLA_VER_IS_AT_LEAST_B_3(client_info->version) && >> + !glnd_cb->isClusterMember) { >> + TRACE_2("resource open failed, node is not cluster >> member"); >> + memset(&gla_evt, 0, sizeof(GLSV_GLA_EVT)); >> + gla_evt.handle = rsc_info->client_handle_id; >> + >> + if (rsc_info->call_type == GLSV_SYNC_CALL) { >> + /* initialise the gla_evt */ >> + gla_evt.error = SA_AIS_ERR_UNAVAILABLE; >> + gla_evt.type = GLSV_GLA_API_RESP_EVT; >> + gla_evt.info.gla_resp_info.type = >> GLSV_GLA_LOCK_RES_OPEN; >> + >> + /* send the evt */ >> + glnd_mds_msg_send_rsp_gla(glnd_cb, &gla_evt, >> rsc_info->agent_mds_dest, &evt->mds_context); >> + >> + goto end; >> + } else { >> + gla_evt.type = GLSV_GLA_CALLBK_EVT; >> + gla_evt.info.gla_clbk_info.callback_type = >> GLSV_LOCK_RES_OPEN_CBK; >> + gla_evt.info.gla_clbk_info.resourceId = >> rsc_info->lcl_resource_id; >> + gla_evt.info.gla_clbk_info.params.res_open.resourceId >> = 0; >> + gla_evt.info.gla_clbk_info.params.res_open.invocation >> = rsc_info->invocation; >> + gla_evt.info.gla_clbk_info.params.res_open.error >> = SA_AIS_ERR_UNAVAILABLE; >> + /* send the evt */ >> + glnd_mds_msg_send_gla(glnd_cb, &gla_evt, >> rsc_info->agent_mds_dest); >> + >> + goto end; >> + } >> + } >> if (glnd_cb->node_state != GLND_OPERATIONAL_STATE || >> glnd_cb->gld_card_up != true) { >> TRACE_2("resource open failed, glnd state %d", >> @@ -927,40 +989,58 @@ static uint32_t glnd_process_gla_resource_close(GLND_CB >> *glnd_cb, >> >> rsc_info = (GLSV_EVT_RSC_INFO *)&evt->info.rsc_info; >> >> - if (glnd_cb->node_state != GLND_OPERATIONAL_STATE || >> - glnd_cb->gld_card_up != true) { >> - TRACE_2("resource close failed, glnd state %d", >> - glnd_cb->node_state); >> + /* get the client handle */ >> + client_info = >> + glnd_client_node_find(glnd_cb, rsc_info->client_handle_id); >> + if (!client_info) { >> /* initialise the gla_evt */ >> memset(&gla_evt, 0, sizeof(GLSV_GLA_EVT)); >> >> - gla_evt.error = SA_AIS_ERR_TRY_AGAIN; >> + gla_evt.error = SA_AIS_ERR_BAD_HANDLE; >> gla_evt.handle = rsc_info->client_handle_id; >> gla_evt.type = GLSV_GLA_API_RESP_EVT; >> gla_evt.info.gla_resp_info.type = >> GLSV_GLA_LOCK_RES_CLOSE; >> glnd_mds_msg_send_rsp_gla(glnd_cb, &gla_evt, >> rsc_info->agent_mds_dest, >> &evt->mds_context); >> + >> + TRACE_2("GLND Client node find failed"); >> + rc = NCSCC_RC_FAILURE; >> goto end; >> } >> >> - /* get the client handle */ >> - client_info = >> - glnd_client_node_find(glnd_cb, rsc_info->client_handle_id); >> - if (!client_info) { >> + if (m_GLA_VER_IS_AT_LEAST_B_3(client_info->version) && >> + !glnd_cb->isClusterMember) { >> + TRACE_2("resource close failed, node is not cluster >> member"); >> + /* initialise the gla_evt */ >> + gla_evt.error = SA_AIS_ERR_UNAVAILABLE; >> + gla_evt.handle = rsc_info->client_handle_id; >> + gla_evt.type = GLSV_GLA_API_RESP_EVT; >> + gla_evt.info.gla_resp_info.type = >> GLSV_GLA_LOCK_RES_CLOSE; >> + >> + glnd_mds_msg_send_rsp_gla(glnd_cb, >> + &gla_evt, >> + rsc_info->agent_mds_dest, >> + &evt->mds_context); >> + >> + goto end; >> + } >> + >> + >> + if (glnd_cb->node_state != GLND_OPERATIONAL_STATE || >> + glnd_cb->gld_card_up != true) { >> + TRACE_2("resource close failed, glnd state %d", >> + glnd_cb->node_state); >> /* initialise the gla_evt */ >> memset(&gla_evt, 0, sizeof(GLSV_GLA_EVT)); >> >> - gla_evt.error = SA_AIS_ERR_BAD_HANDLE; >> + gla_evt.error = SA_AIS_ERR_TRY_AGAIN; >> gla_evt.handle = rsc_info->client_handle_id; >> gla_evt.type = GLSV_GLA_API_RESP_EVT; >> gla_evt.info.gla_resp_info.type = >> GLSV_GLA_LOCK_RES_CLOSE; >> glnd_mds_msg_send_rsp_gla(glnd_cb, &gla_evt, >> rsc_info->agent_mds_dest, >> &evt->mds_context); >> - >> - TRACE_2("GLND Client node find failed"); >> - rc = NCSCC_RC_FAILURE; >> goto end; >> } >> >> @@ -1088,6 +1168,50 @@ static uint32_t glnd_process_gla_resource_lock(GLND_CB >> *glnd_cb, >> >> rsc_lock_info = (GLSV_EVT_RSC_LOCK_INFO >> *)&evt->info.rsc_lock_info; >> >> + /* get the client handle */ >> + client_info = >> + glnd_client_node_find(glnd_cb, rsc_lock_info->client_handle_i >> d); >> + if (!client_info) { >> + LOG_ER("GLND Client node find failed"); >> + rc = NCSCC_RC_FAILURE; >> + goto end; >> + } >> + >> + if (m_GLA_VER_IS_AT_LEAST_B_3(client_info->version) && >> + !glnd_cb->isClusterMember) { >> + TRACE_2("resource lock failed, node is not cluster >> member"); >> + if (rsc_lock_info->call_type == GLSV_SYNC_CALL) { >> + gla_evt.error = SA_AIS_ERR_UNAVAILABLE; >> + gla_evt.handle = rsc_lock_info->client_handle_id; >> + gla_evt.type = GLSV_GLA_API_RESP_EVT; >> + gla_evt.info.gla_resp_info.type = >> GLSV_GLA_LOCK_SYNC_LOCK; >> + >> + glnd_mds_msg_send_rsp_gla(glnd_cb, >> + &gla_evt, >> + rsc_lock_info->agent_mds_dest, >> + &evt->mds_context); >> + >> + rc = NCSCC_RC_FAILURE; >> + goto end; >> + } else { >> + m_GLND_RESOURCE_ASYNC_LCK_GRANT_FILL( >> + gla_evt, >> + SA_AIS_ERR_UNAVAILABLE, >> + 0, >> + rsc_lock_info->lcl_lockid, >> + rsc_lock_info->lock_type, >> + rsc_lock_info->lcl_resource_id, >> + rsc_lock_info->invocation, >> + 0, >> + rsc_lock_info->client_handle_id); >> + >> + /* send the evt to GLA */ >> + glnd_mds_msg_send_gla(glnd_cb, &gla_evt, >> rsc_lock_info->agent_mds_dest); >> + rc = NCSCC_RC_FAILURE; >> + goto end; >> + } >> + } >> + >> /* check for the resource node */ >> res_node = glnd_resource_node_find(glnd_cb, >> rsc_lock_info->resource_id); >> if (!res_node) { >> @@ -1131,15 +1255,6 @@ static uint32_t glnd_process_gla_resource_lock(GLND_CB >> *glnd_cb, >> } >> } >> >> - /* get the client handle */ >> - client_info = >> - glnd_client_node_find(glnd_cb, rsc_lock_info->client_handle_i >> d); >> - if (!client_info) { >> - LOG_ER("GLND Client node find failed"); >> - rc = NCSCC_RC_FAILURE; >> - goto end; >> - } >> - >> gla_evt.handle = rsc_lock_info->client_handle_id; >> >> if (res_node->status == GLND_RESOURCE_NOT_INITIALISED) { >> @@ -1347,6 +1462,42 @@ static uint32_t >> glnd_process_gla_resource_unlock(GLND_CB >> *glnd_cb, >> (GLSV_EVT_RSC_UNLOCK_INFO *)&evt->info.rsc_unlock_info; >> memset(&lck_info, 0, sizeof(GLSV_LOCK_REQ_INFO)); >> >> + /* get the client handle */ >> + client_info = >> + glnd_client_node_find(glnd_cb, rsc_unlock_info->client_handle >> _id); >> + if (!client_info) { >> + LOG_ER("GLND Client node find failed"); >> + goto end; >> + } >> + >> + if (m_GLA_VER_IS_AT_LEAST_B_3(client_info->version) && >> + !glnd_cb->isClusterMember) { >> + TRACE_2("resource unlock failed, node is not cluster >> member"); >> + if (rsc_unlock_info->call_type == GLSV_SYNC_CALL) { >> + gla_evt.error = SA_AIS_ERR_UNAVAILABLE; >> + gla_evt.handle = rsc_unlock_info->client_handle_id; >> + gla_evt.type = GLSV_GLA_API_RESP_EVT; >> + gla_evt.info.gla_resp_info.type = >> GLSV_GLA_LOCK_SYNC_UNLOCK; >> + >> + glnd_mds_msg_send_rsp_gla(glnd_cb, >> + &gla_evt, >> + rsc_unlock_info->agent_mds_dest, >> + &evt->mds_context); >> + >> + goto end; >> + } else { >> + m_GLND_RESOURCE_ASYNC_LCK_UNLOCK_FILL(gla_evt, >> SA_AIS_ERR_UNAVAILABLE, >> + >> rsc_unlock_info->invocation, >> + >> rsc_unlock_info->lcl_resource_id, >> + >> rsc_unlock_info->lcl_lockid, 0); >> + gla_evt.handle = rsc_unlock_info->client_handle >> _id; >> + >> + /* send the evt to GLA */ >> + glnd_mds_msg_send_gla(glnd_cb, &gla_evt, >> rsc_unlock_info->agent_mds_dest); >> + goto end; >> + } >> + } >> + >> /* get the resource node */ >> res_node = >> glnd_resource_node_find(glnd_cb, >> rsc_unlock_info->resource_id); >> @@ -1390,14 +1541,6 @@ static uint32_t >> glnd_process_gla_resource_unlock(GLND_CB >> *glnd_cb, >> } >> } >> >> - /* get the client handle */ >> - client_info = >> - glnd_client_node_find(glnd_cb, rsc_unlock_info->client_handle >> _id); >> - if (!client_info) { >> - LOG_ER("GLND Client node find failed"); >> - goto end; >> - } >> - >> if (res_node->status == GLND_RESOURCE_NOT_INITIALISED) { >> /* sleep for relection time and resend the event */ >> uint32_t tm = GLSV_GLND_MASTER_REELECTION_WAIT_TIME / >> 10000000; >> @@ -1609,6 +1752,7 @@ static uint32_t glnd_process_gla_resource_purge(GLND_CB >> *glnd_cb, >> { >> GLSV_EVT_RSC_INFO *rsc_info; >> GLND_RESOURCE_INFO *res_node = NULL; >> + GLND_CLIENT_INFO *client_info; >> rsc_info = (GLSV_EVT_RSC_INFO *)&evt->info.rsc_info; >> GLSV_GLA_EVT gla_evt; >> SaAisErrorT error = SA_AIS_ERR_LIBRARY; >> @@ -1618,6 +1762,44 @@ static uint32_t >> glnd_process_gla_resource_purge(GLND_CB >> *glnd_cb, >> memset(&gla_evt, 0, sizeof(GLSV_GLA_EVT)); >> gla_evt.type = GLSV_GLA_API_RESP_EVT; >> >> + /* get the client handle */ >> + client_info = glnd_client_node_find(glnd_cb, >> rsc_info->client_handle_id); >> + if (!client_info) { >> + /* initialise the gla_evt */ >> + memset(&gla_evt, 0, sizeof(GLSV_GLA_EVT)); >> + >> + gla_evt.error = SA_AIS_ERR_BAD_HANDLE; >> + gla_evt.handle = rsc_info->client_handle_id; >> + gla_evt.type = GLSV_GLA_API_RESP_EVT; >> + gla_evt.info.gla_resp_info.type = >> GLSV_GLA_LOCK_RES_CLOSE; >> + glnd_mds_msg_send_rsp_gla(glnd_cb, >> + &gla_evt, >> + rsc_info->agent_mds_dest, >> + &evt->mds_context); >> + >> + TRACE_2("GLND Client node find failed"); >> + rc = NCSCC_RC_FAILURE; >> + goto end; >> + } >> + >> + if (m_GLA_VER_IS_AT_LEAST_B_3(client_info->version) && >> + !glnd_cb->isClusterMember) { >> + TRACE_2("resource purge failed, node is not cluster >> member"); >> + /* initialise the gla_evt */ >> + gla_evt.error = SA_AIS_ERR_UNAVAILABLE; >> + gla_evt.handle = rsc_info->client_handle_id; >> + gla_evt.type = GLSV_GLA_API_RESP_EVT; >> + gla_evt.info.gla_resp_info.type = >> GLSV_GLA_LOCK_INITIALIZE; >> + >> + /* send the evt */ >> + glnd_mds_msg_send_rsp_gla(glnd_cb, >> + &gla_evt, >> + rsc_info->agent_mds_dest, >> + &evt->mds_context); >> + >> + goto end; >> + } >> + >> /* get the resource node */ >> res_node = glnd_resource_node_find(glnd_cb, >> rsc_info->resource_id); >> if (!res_node) { >> @@ -2336,6 +2518,14 @@ static uint32_t >> glnd_process_glnd_lck_waiter_clbk(GLND_CB >> *glnd_cb, >> >> waiter_clbk = (GLSV_EVT_GLND_LCK_INFO *)&evt->info.node_lck_info; >> >> + /* don't send the callback if we are not a cluster member */ >> + if (!glnd_cb->isClusterMember) { >> + TRACE("not sending waiter callback because this node is not in the " >> + "cluster"); >> + rc = NCSCC_RC_FAILURE; >> + goto end; >> + } >> + >> res_node = glnd_resource_node_find(glnd_cb, >> waiter_clbk->resource_id); >> if (!res_node) { >> LOG_ER("GLND Rsc node find failed"); >> diff --git a/src/lck/lcknd/glnd_mds.c b/src/lck/lcknd/glnd_mds.c >> index 7f4a692..69ac0c1 100644 >> --- a/src/lck/lcknd/glnd_mds.c >> +++ b/src/lck/lcknd/glnd_mds.c >> @@ -68,6 +68,7 @@ static uint32_t glsv_gla_enc_callbk_evt(NCS_UBAID *uba, >> GLSV_GLA_CALLBACK_INFO *evt); >> static uint32_t glsv_gla_enc_api_resp_evt(NCS_UBAID *uba, >> GLSV_GLA_API_RESP_INFO *evt); >> +static uint32_t glsv_gla_enc_clm_evt(NCS_UBAID *uba, GLSV_GLA_CLM_INFO >> *evt); >> >> uint32_t glnd_mds_get_handle(GLND_CB *cb); >> >> @@ -382,6 +383,10 @@ static uint32_t glnd_mds_enc(GLND_CB *cb, >> MDS_CALLBACK_ENC_INFO *info) >> uba, &evt->info.gla_resp_info); >> break; >> >> + case GLSV_GLA_CLM_EVT: >> + rc = glsv_gla_enc_clm_evt(uba, >> &evt->info.gla_clm_info); >> + break; >> + >> default: >> goto end; >> } >> @@ -1652,3 +1657,37 @@ static uint32_t glsv_gla_enc_api_resp_evt(NCS_UBAID >> *uba, >> >> return NCSCC_RC_SUCCESS; >> } >> + >> +/********************************************************** >> ****************** >> + Name : glsv_gla_enc_clm_evt >> + >> + Description : This routine encodes api response info. >> + >> + Arguments : uba , api response info. >> + >> + Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE >> + >> + Notes : None. >> +*********************************************************** >> *******************/ >> +static uint32_t glsv_gla_enc_clm_evt(NCS_UBAID *uba, GLSV_GLA_CLM_INFO >> *evt) >> +{ >> + uint8_t *p8, size; >> + uint32_t rc = NCSCC_RC_SUCCESS; >> + >> + do { >> + size = (4); >> + /** encode the type of message **/ >> + p8 = ncs_enc_reserve_space(uba, size); >> + if (!p8) { >> + TRACE_2("GLND enc failed"); >> + rc = NCSCC_RC_FAILURE; >> + break; >> + } >> + >> + osaf_encode_bool(uba, evt->isClusterMember); >> + >> + ncs_enc_claim_space(uba, size); >> + } while (false); >> + >> + return rc; >> +} >> diff --git a/src/lck/lcknd/glnd_mds.h b/src/lck/lcknd/glnd_mds.h >> index e258a3f..d7c47b1 100644 >> --- a/src/lck/lcknd/glnd_mds.h >> +++ b/src/lck/lcknd/glnd_mds.h >> @@ -30,6 +30,10 @@ >> #ifndef LCK_LCKND_GLND_MDS_H_ >> #define LCK_LCKND_GLND_MDS_H_ >> >> +#ifdef __cplusplus >> +extern "C" { >> +#endif >> + >> /********************************************************** >> *******************/ >> >> #define SVC_SUBPART_VER uns32 >> @@ -175,4 +179,8 @@ typedef uint32_t (*GLSV_GLND_EVT_HANDLER)(struct >> glnd_cb_tag *, >> (l_evt).info.gla_clbk_info.params.unlock.error = (l_err); >> \ >> } while (0); >> >> +#ifdef __cplusplus >> +} >> +#endif >> + >> #endif // LCK_LCKND_GLND_MDS_H_ >> diff --git a/src/lck/lcknd/glnd_res.c b/src/lck/lcknd/glnd_res.c >> index 4e4f47a..90f6770 100644 >> --- a/src/lck/lcknd/glnd_res.c >> +++ b/src/lck/lcknd/glnd_res.c >> @@ -1396,6 +1396,10 @@ static void glnd_master_process_lock_initi >> ate_waitercallbk( >> >> lock_list_info->req_mdest_id); >> >> } else { >> + /* don't send the callback if we are not a cluster member */ >> + if (!cb->isClusterMember) >> + break; >> + >> GLSV_GLA_EVT gla_evt; >> GLND_CLIENT_INFO *client_info; >> /* send it to the local GLA component */ >> diff --git a/src/lck/lcknd/glnd_res_req.c b/src/lck/lcknd/glnd_res_req.c >> index 7d3e5e9..1490ba5 100644 >> --- a/src/lck/lcknd/glnd_res_req.c >> +++ b/src/lck/lcknd/glnd_res_req.c >> @@ -171,3 +171,53 @@ void glnd_resource_req_node_del(GLND_CB *glnd_cb, >> uint32_t res_req_hdl) >> } >> return; >> } >> + >> +/********************************************************** >> ******************* >> + PROCEDURE NAME : glnd_resource_req_node_down >> + >> + DESCRIPTION : Sends callback responses to outstanding requests from >> node >> + down >> + >> + ARGUMENTS :glnd_cb - ptr to the GLND control block >> + >> + >> + RETURNS :The pointer to the resource req node info on success. >> + else returns NULL. >> + >> + NOTES : Delete the returned pointer immediately. >> +*********************************************************** >> ******************/ >> +void glnd_resource_req_node_down(GLND_CB *glnd_cb) >> +{ >> + GLND_RESOURCE_REQ_LIST *res_req_info; >> + >> + for (res_req_info = glnd_cb->res_req_list; >> + res_req_info; >> + res_req_info = res_req_info->next) { >> + GLSV_GLA_EVT gla_evt; >> + >> + if (res_req_info->call_type == GLSV_SYNC_CALL) { >> + glnd_stop_tmr(&res_req_info->timeout); >> + >> + gla_evt.error = SA_AIS_ERR_UNAVAILABLE; >> + gla_evt.handle = res_req_info->client_handle_id; >> + gla_evt.type = GLSV_GLA_API_RESP_EVT; >> + gla_evt.info.gla_resp_info.type = GLSV_GLA_LOCK_RES_OPEN; >> + >> + glnd_mds_msg_send_rsp_gla(glnd_cb, >> + &gla_evt, >> + res_req_info->agent_mds_dest, >> + &res_req_info->glnd_res_mds_ctxt); >> + } else if (res_req_info->call_type == GLSV_ASYNC_CALL) { >> + gla_evt.type = GLSV_GLA_CALLBK_EVT; >> + gla_evt.info.gla_clbk_info.callback_type = GLSV_LOCK_RES_OPEN_CBK; >> + gla_evt.info.gla_clbk_info.resourceId = >> res_req_info->lcl_resource_id; >> + gla_evt.info.gla_clbk_info.params.res_open.resourceId = 0; >> + gla_evt.info.gla_clbk_info.params.res_open.invocation = >> + res_req_info->invocation; >> + gla_evt.info.gla_clbk_info.params.res_open.error = >> SA_AIS_ERR_UNAVAILABLE; >> + >> + glnd_mds_msg_send_gla(glnd_cb, &gla_evt, >> res_req_info->agent_mds_dest); >> + } >> + } >> +} >> + >> -- >> 2.7.4 >> >> > ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ Opensaf-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/opensaf-devel
