osaf/services/saf/logsv/lgs/Makefile.am |    4 +-
 osaf/services/saf/logsv/lgs/lgs.h       |    5 +
 osaf/services/saf/logsv/lgs/lgs_cb.h    |   15 +++
 osaf/services/saf/logsv/lgs/lgs_evt.cc  |  142 ++++++++++++++++++++++++++++++++
 osaf/services/saf/logsv/lgs/lgs_evt.h   |    1 +
 osaf/services/saf/logsv/lgs/lgs_main.cc |   29 ++++++
 osaf/services/saf/logsv/lgs/lgs_mds.cc  |   41 ++++++++-
 osaf/services/saf/logsv/lgs/lgs_util.cc |   83 ++++++++++++++++++
 8 files changed, 317 insertions(+), 3 deletions(-)


Description:

Form CLM integration is supported from Log Service A.02.02.

At-least a A.02.02 LGA client will check CLM membership status of client's node.
 old LGA clients A.02.01 are always clm member.

This patch enhanced the log service for Unavailability of the Log Service API 
on a
Non-Member Node which will fail with SA_AIS_ERR_UNAVAILABLE.

After this patch the Log Service does not provide service to processes on 
cluster nodes that are not
in the cluster membership.

If the node rejoins the cluster membership, processes executing on the node 
will be
able to reinitialize new library handles and use the entire set of Log Service 
APIs that
operate on these new handles; however, invocation of APIs that operate on 
handles
acquired by any process before the node left the membership will continue to 
fail with
SA_AIS_ERR_UNAVAILABLE (or with the special treatment described above for
asynchronous calls) with the exception of saLogFinalize(), which is used to 
free the
library handles and all resources associated with these handles. Hence, it is 
recommended
for the processes to finalize the library handles as soon as the processes
detect that the node left the membership.

Detailed README will be provide soon.

Following are expected Log Service API behavior :

Case1: On Non-Member Node,  Log Service API will fail with code 
SA_AIS_ERR_UNAVAILABLE (31)
Case2: On Member Node after recovered from Non-Member Node, Log Service API 
will fail with code SA_AIS_ERR_UNAVAILABLE (31)
Case3: Non-Member Node + (Headless) Log Service API will fail with code 
SA_AIS_ERR_UNAVAILABLE (31)
Case4: On Non-Member Node + (Headless) + (Head Joined) Log Service API will 
fail with code SA_AIS_ERR_UNAVAILABLE (31)

diff --git a/osaf/services/saf/logsv/lgs/Makefile.am 
b/osaf/services/saf/logsv/lgs/Makefile.am
--- a/osaf/services/saf/logsv/lgs/Makefile.am
+++ b/osaf/services/saf/logsv/lgs/Makefile.am
@@ -67,7 +67,8 @@ osaflogd_SOURCES = \
        lgs_mbcsv_v3.cc \
        lgs_mbcsv_v5.cc \
        lgs_recov.cc \
-       lgs_imm_gcfg.cc
+       lgs_imm_gcfg.cc \
+       lgs_clm.cc
 
 osaflogd_LDADD = \
        $(top_builddir)/osaf/tools/safimm/src/libimmutil.la \
@@ -75,4 +76,5 @@ osaflogd_LDADD = \
        $(top_builddir)/osaf/libs/saf/libSaAmf/libSaAmf.la \
        $(top_builddir)/osaf/libs/saf/libSaImm/libSaImmOi.la \
        $(top_builddir)/osaf/libs/saf/libSaImm/libSaImmOm.la \
+       $(top_builddir)/osaf/libs/saf/libSaClm/libSaClm.la \
        $(top_builddir)/osaf/libs/agents/infrastructure/rda/librda.la
diff --git a/osaf/services/saf/logsv/lgs/lgs.h 
b/osaf/services/saf/logsv/lgs/lgs.h
--- a/osaf/services/saf/logsv/lgs/lgs.h
+++ b/osaf/services/saf/logsv/lgs/lgs.h
@@ -33,6 +33,7 @@
 #include <saAis.h>
 #include <saf_error.h>
 #include <saImmOm.h>
+#include <saClm.h>
 #include "saAmf.h"
 
 /* LGS files */
@@ -78,6 +79,7 @@
 #define LGS_LOG_SHARED_FILESYSTEM 1            /* Use shared filesystem. 
Default */
 #define LGS_LOG_SPLIT_FILESYSTEM  2     /* Store logs on local file system on
                                            each node */
+#define m_LGS_GET_NODE_ID_FROM_ADEST(adest) (NODE_ID) ((uint64_t)adest >> 32)
 
 /* ========================================================================
  *   DATA DECLARATIONS
@@ -131,4 +133,7 @@ int lgs_get_streamobj_attr(SaImmAttrValu
                           SaImmHandleT *immOmHandle);
 int lgs_free_streamobj_attr(SaImmHandleT immHandle);
 
+extern uint32_t send_clm_node_status_change(SaClmClusterChangesT 
cluster_change, NODE_ID node_id);
+extern void lgs_init_with_clm(void);
+
 #endif   /* ifndef __LGS_H */
diff --git a/osaf/services/saf/logsv/lgs/lgs_cb.h 
b/osaf/services/saf/logsv/lgs/lgs_cb.h
--- a/osaf/services/saf/logsv/lgs/lgs_cb.h
+++ b/osaf/services/saf/logsv/lgs/lgs_cb.h
@@ -21,6 +21,7 @@
 #include <stdbool.h>
 #include <saLog.h>
 #include <saImmOi.h>
+#include <saClm.h>
 #include <mbcsv_papi.h>
 #include <ncs_edu_pub.h>
 
@@ -55,6 +56,11 @@ typedef struct lgs_stream_list {
 } lgs_stream_list_t;
 
 typedef struct {
+       NCS_PATRICIA_NODE patnode;
+       NODE_ID node_id;
+} lgs_clm_node_t;
+
+typedef struct {
        NCS_PATRICIA_NODE pat_node;
        uint32_t client_id;
        uint32_t client_id_net;
@@ -73,6 +79,7 @@ typedef struct lgs_cb {
        MDS_DEST vaddr;         /* My identification in MDS                  */
        SaVersionT log_version; /* The version currently supported           */
        NCS_PATRICIA_TREE client_tree;  /* LGA/Library/Client instantiation 
pat. tree */
+       NCS_PATRICIA_TREE clm_node_tree;  /* LGA/Library/Client instantiation 
pat. tree */
        SaNameT comp_name;      /* Components's name LGS                     */
        SaAmfHandleT amf_hdl;   /* AMF handle, obtained thru AMF init        */
        SaSelectionObjectT amfSelectionObject;  /* Selection Object to wait for 
AMF events */
@@ -80,6 +87,9 @@ typedef struct lgs_cb {
        bool is_quiesced_set;
        SaImmOiHandleT immOiHandle;     /* IMM OI handle                        
   */
        SaSelectionObjectT immSelectionObject;  /* Selection Object to wait for 
IMM events */
+       SaSelectionObjectT clmSelectionObject;  /* Selection Object to wait for 
clms events */
+       SaClmHandleT clm_hdl;   /* CLM handle, obtained through CLM init        
*/
+       bool clm_initialized; //For CLM init status;
        SaAmfHAStateT ha_state; /* present AMF HA state of the component     */
        uint32_t last_client_id;        /* Value of last client_id assigned     
     */
        uint32_t async_upd_cnt; /* Async Update Count for Warmsync */
@@ -94,6 +104,7 @@ typedef struct lgs_cb {
                                                    down events Processing */
        LGA_DOWN_LIST *lga_down_list_tail;
 
+       NCS_SEL_OBJ usr2_sel_obj; /* Selection object for CLM initialization.*/
        bool nid_started;       /**< true if started by NID */
        SaUint32T scAbsenceAllowed; /* OpenSAF global configuration for 
recovery handling */
        lgs_state_t lgs_recovery_state; /* Indicate current recovery state for 
the server */
@@ -106,5 +117,9 @@ typedef struct lgs_cb {
 extern uint32_t lgs_cb_init(lgs_cb_t *);
 extern void lgs_process_mbx(SYSF_MBX *mbx);
 extern uint32_t lgs_stream_add(lgs_cb_t *cb, log_stream_t *stream);
+extern uint32_t lgs_clm_node_del(NODE_ID node_id);
+extern uint32_t lgs_clm_node_add(NODE_ID node_id);
+extern uint32_t lgs_clm_node_find(NODE_ID node_id);
+extern bool is_client_clm_member(NODE_ID node_id, SaVersionT *ver);
 
 #endif
diff --git a/osaf/services/saf/logsv/lgs/lgs_evt.cc 
b/osaf/services/saf/logsv/lgs/lgs_evt.cc
--- a/osaf/services/saf/logsv/lgs/lgs_evt.cc
+++ b/osaf/services/saf/logsv/lgs/lgs_evt.cc
@@ -56,6 +56,94 @@ LGSV_LGS_LGA_API_MSG_HANDLER lgs_lga_api
 };
 
 /**
+ * Name          : lgs_clm_node_tree_init
+ * Description   : This routine is used to initialize the clm_node_tree
+ * Arguments     : lgs_cb - pointer to the lgs Control Block
+ * Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE
+ * Notes         : None
+ */
+uint32_t lgs_clm_node_tree_init(lgs_cb_t *lgs_cb)
+{
+       TRACE_ENTER();
+       NCS_PATRICIA_PARAMS param;
+       memset(&param, 0, sizeof(NCS_PATRICIA_PARAMS));
+
+       param.key_size = sizeof(NODE_ID);
+       if (ncs_patricia_tree_init(&lgs_cb->clm_node_tree, &param) != 
NCSCC_RC_SUCCESS) {
+               LOG_ER("lgs patricia tee init failed for clm_node_tree");
+               return NCSCC_RC_FAILURE;
+       }
+       TRACE_LEAVE();
+       return NCSCC_RC_SUCCESS;
+}
+
+/**
+ * Name          : lgs_clm_node_get
+ * Description   : This routine finds the clm_node .
+ * Arguments     : node_id - CLM Node id
+ * Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE
+ * Notes         : None
+ */
+uint32_t lgs_clm_node_find(NODE_ID node_id)
+{
+       uint32_t rc = NCSCC_RC_FAILURE;
+       lgs_clm_node_t *clm_node = (lgs_clm_node_t *)
+               ncs_patricia_tree_get(&lgs_cb->clm_node_tree, (uint8_t 
*)&node_id);
+
+       if (clm_node !=  NULL)
+               rc = NCSCC_RC_SUCCESS;
+       else 
+               TRACE("node_id find in DB failed : %x",node_id);
+
+       return rc;
+}
+
+/**
+ * Name          : lgs_clm_node_add
+ * Description   : This routine adds the new node to clm_node_tree.
+ * Arguments     : node_id - CLM Node id
+ * Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE
+ * Notes         : None 
+ */
+uint32_t lgs_clm_node_add(NODE_ID node_id)
+{
+       TRACE_ENTER();
+       uint32_t rc = NCSCC_RC_FAILURE;
+       lgs_clm_node_t *clm_node;
+
+       clm_node = (lgs_clm_node_t *) malloc(sizeof(lgs_clm_node_t));
+       clm_node->node_id = node_id;
+       clm_node->patnode.key_info = (uint8_t *)&clm_node->node_id;
+       rc = ncs_patricia_tree_add(&lgs_cb->clm_node_tree, (NCS_PATRICIA_NODE 
*)&clm_node->patnode);
+       if (rc != NCSCC_RC_SUCCESS)
+               TRACE("node_id add to DB failed : %x",node_id);
+       TRACE_LEAVE();
+       return rc;
+}
+
+/**
+ * Name          : lgs_clm_node_del
+ * Description   : Function to Delete the clm_node.
+ * Arguments     : node_id - CLM Node id
+ * Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE 
+ * Notes         : None.
+ */
+uint32_t lgs_clm_node_del(NODE_ID node_id)
+{
+        TRACE_ENTER();
+        uint32_t rc = NCSCC_RC_FAILURE;
+ 
+        lgs_clm_node_t *clm_node = (lgs_clm_node_t *)
+            ncs_patricia_tree_get(&lgs_cb->clm_node_tree, (uint8_t *)&node_id);
+        if (clm_node != NULL)
+                rc = ncs_patricia_tree_del(&lgs_cb->clm_node_tree, 
(NCS_PATRICIA_NODE *)&clm_node->patnode);
+       if (rc != NCSCC_RC_SUCCESS)
+                TRACE("node_id delete to DB failed : %x",node_id);
+        TRACE_LEAVE();
+        return rc;
+}
+
+/**
  * Get client record from client ID
  * @param client_id
  * 
@@ -583,6 +671,9 @@ uint32_t lgs_cb_init(lgs_cb_t *lgs_cb)
        lgs_cb->amfSelectionObject = -1;
        lgs_cb->immSelectionObject = -1;
        lgs_cb->mbcsv_sel_obj = -1;
+       lgs_cb->clm_hdl = 0;
+       lgs_cb->clm_initialized = false;
+       lgs_cb->clmSelectionObject = -1;
 
        /* Assign Version. Currently, hardcoded, This will change later */
        lgs_cb->log_version.releaseCode = LOG_RELEASE_CODE;
@@ -598,6 +689,12 @@ uint32_t lgs_cb_init(lgs_cb_t *lgs_cb)
        if (NCSCC_RC_SUCCESS != ncs_patricia_tree_init(&lgs_cb->client_tree, 
&reg_param))
                return NCSCC_RC_FAILURE;
 
+       /* Initialize patricia tree for CLM Node list */
+       if (NCSCC_RC_SUCCESS != lgs_clm_node_tree_init(lgs_cb)) {
+               LOG_ER("LGS: ncs_patricia_tree_init FAILED");
+               return NCSCC_RC_FAILURE;
+       }
+
        done:
        TRACE_LEAVE();
        return rc;
@@ -637,6 +734,12 @@ static uint32_t proc_initialize_msg(lgs_
                goto snd_rsp;
        }
 
+       if (is_client_clm_member(evt->fr_node_id, version) != true){
+               ais_rc = SA_AIS_ERR_UNAVAILABLE;
+               TRACE("client not a CLM member FAILED");
+               goto snd_rsp;
+       }
+
        if ((client = lgs_client_new(evt->fr_dest, 0, NULL)) == NULL) {
                ais_rc = SA_AIS_ERR_NO_MEMORY;
                goto snd_rsp;
@@ -1451,3 +1554,42 @@ void lgs_process_mbx(SYSF_MBX *mbx)
                lgs_evt_destroy(msg);
        }
 }
+
+/**
+ * @brief  Sends CLM membership status of the node to all the clients
+ *         on the node except A11 clients.
+ * @param  cluster_change (CLM membership status of node).
+ * @param  NCS node_id.
+ * @return NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE.
+ */
+uint32_t send_cluster_membership_msg_to_clients(SaClmClusterChangesT 
cluster_change, NODE_ID node_id) {
+       uint32_t rc = NCSCC_RC_SUCCESS;
+       log_client_t *rp = NULL;
+       uint32_t client_id_net;
+
+       TRACE_ENTER();
+       TRACE_3("node_id: %x, change:%u", node_id, cluster_change);
+
+       rp = reinterpret_cast<log_client_t 
*>(ncs_patricia_tree_getnext(&lgs_cb->client_tree, NULL));
+
+       while (rp != NULL) {
+               /** Store the client_id_net for get Next  */
+               client_id_net = rp->client_id_net;
+               NODE_ID tmp_node_id = 
m_LGS_GET_NODE_ID_FROM_ADEST(rp->mds_dest);
+               //Do not send to A11 client. Send only to specific Node
+               if (tmp_node_id == node_id)
+                       rc = send_clm_node_status_lib(cluster_change, 
rp->client_id, rp->mds_dest);
+
+               rp = reinterpret_cast<log_client_t *>(ncs_patricia_tree_getnext(
+                                       &lgs_cb->client_tree, 
reinterpret_cast<uint8_t *>(&client_id_net)));
+       }
+
+       TRACE_LEAVE();
+       return rc;
+}
+
+uint32_t send_clm_node_status_change(SaClmClusterChangesT cluster_change, 
NODE_ID node_id) {
+       return (send_cluster_membership_msg_to_clients(cluster_change, 
node_id));
+
+}
+
diff --git a/osaf/services/saf/logsv/lgs/lgs_evt.h 
b/osaf/services/saf/logsv/lgs/lgs_evt.h
--- a/osaf/services/saf/logsv/lgs/lgs_evt.h
+++ b/osaf/services/saf/logsv/lgs/lgs_evt.h
@@ -77,6 +77,7 @@ extern bool lgs_lga_entry_valid(lgs_cb_t
 extern uint32_t lgs_remove_lga_down_rec(lgs_cb_t *cb, MDS_DEST mds_dest);
 extern void lgs_send_write_log_ack(uint32_t client_id, SaInvocationT 
invocation, SaAisErrorT error, MDS_DEST mds_dest);
 extern void lgs_free_write_log(const lgsv_write_log_async_req_t *param);
+extern uint32_t send_clm_node_status_lib(SaClmClusterChangesT cluster_change, 
unsigned int client_id, MDS_DEST mdsDest);
 
 SaAisErrorT create_new_app_stream(
                lgsv_stream_open_req_t *open_sync_param,
diff --git a/osaf/services/saf/logsv/lgs/lgs_main.cc 
b/osaf/services/saf/logsv/lgs/lgs_main.cc
--- a/osaf/services/saf/logsv/lgs/lgs_main.cc
+++ b/osaf/services/saf/logsv/lgs/lgs_main.cc
@@ -49,6 +49,7 @@ enum {
        FD_MBCSV,
        FD_MBX,
        FD_CLTIMER,
+       FD_CLM,
        FD_IMM,         /* Must be the last in the fds array */
        FD_NUM
 };
@@ -332,6 +333,14 @@ static uint32_t log_initialize(void)
                goto done;
        }
 
+       /* Create a CLM selection object */
+       if (lgs_cb->nid_started &&
+                        (rc = ncs_sel_obj_create(&lgs_cb->usr2_sel_obj)) != 
NCSCC_RC_SUCCESS)
+        {
+                LOG_ER("lgsv: CLM ncs_sel_obj_create failed");
+                goto done;
+        }
+
        /*
         * Initialize a signal handler that will use the selection object.
         * The signal is sent from our script when AMF does instantiate.
@@ -501,6 +510,9 @@ int main(int argc, char *argv[])
        fds[FD_IMM].fd = lgs_cb->immSelectionObject;
        fds[FD_IMM].events = POLLIN;
 
+       lgs_cb->clmSelectionObject = lgs_cb->nid_started ?
+               lgs_cb->usr2_sel_obj.rmv_obj : -1;
+
        while (1) {
                if (cltimer_fd < 0 && log_rtobj_list_no() != 0) {
                        /* Needed only if any "lost" objects are found
@@ -513,6 +525,8 @@ int main(int argc, char *argv[])
                fds[FD_CLTIMER].events = POLLIN;
                fds[FD_MBCSV].fd = lgs_cb->mbcsv_sel_obj;
                fds[FD_MBCSV].events = POLLIN;
+               fds[FD_CLM].fd = lgs_cb->clmSelectionObject;
+               fds[FD_CLM].events = POLLIN;
 
                /* Protect since the reinit thread may be in the process of
                 * changing the values
@@ -567,6 +581,21 @@ int main(int argc, char *argv[])
                        }
                }
 
+               if (fds[FD_CLM].revents & POLLIN) {
+                       if (lgs_cb->clm_hdl != 0) {
+                               if ((error = saClmDispatch(lgs_cb->clm_hdl, 
SA_DISPATCH_ALL)) != SA_AIS_OK) {
+                                       LOG_ER("saClmDispatch failed: %u", 
error);
+                                       break;
+                               }
+                       } else {
+                               TRACE("SIGUSR2 event rec");
+                               ncs_sel_obj_rmv_ind(&lgs_cb->usr2_sel_obj, 
true, true);
+                               ncs_sel_obj_destroy(&lgs_cb->usr2_sel_obj);     
                        
+                               lgs_cb->clmSelectionObject = -1;
+                               lgs_init_with_clm();
+                       }
+               }
+
                if (fds[FD_CLTIMER].revents & POLLIN) {
                        /* To avoid 'stray objects', after a timeout all runtime
                         * objects that has not been restored shall be deleted
diff --git a/osaf/services/saf/logsv/lgs/lgs_mds.cc 
b/osaf/services/saf/logsv/lgs/lgs_mds.cc
--- a/osaf/services/saf/logsv/lgs/lgs_mds.cc
+++ b/osaf/services/saf/logsv/lgs/lgs_mds.cc
@@ -763,11 +763,19 @@ static uint32_t mds_enc(struct ncsmds_ca
                                goto err;
                        }
                        ncs_encode_32bit(&p8, 
msg->info.cbk_info.write_cbk.error);
+                       TRACE_8("LGSV_WRITE_LOG_CALLBACK_IND");
+               } else if (msg->info.cbk_info.type == 
LGSV_CLM_NODE_STATUS_CALLBACK) {
+                       p8 = ncs_enc_reserve_space(uba, 4);
+                       if (!p8) {
+                               TRACE("ncs_enc_reserve_space failed");
+                               goto err;
+                       }
+                       ncs_encode_32bit(&p8, 
msg->info.cbk_info.clm_node_status_cbk.clm_node_status);
+                       TRACE_8("LGSV_CLM_NODE_STATUS_CALLBACK");
                } else {
                        TRACE("unknown callback type %d", 
msg->info.cbk_info.type);
                        goto err;
                }
-               TRACE_8("LGSV_WRITE_LOG_CALLBACK_IND");
        } else {
                TRACE("unknown msg type %d", msg->type);
                goto err;
@@ -1167,7 +1175,18 @@ static uint32_t mds_svc_event(struct ncs
                                osafassert(rc == NCSCC_RC_SUCCESS);
                        }
                }
-       }
+       } else if (info->info.svc_evt.i_svc_id == NCSMDS_SVC_ID_AVD) {
+                if (info->info.svc_evt.i_change == NCSMDS_UP) {
+                        TRACE_8("MDS UP dest: %" PRIx64 ", node ID: %x, 
svc_id: %d",
+                                        info->info.svc_evt.i_dest, 
info->info.svc_evt.i_node_id, info->info.svc_evt.i_svc_id);
+                        //Subscribed for only INTRA NODE, only one ADEST will 
come.
+                        if (m_MDS_DEST_IS_AN_ADEST(info->info.svc_evt.i_dest)) 
{
+                                TRACE_8("AVD ADEST UP");
+                                ncs_sel_obj_ind(&lgs_cb->usr2_sel_obj);
+                        }
+ 
+                }
+        }
 
  done:
        return rc;
@@ -1334,6 +1353,24 @@ uint32_t lgs_mds_init(lgs_cb_t *cb, SaAm
                return rc;
        }
 
+
+       svc = NCSMDS_SVC_ID_AVD;
+        /* Now subscribe for AVD events in MDS. This will be 
+           used for CLM registration.*/
+        memset(&mds_info, '\0', sizeof(NCSMDS_INFO));
+        mds_info.i_mds_hdl = cb->mds_hdl;
+        mds_info.i_svc_id = NCSMDS_SVC_ID_LGS;
+        mds_info.i_op = MDS_SUBSCRIBE;
+        mds_info.info.svc_subscribe.i_scope = NCSMDS_SCOPE_INTRANODE;
+        mds_info.info.svc_subscribe.i_num_svcs = 1;
+        mds_info.info.svc_subscribe.i_svc_ids = &svc;
+ 
+        rc = ncsmds_api(&mds_info);
+        if (rc != NCSCC_RC_SUCCESS) {
+                LOG_ER("MDS for AVD subscribe FAILED");
+                return rc;
+        }
+
        TRACE_LEAVE();
        return rc;
 }
diff --git a/osaf/services/saf/logsv/lgs/lgs_util.cc 
b/osaf/services/saf/logsv/lgs/lgs_util.cc
--- a/osaf/services/saf/logsv/lgs/lgs_util.cc
+++ b/osaf/services/saf/logsv/lgs/lgs_util.cc
@@ -415,6 +415,89 @@ void lgs_send_write_log_ack(uint32_t cli
 }
 
 /**
+ * @brief  Send Membership status of node to a lib on that node.
+ *  
+ * @param SaClmClusterChangesT (CLM status of node) 
+ * @param client_id 
+ * @param mdsDest of client
+ *
+ * @return NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE.
+ */
+uint32_t send_clm_node_status_lib(SaClmClusterChangesT cluster_change, 
unsigned int client_id, MDS_DEST mdsDest)
+{
+       uint32_t rc = NCSCC_RC_SUCCESS;
+       NCSMDS_INFO mds_info = {0};
+       lgsv_msg_t msg;
+
+       TRACE_ENTER();
+       TRACE_3("change:%u, client_id: %u", cluster_change, client_id);
+
+       memset(&msg, 0, sizeof(lgsv_msg_t));
+       msg.type = LGSV_LGS_CBK_MSG;
+       msg.info.cbk_info.type = LGSV_CLM_NODE_STATUS_CALLBACK;
+       msg.info.cbk_info.lgs_client_id = client_id;
+       msg.info.cbk_info.inv = 0;
+       msg.info.cbk_info.clm_node_status_cbk.clm_node_status = cluster_change;
+
+       mds_info.i_mds_hdl = lgs_cb->mds_hdl;
+       mds_info.i_svc_id = NCSMDS_SVC_ID_LGS;
+       mds_info.i_op = MDS_SEND;       
+       mds_info.info.svc_send.i_msg = &msg;
+       mds_info.info.svc_send.i_to_svc = NCSMDS_SVC_ID_LGA;
+       mds_info.info.svc_send.i_priority = MDS_SEND_PRIORITY_HIGH;
+       mds_info.info.svc_send.i_sendtype = MDS_SENDTYPE_SND;
+       mds_info.info.svc_send.info.snd.i_to_dest = mdsDest;
+
+       rc = ncsmds_api(&mds_info);
+       if (rc != NCSCC_RC_SUCCESS)
+               LOG_NO("Failed (%u) to send of WRITE ack to: %" PRIx64, rc, 
mdsDest);
+
+       TRACE_LEAVE();
+        return rc;
+}
+ 
+/**
+ * @brief Checks if LGSV has already initialized with CLM service. 
+ *
+ * @return true/false.
+ */
+bool is_clm_init()
+{
+        return (((lgs_cb->clm_hdl != 0) && (lgs_cb->clm_initialized == true)) 
? true : false);
+}
+
+/**
+ * @brief  Checks CLM membership status of a client.
+ *         A.02.01 clients are always CLM member.
+ * @param  Client MDS_DEST
+ * @param  Client saf version.
+ * @return NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE.
+ */
+bool is_client_clm_member(NODE_ID node_id, SaVersionT *ver) {
+
+  //Before CLM init all clients are clm member.
+  if (is_clm_init() == false)
+    return true;
+
+  TRACE("client Version: %d.%d.%d", ver->releaseCode, ver->majorVersion, 
ver->minorVersion);
+  //CLM integration is supported from A.02.02. So old clients A.02.01 are 
always clm member.
+  if ((ver->releaseCode == LOG_RELEASE_CODE_0) &&
+      (ver->majorVersion == LOG_MAJOR_VERSION_0) &&
+      (ver->minorVersion == LOG_MINOR_VERSION_0))
+    return true;
+  /*
+    It means CLM initialization is successful and this is atleast a A.02.02 
client.
+    So check CLM membership status of client's node.
+  */
+  if (lgs_clm_node_find(node_id) != NCSCC_RC_SUCCESS)
+         return false;
+  else
+         return true;
+}
+
+
+
+/**
  * Free all dynamically allocated memory for a WRITE
  * @param param
  */

------------------------------------------------------------------------------
What NetFlow Analyzer can do for you? Monitors network bandwidth and traffic
patterns at an interface-level. Reveals which users, apps, and protocols are 
consuming the most bandwidth. Provides multi-vendor support for NetFlow, 
J-Flow, sFlow and other flows. Make informed decisions using capacity planning
reports.http://sdm.link/zohodev2dev
_______________________________________________
Opensaf-devel mailing list
Opensaf-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to