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

Reply via email to