Hi Lennar,
I just incorporated possible comments based on the current code base,
This My fist patch for LOG :) , so I just followed how existing
functions/variables organized like.
I will considered all other inputs while doing complete refracting code
to C++ in a separate ticket soon.
Please see also inline response [AVM]
-AVM
On 8/2/2016 6:30 PM, Lennart Lund wrote:
> Hi
>
> My comments for patch 2
>
> I have found some things that should be considered in order to get as clean
> code as possible:
> 1.
> Functions for handling CLM can be found in several files. It is better to
> collect all CLM handling in the lgs_clm file and just include function calls
> in the rest of the code. Also all functions that shall be globally available
> should have a prototype in the corresponding lgs_clm.h file
[AVM] I will considered all your inputs while doing complete
refracting code to C++ in a separate ticket soon.
> 2.
> New global variables are added to the cb structure. Do not use global
> variables try at least to keep the scope of state variables, flags and other
> variables within the lgs_clm file. Implement setter and getter functions if
> needed or even better functions that are using the variables e.g. like the
> is_client_clm_member() function. This also makes it possible to make these
> functions thread safe (do not use the global cb lock mutex). which means
> that this can be handled in one place instead of all over the code
[AVM] I moved the stuff that is possible based on current code base of
LOG service , i will take care of your suggestions while doing complete
refracting code to C++ in a separate ticket soon.
> 3.
> Take advantage of C++ and make simpler handling of lists. It's no longer
> needed to use patricia tree handling
> Maybe even create a LgsClm class?
[AVM] Same comment was give by Anders Widell as well.
I will do all NCS_PATRICIA_TREE conversion to std::map of
Log service in one go in a separate ticket soon.
>
> See also inline comments [Lennart]
>
> Thanks
> Lennart
>
>> -----Original Message-----
>> From: [email protected] [mailto:[email protected]]
>> Sent: den 2 augusti 2016 10:18
>> To: Vu Minh Nguyen <[email protected]>; Lennart Lund
>> <[email protected]>; Anders Widell <[email protected]>
>> Cc: [email protected]
>> Subject: [PATCH 2 of 3] lgs: director Cluster Membership (CLM) integration
>> [#1638] V2
>>
>> osaf/services/saf/logsv/lgs/Makefile.am | 7 +-
>> osaf/services/saf/logsv/lgs/lgs_cb.h | 15 +++
>> osaf/services/saf/logsv/lgs/lgs_clm.cc | 142
>> +++++++++++++++++++++++++++++++
>> osaf/services/saf/logsv/lgs/lgs_clm.h | 25 +++++
>> osaf/services/saf/logsv/lgs/lgs_evt.cc | 143
>> ++++++++++++++++++++++++++++++++
>> osaf/services/saf/logsv/lgs/lgs_evt.h | 2 +
>> osaf/services/saf/logsv/lgs/lgs_main.cc | 28 ++++++
>> osaf/services/saf/logsv/lgs/lgs_mds.cc | 38 ++++++++-
>> osaf/services/saf/logsv/lgs/lgs_util.cc | 83 ++++++++++++++++++
>> 9 files changed, 480 insertions(+), 3 deletions(-)
>>
>>
>> diff --git a/osaf/services/saf/logsv/lgs/Makefile.am
>> b/osaf/services/saf/logsv/lgs/Makefile.am
>> --- a/osaf/services/saf/logsv/lgs/Makefile.am
>> +++ b/osaf/services/saf/logsv/lgs/Makefile.am
>> @@ -37,7 +37,8 @@ noinst_HEADERS = \
>> lgs_mbcsv_v3.h \
>> lgs_mbcsv_v5.h \
>> lgs_recov.h \
>> - lgs_imm_gcfg.h
>> + lgs_imm_gcfg.h \
>> + lgs_clm.h
>>
>> osaf_execbindir = $(pkglibdir)
>> osaf_execbin_PROGRAMS = osaflogd
>> @@ -67,7 +68,8 @@ osaflogd_SOURCES = \
>> lgs_mbcsv_v3.cc \
>> lgs_mbcsv_v5.cc \
>> lgs_recov.cc \
>> - lgs_imm_gcfg.cc
>> + lgs_imm_gcfg.cc \
>> + lgs_clm.cc
>>
>> osaflogd_LDADD = \
>> $(top_builddir)/osaf/tools/safimm/src/libimmutil.la \
>> @@ -75,4 +77,5 @@ osaflogd_LDADD = \
>> $(top_builddir)/osaf/libs/saf/libSaAmf/libSaAmf.la \
>> $(top_builddir)/osaf/libs/saf/libSaImm/libSaImmOi.la \
>> $(top_builddir)/osaf/libs/saf/libSaImm/libSaImmOm.la \
>> + $(top_builddir)/osaf/libs/saf/libSaClm/libSaClm.la \
>> $(top_builddir)/osaf/libs/agents/infrastructure/rda/librda.la
>> diff --git a/osaf/services/saf/logsv/lgs/lgs_cb.h
>> b/osaf/services/saf/logsv/lgs/lgs_cb.h
>> --- a/osaf/services/saf/logsv/lgs/lgs_cb.h
>> +++ b/osaf/services/saf/logsv/lgs/lgs_cb.h
>> @@ -21,6 +21,7 @@
>> #include <stdbool.h>
>> #include <saLog.h>
>> #include <saImmOi.h>
>> +#include <saClm.h>
>> #include <mbcsv_papi.h>
>> #include <ncs_edu_pub.h>
>>
>> @@ -55,6 +56,11 @@ typedef struct lgs_stream_list {
>> } lgs_stream_list_t;
>>
>> typedef struct {
>> + NCS_PATRICIA_NODE patnode;
>> + NODE_ID node_id;
>> +} lgs_clm_node_t;
>> +
> [Lennart] Would it be possible to not add new patricia node handling? Since
> the log service is compiled as C++ code C++ list tools could be used instead?
> lgs_clm_node_find
[AVM] Same comment was give by Anders Widell as well.
I will do all NCS_PATRICIA_TREE conversion to std::map of
Log service in one go in a separate ticket soon.
>> +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;
> [Lennart] Why adding new globals? At least this one is not needed. This
> variable could be declared locally in lgs_clm.cc only if the is_clm_init()
> function is moved from lgs_util.cc to lgs_clm.cc. Try to keep CLM handling
> code in one place (could be a class) and avoid global varaibles (avoid using
> the cb structure as an all-purpose "slask" global if possible)
[AVM] clm_initialized is Agent wide information this will used future
purposes like all services concurrently starting ect..
>> SaAmfHAStateT ha_state; /* present AMF HA state of the
>> component */
>> uint32_t last_client_id; /* Value of last client_id assigned
>> */
>> uint32_t async_upd_cnt; /* Async Update Count for Warmsync
>> */
>> @@ -94,6 +104,7 @@ typedef struct lgs_cb {
>> down events Processing
>> */
>> LGA_DOWN_LIST *lga_down_list_tail;
>>
>> + NCS_SEL_OBJ clm_init_sel_obj; /* Selection object for CLM
>> initialization.*/
>> bool nid_started; /**< true if started by NID */
>> SaUint32T scAbsenceAllowed; /* OpenSAF global configuration for
>> recovery handling */
>> lgs_state_t lgs_recovery_state; /* Indicate current recovery state for
>> the server */
>> @@ -106,5 +117,9 @@ typedef struct lgs_cb {
>> extern uint32_t lgs_cb_init(lgs_cb_t *);
>> extern void lgs_process_mbx(SYSF_MBX *mbx);
>> extern uint32_t lgs_stream_add(lgs_cb_t *cb, log_stream_t *stream);
>> +extern uint32_t lgs_clm_node_del(NODE_ID node_id);
>> +extern uint32_t lgs_clm_node_add(NODE_ID node_id);
>> +extern uint32_t lgs_clm_node_find(NODE_ID node_id);
>> +extern bool is_client_clm_member(NODE_ID node_id, SaVersionT *ver);
> [Lennart] Does the function protoypes really belongs here? The code can be
> found in lgs_evt.cc and lgs_util.cc but probably belongs to the lgs_clm.cc
> file and the prototypes should be in the lgs_clm.h file?
[AVM] Moved.
>
>> #endif
>> diff --git a/osaf/services/saf/logsv/lgs/lgs_clm.cc
>> b/osaf/services/saf/logsv/lgs/lgs_clm.cc
>> new file mode 100644
>> --- /dev/null
>> +++ b/osaf/services/saf/logsv/lgs/lgs_clm.cc
>> @@ -0,0 +1,142 @@
>> +/* -*- OpenSAF -*-
>> + *
>> + * (C) Copyright 2016 The OpenSAF Foundation
>> + *
>> + * This program is distributed in the hope that it will be useful, but
>> + * WITHOUT ANY WARRANTY; without even the implied warranty of
>> MERCHANTABILITY
>> + * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are
>> licensed
>> + * under the GNU Lesser General Public License Version 2.1, February 1999.
>> + * The complete license can be accessed from the following location:
>> + * http://opensource.org/licenses/lgpl-license.php
>> + * See the Copying file included with the OpenSAF distribution for full
>> + * licensing terms.
>> + *
>> + * Author(s): Oracle
>> + *
>> + */
>> +
>> +#include "lgs.h"
>> +#include "lgs_clm.h"
>> +
>> +/*
>> + * @brief CLM callback for tracking node membership status.
>> + * Depending upon the membership status (joining/leaving cluster)
>> + * of a node, LGS will add or remove node from its data base.
>> + * A node is added when it is part of the cluster and is removed
>> + * when it leaves the cluster membership. An update of status is
>> + * sent to the clients on that node. Based on this status LGA
>> + * will decide return code for different API calls.
>> + *
>> + */
>> +static void lgs_clm_track_cbk(const SaClmClusterNotificationBufferT_4
>> *notificationBuffer,
>> + SaUint32T numberOfMembers, SaInvocationT invocation,
>> + const SaNameT *rootCauseEntity, const SaNtfCorrelationIdsT
>> *correlationIds,
>> + SaClmChangeStepT step, SaTimeT timeSupervision,
>> SaAisErrorT error)
>> +{
>> + NODE_ID node_id;
>> + SaClmClusterChangesT cluster_change;
>> + SaBoolT is_member;
>> + uint32_t i = 0;
>> +
>> + TRACE_ENTER2("'%llu' '%u' '%u'", invocation, step, error);
>> + if (error != SA_AIS_OK) {
>> + TRACE_1("Error received in ClmTrackCallback");
>> + goto done;
>> + }
>> + lgs_cb->clm_initialized = true;
>> +
>> + for (i = 0; i < notificationBuffer->numberOfItems; i++) {
>> + switch(step) {
>> + case SA_CLM_CHANGE_COMPLETED:
>> + is_member = notificationBuffer-
>>> notification[i].clusterNode.member;
>> + node_id = notificationBuffer-
>>> notification[i].clusterNode.nodeId;
>> + if (lgs_clm_node_find(node_id) ==
>> NCSCC_RC_SUCCESS) {
>> + TRACE_1("'%x' is present in LGS db",
>> node_id);
>> + if (!is_member) {
>> + TRACE("CLM Node : %x Left
>> the cluster", node_id);
>> + cluster_change =
>> SA_CLM_NODE_LEFT;
>> + if
>> (lgs_clm_node_del(node_id) == NCSCC_RC_SUCCESS){
>> + if (lgs_cb->ha_state
>> == SA_AMF_HA_ACTIVE)
>> +
>> send_clm_node_status_change(cluster_change, node_id);
>> + }
>> + }
>> + } else {
>> + TRACE_1("'%x' is not present in LGS
>> db", node_id);
>> + if (is_member) {
>> + TRACE("CLM Node : %x
>> Joined the cluster", node_id);
>> + cluster_change =
>> SA_CLM_NODE_JOINED;
>> +
>> if(lgs_clm_node_add(node_id) == NCSCC_RC_SUCCESS) {
>> + if (lgs_cb->ha_state
>> == SA_AMF_HA_ACTIVE)
>> +
>> send_clm_node_status_change(cluster_change, node_id);
>> + }
>> + }
>> + }
>> + break;
>> + default:
>> + break;
>> + }
>> + }
>> +done:
>> + TRACE_LEAVE();
>> + return;
>> +}
>> +
>> +static const SaClmCallbacksT_4 clm_callbacks = {
>> + 0,
>> + lgs_clm_track_cbk /*saClmClusterTrackCallback*/
>> +};
>> +
>> +/*
>> + * @brief Registers with the CLM service (B.04.01).
>> + *
>> + * @return SaAisErrorT
>> + */
>> +void *lgs_clm_init_thread(void *cb)
>> +{
>> + static SaVersionT clmVersion = { 'B', 0x04, 0x01 };
>> + lgs_cb_t *_lgs_cb = (lgs_cb_t *) cb;
>> + SaAisErrorT rc = SA_AIS_OK;
>> + TRACE_ENTER();
>> + rc = saClmInitialize_4(&_lgs_cb->clm_hdl, &clm_callbacks,
>> &clmVersion);
>> + if (rc != SA_AIS_OK) {
>> + LOG_ER("saClmInitialize failed with error: %d", rc);
>> + TRACE_LEAVE();
>> + exit(EXIT_FAILURE);
>> + }
>> + rc = saClmSelectionObjectGet(_lgs_cb->clm_hdl, &lgs_cb-
>>> clmSelectionObject);
>> + if (rc != SA_AIS_OK) {
>> + LOG_ER("saClmSelectionObjectGet failed with error: %d",
>> rc);
>> + TRACE_LEAVE();
>> + exit(EXIT_FAILURE);
>> + }
>> + //TODO:subscribe for SA_TRACK_START_STEP also.
>> + rc = saClmClusterTrack_4(_lgs_cb->clm_hdl, (SA_TRACK_CURRENT |
>> SA_TRACK_CHANGES), NULL);
>> + if (rc != SA_AIS_OK) {
>> + LOG_ER("saClmClusterTrack failed with error: %d", rc);
>> + TRACE_LEAVE();
>> + exit(EXIT_FAILURE);
>> + }
>> + TRACE("CLM Initialization SUCCESS......");
>> + TRACE_LEAVE();
>> + return NULL;
>> +}
>> +
>> +/*
>> + * @brief Creates a thread to initialize with CLM.
>> + */
>> +void lgs_init_with_clm(void)
>> +{
>> + pthread_t thread;
>> + pthread_attr_t attr;
>> + TRACE_ENTER();
>> +
>> + pthread_attr_init(&attr);
>> + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
>> +
>> + if (pthread_create(&thread, &attr, lgs_clm_init_thread, lgs_cb) != 0)
>> {
>> + LOG_ER("pthread_create FAILED: %s", strerror(errno));
>> + exit(EXIT_FAILURE);
>> + }
>> + pthread_attr_destroy(&attr);
>> + TRACE_LEAVE();
>> +}
>> diff --git a/osaf/services/saf/logsv/lgs/lgs_clm.h
>> b/osaf/services/saf/logsv/lgs/lgs_clm.h
>> new file mode 100644
>> --- /dev/null
>> +++ b/osaf/services/saf/logsv/lgs/lgs_clm.h
>> @@ -0,0 +1,25 @@
>> +/* -*- OpenSAF -*-
>> + *
>> + * (C) Copyright 2016 The OpenSAF Foundation
>> + *
>> + * This program is distributed in the hope that it will be useful, but
>> + * WITHOUT ANY WARRANTY; without even the implied warranty of
>> MERCHANTABILITY
>> + * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are
>> licensed
>> + * under the GNU Lesser General Public License Version 2.1, February 1999.
>> + * The complete license can be accessed from the following location:
>> + * http://opensource.org/licenses/lgpl-license.php
>> + * See the Copying file included with the OpenSAF distribution for full
>> + * licensing terms.
>> + *
>> + * Author(s): Oracle
>> + *
>> + */
>> +
>> +#include <saClm.h>
>> +
>> +#define m_LGS_GET_NODE_ID_FROM_ADEST(adest) (NODE_ID)
>> ((uint64_t)adest >> 32)
>> +
>> +/*
>> + * @brief Creates a thread to initialize with CLM.
>> + */
>> +void lgs_init_with_clm(void);
>> diff --git a/osaf/services/saf/logsv/lgs/lgs_evt.cc
>> b/osaf/services/saf/logsv/lgs/lgs_evt.cc
>> --- a/osaf/services/saf/logsv/lgs/lgs_evt.cc
>> +++ b/osaf/services/saf/logsv/lgs/lgs_evt.cc
>> @@ -23,6 +23,7 @@
>> #include "lgs_mbcsv_v2.h"
>> #include "lgs_recov.h"
>> #include "lgs_imm_gcfg.h"
>> +#include "lgs_clm.h"
>>
>> /* Macro to validate the version */
>> #define m_LOG_VER_IS_VALID(ver) \
>> @@ -56,6 +57,94 @@ LGSV_LGS_LGA_API_MSG_HANDLER lgs_lga_api
>> };
>>
>> /**
>> + * Name : lgs_clm_node_tree_init
>> + * Description : This routine is used to initialize the clm_node_tree
>> + * Arguments : lgs_cb - pointer to the lgs Control Block
>> + * Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE
>> + * Notes : None
>> + */
>> +uint32_t lgs_clm_node_tree_init(lgs_cb_t *lgs_cb)
>> +{
>> + TRACE_ENTER();
>> + NCS_PATRICIA_PARAMS param;
>> + memset(¶m, 0, sizeof(NCS_PATRICIA_PARAMS));
>> +
>> + param.key_size = sizeof(NODE_ID);
>> + if (ncs_patricia_tree_init(&lgs_cb->clm_node_tree, ¶m) !=
>> NCSCC_RC_SUCCESS) {
>> + LOG_ER("lgs patricia tee init failed for clm_node_tree");
>> + return NCSCC_RC_FAILURE;
>> + }
>> + TRACE_LEAVE();
>> + return NCSCC_RC_SUCCESS;
>> +}
>> +
>> +/**
>> + * Name : lgs_clm_node_find
>> + * Description : This routine finds the clm_node .
>> + * Arguments : node_id - CLM Node id
>> + * Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE
>> + * Notes : None
>> + */
>> +uint32_t lgs_clm_node_find(NODE_ID node_id)
>> +{
>> + uint32_t rc = NCSCC_RC_FAILURE;
>> + lgs_clm_node_t *clm_node = (lgs_clm_node_t *)
>> + ncs_patricia_tree_get(&lgs_cb->clm_node_tree, (uint8_t
>> *)&node_id);
>> +
>> + if (clm_node != NULL)
>> + rc = NCSCC_RC_SUCCESS;
>> + else
>> + TRACE("node_id find in DB failed : %x",node_id);
>> +
>> + return rc;
>> +}
>> +
>> +/**
>> + * Name : lgs_clm_node_add
>> + * Description : This routine adds the new node to clm_node_tree.
>> + * Arguments : node_id - CLM Node id
>> + * Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE
>> + * Notes : None
>> + */
>> +uint32_t lgs_clm_node_add(NODE_ID node_id)
>> +{
>> + TRACE_ENTER();
>> + uint32_t rc = NCSCC_RC_FAILURE;
>> + lgs_clm_node_t *clm_node;
>> +
>> + clm_node = (lgs_clm_node_t *) malloc(sizeof(lgs_clm_node_t));
>> + clm_node->node_id = node_id;
>> + clm_node->patnode.key_info = (uint8_t *)&clm_node->node_id;
>> + rc = ncs_patricia_tree_add(&lgs_cb->clm_node_tree,
>> (NCS_PATRICIA_NODE *)&clm_node->patnode);
>> + if (rc != NCSCC_RC_SUCCESS)
>> + TRACE("node_id add to DB failed : %x",node_id);
>> + TRACE_LEAVE();
>> + return rc;
>> +}
>> +
>> +/**
>> + * Name : lgs_clm_node_del
>> + * Description : Function to Delete the clm_node.
>> + * Arguments : node_id - CLM Node id
>> + * Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE
>> + * Notes : None.
>> + */
>> +uint32_t lgs_clm_node_del(NODE_ID node_id)
>> +{
>> + TRACE_ENTER();
>> + uint32_t rc = NCSCC_RC_FAILURE;
>> +
>> + lgs_clm_node_t *clm_node = (lgs_clm_node_t *)
>> + ncs_patricia_tree_get(&lgs_cb->clm_node_tree, (uint8_t
>> *)&node_id);
>> + if (clm_node != NULL)
>> + rc = ncs_patricia_tree_del(&lgs_cb->clm_node_tree,
>> (NCS_PATRICIA_NODE *)&clm_node->patnode);
>> + if (rc != NCSCC_RC_SUCCESS)
>> + TRACE("node_id delete to DB failed : %x",node_id);
>> + TRACE_LEAVE();
>> + return rc;
>> +}
>> +
>> +/**
>> * Get client record from client ID
>> * @param client_id
>> *
>> @@ -583,6 +672,9 @@ uint32_t lgs_cb_init(lgs_cb_t *lgs_cb)
>> lgs_cb->amfSelectionObject = -1;
>> lgs_cb->immSelectionObject = -1;
>> lgs_cb->mbcsv_sel_obj = -1;
>> + lgs_cb->clm_hdl = 0;
>> + lgs_cb->clm_initialized = false;
>> + lgs_cb->clmSelectionObject = -1;
>>
>> /* Assign Version. Currently, hardcoded, This will change later */
>> lgs_cb->log_version.releaseCode = LOG_RELEASE_CODE;
>> @@ -598,6 +690,12 @@ uint32_t lgs_cb_init(lgs_cb_t *lgs_cb)
>> if (NCSCC_RC_SUCCESS != ncs_patricia_tree_init(&lgs_cb-
>>> client_tree, ®_param))
>> return NCSCC_RC_FAILURE;
>>
>> + /* Initialize patricia tree for CLM Node list */
>> + if (NCSCC_RC_SUCCESS != lgs_clm_node_tree_init(lgs_cb)) {
>> + LOG_ER("LGS: ncs_patricia_tree_init FAILED");
>> + return NCSCC_RC_FAILURE;
>> + }
>> +
>> done:
>> TRACE_LEAVE();
>> return rc;
>> @@ -637,6 +735,12 @@ static uint32_t proc_initialize_msg(lgs_
>> goto snd_rsp;
>> }
>>
>> + if (is_client_clm_member(evt->fr_node_id, version) != true){
>> + ais_rc = SA_AIS_ERR_UNAVAILABLE;
>> + TRACE("client not a CLM member FAILED");
>> + goto snd_rsp;
>> + }
>> +
>> if ((client = lgs_client_new(evt->fr_dest, 0, NULL)) == NULL) {
>> ais_rc = SA_AIS_ERR_NO_MEMORY;
>> goto snd_rsp;
>> @@ -1451,3 +1555,42 @@ void lgs_process_mbx(SYSF_MBX *mbx)
>> lgs_evt_destroy(msg);
>> }
>> }
>> +
>> +/**
>> + * @brief Sends CLM membership status of the node to all the clients
>> + * on the node except A11 clients.
>> + * @param cluster_change (CLM membership status of node).
>> + * @param NCS node_id.
>> + * @return NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE.
>> + */
>> +uint32_t
>> send_cluster_membership_msg_to_clients(SaClmClusterChangesT
>> cluster_change, NODE_ID node_id) {
>> + uint32_t rc = NCSCC_RC_SUCCESS;
>> + log_client_t *rp = NULL;
>> + uint32_t client_id_net;
>> +
>> + TRACE_ENTER();
>> + TRACE_3("node_id: %x, change:%u", node_id, cluster_change);
>> +
>> + rp = reinterpret_cast<log_client_t
>> *>(ncs_patricia_tree_getnext(&lgs_cb->client_tree, NULL));
>> +
>> + while (rp != NULL) {
>> + /** Store the client_id_net for get Next */
>> + client_id_net = rp->client_id_net;
>> + NODE_ID tmp_node_id =
>> m_LGS_GET_NODE_ID_FROM_ADEST(rp->mds_dest);
>> + //Do not send to A11 client. Send only to specific Node
>> + if (tmp_node_id == node_id)
>> + rc = send_clm_node_status_lib(cluster_change, rp-
>>> client_id, rp->mds_dest);
>> +
>> + rp = reinterpret_cast<log_client_t
>> *>(ncs_patricia_tree_getnext(
>> + &lgs_cb->client_tree,
>> reinterpret_cast<uint8_t *>(&client_id_net)));
>> + }
>> +
>> + TRACE_LEAVE();
>> + return rc;
>> +}
>> +
>> +uint32_t send_clm_node_status_change(SaClmClusterChangesT
>> cluster_change, NODE_ID node_id) {
>> + return (send_cluster_membership_msg_to_clients(cluster_change,
>> node_id));
>> +
>> +}
>> +
>> diff --git a/osaf/services/saf/logsv/lgs/lgs_evt.h
>> b/osaf/services/saf/logsv/lgs/lgs_evt.h
>> --- a/osaf/services/saf/logsv/lgs/lgs_evt.h
>> +++ b/osaf/services/saf/logsv/lgs/lgs_evt.h
>> @@ -77,6 +77,8 @@ extern bool lgs_lga_entry_valid(lgs_cb_t
>> extern uint32_t lgs_remove_lga_down_rec(lgs_cb_t *cb, MDS_DEST
>> mds_dest);
>> extern void lgs_send_write_log_ack(uint32_t client_id, SaInvocationT
>> invocation, SaAisErrorT error, MDS_DEST mds_dest);
>> extern void lgs_free_write_log(const lgsv_write_log_async_req_t *param);
>> +extern uint32_t send_clm_node_status_lib(SaClmClusterChangesT
>> cluster_change, unsigned int client_id, MDS_DEST mdsDest);
>> +extern uint32_t send_clm_node_status_change(SaClmClusterChangesT
>> cluster_change, NODE_ID node_id);
>>
>> SaAisErrorT create_new_app_stream(
>> lgsv_stream_open_req_t *open_sync_param,
>> diff --git a/osaf/services/saf/logsv/lgs/lgs_main.cc
>> b/osaf/services/saf/logsv/lgs/lgs_main.cc
>> --- a/osaf/services/saf/logsv/lgs/lgs_main.cc
>> +++ b/osaf/services/saf/logsv/lgs/lgs_main.cc
>> @@ -38,6 +38,7 @@
>> #include "osaf_utility.h"
>> #include "lgs_recov.h"
>> #include "immutil.h"
>> +#include "lgs_clm.h"
>>
>> /*
>> ==========================================================
>> ==============
>> * DEFINITIONS
>> @@ -49,6 +50,7 @@ enum {
>> FD_MBCSV,
>> FD_MBX,
>> FD_CLTIMER,
>> + FD_CLM,
>> FD_IMM, /* Must be the last in the fds array */
>> FD_NUM
>> };
>> @@ -332,6 +334,13 @@ static uint32_t log_initialize(void)
>> goto done;
>> }
>>
>> + /* Create a CLM selection object */
>> + if ((rc = ncs_sel_obj_create(&lgs_cb->clm_init_sel_obj)) !=
>> NCSCC_RC_SUCCESS)
>> + {
>> + LOG_ER("lgsv: CLM ncs_sel_obj_create failed");
>> + goto done;
>> + }
>> +
>> /*
>> * Initialize a signal handler that will use the selection object.
>> * The signal is sent from our script when AMF does instantiate.
>> @@ -501,6 +510,8 @@ int main(int argc, char *argv[])
>> fds[FD_IMM].fd = lgs_cb->immSelectionObject;
>> fds[FD_IMM].events = POLLIN;
>>
>> + lgs_cb->clmSelectionObject = lgs_cb->clm_init_sel_obj.rmv_obj;
>> +
>> while (1) {
>> if (cltimer_fd < 0 && log_rtobj_list_no() != 0) {
>> /* Needed only if any "lost" objects are found
>> @@ -513,6 +524,8 @@ int main(int argc, char *argv[])
>> fds[FD_CLTIMER].events = POLLIN;
>> fds[FD_MBCSV].fd = lgs_cb->mbcsv_sel_obj;
>> fds[FD_MBCSV].events = POLLIN;
>> + fds[FD_CLM].fd = lgs_cb->clmSelectionObject;
>> + fds[FD_CLM].events = POLLIN;
>>
>> /* Protect since the reinit thread may be in the process of
>> * changing the values
>> @@ -567,6 +580,21 @@ int main(int argc, char *argv[])
>> }
>> }
>>
>> + if (fds[FD_CLM].revents & POLLIN) {
>> + if (lgs_cb->clm_hdl != 0) {
>> + if ((error = saClmDispatch(lgs_cb->clm_hdl,
>> SA_DISPATCH_ALL)) != SA_AIS_OK) {
>> + LOG_ER("saClmDispatch failed: %u",
>> error);
>> + break;
>> + }
>> + } else {
>> + TRACE("init CLM ");
>> + ncs_sel_obj_rmv_ind(&lgs_cb-
>>> clm_init_sel_obj, true, true);
>> + ncs_sel_obj_destroy(&lgs_cb-
>>> clm_init_sel_obj);
>> + lgs_cb->clmSelectionObject = -1;
>> + lgs_init_with_clm();
>> + }
>> + }
>> +
>> if (fds[FD_CLTIMER].revents & POLLIN) {
>> /* To avoid 'stray objects', after a timeout all runtime
>> * objects that has not been restored shall be deleted
>> diff --git a/osaf/services/saf/logsv/lgs/lgs_mds.cc
>> b/osaf/services/saf/logsv/lgs/lgs_mds.cc
>> --- a/osaf/services/saf/logsv/lgs/lgs_mds.cc
>> +++ b/osaf/services/saf/logsv/lgs/lgs_mds.cc
>> @@ -763,11 +763,19 @@ static uint32_t mds_enc(struct ncsmds_ca
>> goto err;
>> }
>> ncs_encode_32bit(&p8, msg-
>>> info.cbk_info.write_cbk.error);
>> + TRACE_8("LGSV_WRITE_LOG_CALLBACK_IND");
>> + } else if (msg->info.cbk_info.type ==
>> LGSV_CLM_NODE_STATUS_CALLBACK) {
>> + p8 = ncs_enc_reserve_space(uba, 4);
>> + if (!p8) {
>> + TRACE("ncs_enc_reserve_space failed");
>> + goto err;
>> + }
>> + ncs_encode_32bit(&p8, msg-
>>> info.cbk_info.clm_node_status_cbk.clm_node_status);
>> + TRACE_8("LGSV_CLM_NODE_STATUS_CALLBACK");
>> } else {
>> TRACE("unknown callback type %d", msg-
>>> info.cbk_info.type);
>> goto err;
>> }
>> - TRACE_8("LGSV_WRITE_LOG_CALLBACK_IND");
>> } else {
>> TRACE("unknown msg type %d", msg->type);
>> goto err;
>> @@ -1167,6 +1175,16 @@ static uint32_t mds_svc_event(struct ncs
>> osafassert(rc == NCSCC_RC_SUCCESS);
>> }
>> }
>> + } else if (info->info.svc_evt.i_svc_id == NCSMDS_SVC_ID_AVD) {
>> + if (info->info.svc_evt.i_change == NCSMDS_UP) {
>> + TRACE_8("MDS UP dest: %" PRIx64 ", node ID: %x,
>> svc_id: %d",
>> + info->info.svc_evt.i_dest, info-
>>> info.svc_evt.i_node_id, info->info.svc_evt.i_svc_id);
>> + //Subscribed for only INTRA NODE, only one ADEST
>> will come.
>> + if (m_MDS_DEST_IS_AN_ADEST(info-
>>> info.svc_evt.i_dest)) {
>> + TRACE_8("AVD ADEST UP");
>> + ncs_sel_obj_ind(&lgs_cb->clm_init_sel_obj);
>> + }
>> + }
>> }
>>
>> done:
>> @@ -1334,6 +1352,24 @@ uint32_t lgs_mds_init(lgs_cb_t *cb, SaAm
>> return rc;
>> }
>>
>> +
>> + svc = NCSMDS_SVC_ID_AVD;
>> + /* Now subscribe for AVD events in MDS. This will be
>> + used for CLM registration.*/
>> + memset(&mds_info, '\0', sizeof(NCSMDS_INFO));
>> + mds_info.i_mds_hdl = cb->mds_hdl;
>> + mds_info.i_svc_id = NCSMDS_SVC_ID_LGS;
>> + mds_info.i_op = MDS_SUBSCRIBE;
>> + mds_info.info.svc_subscribe.i_scope = NCSMDS_SCOPE_INTRANODE;
>> + mds_info.info.svc_subscribe.i_num_svcs = 1;
>> + mds_info.info.svc_subscribe.i_svc_ids = &svc;
>> +
>> + rc = ncsmds_api(&mds_info);
>> + if (rc != NCSCC_RC_SUCCESS) {
>> + LOG_ER("MDS for AVD subscribe FAILED");
>> + return rc;
>> + }
>> +
>> TRACE_LEAVE();
>> return rc;
>> }
>> diff --git a/osaf/services/saf/logsv/lgs/lgs_util.cc
>> b/osaf/services/saf/logsv/lgs/lgs_util.cc
>> --- a/osaf/services/saf/logsv/lgs/lgs_util.cc
>> +++ b/osaf/services/saf/logsv/lgs/lgs_util.cc
>> @@ -415,6 +415,89 @@ void lgs_send_write_log_ack(uint32_t cli
>> }
>>
>> /**
>> + * @brief Send Membership status of node to a lib on that node.
>> + *
>> + * @param SaClmClusterChangesT (CLM status of node)
>> + * @param client_id
>> + * @param mdsDest of client
>> + *
>> + * @return NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE.
>> + */
>> +uint32_t send_clm_node_status_lib(SaClmClusterChangesT
>> cluster_change, unsigned int client_id, MDS_DEST mdsDest)
>> +{
>> + uint32_t rc = NCSCC_RC_SUCCESS;
>> + NCSMDS_INFO mds_info = {0};
>> + lgsv_msg_t msg;
>> +
>> + TRACE_ENTER();
>> + TRACE_3("change:%u, client_id: %u", cluster_change, client_id);
>> +
>> + memset(&msg, 0, sizeof(lgsv_msg_t));
>> + msg.type = LGSV_LGS_CBK_MSG;
>> + msg.info.cbk_info.type = LGSV_CLM_NODE_STATUS_CALLBACK;
>> + msg.info.cbk_info.lgs_client_id = client_id;
>> + msg.info.cbk_info.inv = 0;
>> + msg.info.cbk_info.clm_node_status_cbk.clm_node_status =
>> cluster_change;
>> +
>> + mds_info.i_mds_hdl = lgs_cb->mds_hdl;
>> + mds_info.i_svc_id = NCSMDS_SVC_ID_LGS;
>> + mds_info.i_op = MDS_SEND;
>> + mds_info.info.svc_send.i_msg = &msg;
>> + mds_info.info.svc_send.i_to_svc = NCSMDS_SVC_ID_LGA;
>> + mds_info.info.svc_send.i_priority = MDS_SEND_PRIORITY_HIGH;
>> + mds_info.info.svc_send.i_sendtype = MDS_SENDTYPE_SND;
>> + mds_info.info.svc_send.info.snd.i_to_dest = mdsDest;
>> +
>> + rc = ncsmds_api(&mds_info);
>> + if (rc != NCSCC_RC_SUCCESS)
>> + LOG_NO("Failed (%u) to send of WRITE ack to: %" PRIx64, rc,
>> mdsDest);
>> +
>> + TRACE_LEAVE();
>> + return rc;
>> +}
>> +
>> +/**
>> + * @brief Checks if LGSV has already initialized with CLM service.
>> + *
>> + * @return true/false.
>> + */
>> +bool is_clm_init()
>> +{
>> + return (((lgs_cb->clm_hdl != 0) && (lgs_cb->clm_initialized ==
>> true)) ?
>> true : false);
>> +}
>> +
>> +/**
>> + * @brief Checks CLM membership status of a client.
>> + * A.02.01 clients are always CLM member.
>> + * @param Client MDS_DEST
>> + * @param Client saf version.
>> + * @return NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE.
>> + */
>> +bool is_client_clm_member(NODE_ID node_id, SaVersionT *ver) {
>> +
>> + //Before CLM init all clients are clm member.
>> + if (is_clm_init() == false)
>> + return true;
>> +
>> + TRACE("client Version: %d.%d.%d", ver->releaseCode, ver->majorVersion,
>> ver->minorVersion);
>> + //CLM integration is supported from A.02.02. So old clients A.02.01 are
>> always clm member.
>> + if ((ver->releaseCode == LOG_RELEASE_CODE_0) &&
>> + (ver->majorVersion == LOG_MAJOR_VERSION_0) &&
>> + (ver->minorVersion == LOG_MINOR_VERSION_0))
>> + return true;
>> + /*
>> + It means CLM initialization is successful and this is atleast a A.02.02
>> client.
>> + So check CLM membership status of client's node.
>> + */
>> + if (lgs_clm_node_find(node_id) != NCSCC_RC_SUCCESS)
>> + return false;
>> + else
>> + return true;
>> +}
>> +
>> +
>> +
>> +/**
>> * Free all dynamically allocated memory for a WRITE
>> * @param param
>> */
------------------------------------------------------------------------------
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel