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->
> notification[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_
> RESTARTED);
> - }
> - 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_
> mds_dest,
> + &lckListInfo->glnd_res_lock_
> mds_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_
> mds_dest,
> + &lckListInfo->glnd_res_lock_
> mds_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->
> notification[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_
> id);
> + 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_
> id);
> - 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_
> initiate_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