Hi Vu,

I Incorporated most of your review comments please review  `lgs: 
director Cluster Membership (CLM) integration [#1638] V4`.

-AVM

On 8/5/2016 10:26 AM, Vu Minh Nguyen wrote:
> Hi Mahesh,
>
> I have some comments [Vu].
>
> Regards, Vu
>
>> -----Original Message-----
>> From: mahesh.va...@oracle.com [mailto:mahesh.va...@oracle.com]
>> Sent: Thursday, August 4, 2016 6:13 PM
>> To: vu.m.ngu...@dektech.com.au; lennart.l...@ericsson.com;
>> anders.wid...@ericsson.com
>> Cc: opensaf-devel@lists.sourceforge.net
>> Subject: [PATCH 2 of 3] lgs: director Cluster Membership (CLM) integration
>> [#1638] V3
>>
>>   osaf/services/saf/logsv/lgs/Makefile.am |    7 +-
>>   osaf/services/saf/logsv/lgs/lgs_cb.h    |    9 +
>>   osaf/services/saf/logsv/lgs/lgs_clm.cc  |  403
>> ++++++++++++++++++++++++++++++++
>>   osaf/services/saf/logsv/lgs/lgs_clm.h   |   39 +++
>>   osaf/services/saf/logsv/lgs/lgs_evt.cc  |   15 +
>>   osaf/services/saf/logsv/lgs/lgs_main.cc |   28 ++
>>   osaf/services/saf/logsv/lgs/lgs_mds.cc  |   38 ++-
>>   7 files changed, 536 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>
>>
>> @@ -73,6 +74,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 */
>> +    void *clm_node_db;       /* used for C++ STL map */
>>      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 +82,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 +99,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 +112,8 @@ 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);
>>
>>   #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,403 @@
>> +/*      -*- 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 "osaf/services/saf/logsv/lgs/lgs.h"
>> +#include "osaf/services/saf/logsv/lgs/lgs_clm.h"
>> +
>> +static bool clm_initialized;
>> +typedef std::map<NODE_ID, lgs_clm_node_t *> ClmNodeMap;
>> +
>> +/**
>> + * @brief Checks if LGSV has already initialized with CLM service.
>> + *
>> + * @return true/false.
>> + */
>> +bool is_clm_init() {
>> +  return (((lgs_cb->clm_hdl != 0)
>> +        && (clm_initialized == true)) ? true : false);
>> +}
>> +
>> +/**
>> + * Name     : lgs_clm_node_map_init
>> + * Description   : This routine is used to initialize the clm_node_map
>> + * Arguments     : lgs_cb - pointer to the lgs Control Block
>> + * Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE
>> + * Notes    : None
>> + */
>> +uint32_t lgs_clm_node_map_init(lgs_cb_t *lgs_cb) {
>> +  TRACE_ENTER();
>> +  if (lgs_cb->clm_node_db) {
> [Vu] Please have this ` clm_node_db` pointer initialized.
>
>> +    TRACE("CLM Node map already exists");
>> +    return NCSCC_RC_FAILURE;
>> +  }
>> +
>> +  lgs_cb->clm_node_db = new ClmNodeMap;
>> +  TRACE_LEAVE();
>> +  return NCSCC_RC_SUCCESS;
>> +}
>> +
>> +/**
>> + * Name     : lgs_clm_node_map_destroy
>> + * Description   : This routine is used to destroy  the clm_node_map
>> + * Arguments     : lgs_cb - pointer to the lgs Control Block
>> + * Return Values : void
>> + * Notes    : None
>> + */
>> +void lgs_clm_node_map_destroy() {
>> +  delete reinterpret_cast<ClmNodeMap *>(lgs_cb->clm_node_db);
>> +  lgs_cb->clm_node_db = 0;
>> +}
> [Vu] This function is not called anywhere.
>
>> +
>> +/**
>> + * Name     : lgs_clm_node_find
>> + * Description   : This routine finds the clm_node .
>> + * Arguments     : clm_node_id - CLM Node id
>> + * Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE
>> + * Notes    : None
>> + */
>> +uint32_t lgs_clm_node_find(NODE_ID clm_node_id) {
>> +  TRACE_ENTER();
>> +  uint32_t rc;
>> +
>> +  ClmNodeMap *clmNodeMap(reinterpret_cast<ClmNodeMap *>
>> +      (lgs_cb->clm_node_db));
>> +
>> +  if (clmNodeMap) {
>> +    ClmNodeMap::iterator it(clmNodeMap->find(clm_node_id));
> [Vu] Consider using `auto it` for all ` ClmNodeMap::iterator it`.
>
>> +
>> +    if (it != clmNodeMap->end()) {
>> +      rc = NCSCC_RC_SUCCESS;
>> +    } else {
>> +      rc = NCSCC_RC_FAILURE;
>> +      TRACE("clm_node_id not exist DB failed : %x", clm_node_id);
>> +    }
>> +  } else {
>> +    TRACE("clmNodeMap DB not exist failed : %x", clm_node_id);
>> +    rc = NCSCC_RC_FAILURE;
>> +    //    osafassert(false);
>> +  }
>> +
>> +  TRACE_LEAVE();
>> +  return rc;
>> +}
>> +
>> +/**
>> + * Name     : lgs_clm_node_add
>> + * Description   : This routine adds the new node to clm_node_map.
>> + * Arguments     : clm_node_id - CLM Node id
>> + * Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE
>> + * Notes    : None
>> + */
>> +uint32_t lgs_clm_node_add(NODE_ID clm_node_id) {
>> +  TRACE_ENTER();
>> +  uint32_t rc;
>> +  lgs_clm_node_t *clm_node;
>> +
>> +  clm_node = reinterpret_cast<lgs_clm_node_t *>
>> +    (malloc(sizeof(lgs_clm_node_t)));
> [Vu] Consider using `new` instead.
> I don't see the purpose of using the second of `ClmNodeMap`.
> If using std::list<NODE_ID>, we may not need to allocate memory here.
>
>> +
>> +  clm_node->clm_node_id = clm_node_id;
>> +
>> +  ClmNodeMap *clmNodeMap(reinterpret_cast<ClmNodeMap *>
>> +      (lgs_cb->clm_node_db));
>> +
>> +  if (clmNodeMap) {
>> +    std::pair<ClmNodeMap::iterator, bool> p(clmNodeMap->insert(
>> +          std::make_pair(clm_node->clm_node_id, clm_node)));
> [Vu] Using `auto` instead of ` std::pair<ClmNodeMap::iterator, bool>`
>> +
>> +    if (!p.second) {
>> +      TRACE("unable to add clm node info map - the id %x already
> existed",
>> +          clm_node->clm_node_id);
>> +      rc = NCSCC_RC_FAILURE;
>> +    }
>> +  } else {
>> +    TRACE("can't find local sec map in lgs_clm_node_add");
>> +    rc = NCSCC_RC_FAILURE;
>> +  }
>> +  TRACE_LEAVE();
>> +  return rc;
>> +}
>> +
>> +/**
>> + * Name     : lgs_clm_node_del
>> + * Description   : Function to Delete the clm_node.
>> + * Arguments     : clm_node_id - CLM Node id
>> + * Return Values : NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE
>> + * Notes    : None.
>> + */
>> +uint32_t lgs_clm_node_del(NODE_ID clm_node_id) {
>> +  TRACE_ENTER();
>> +  uint32_t rc;
>> +
>> +  ClmNodeMap *clmNodeMap(reinterpret_cast<ClmNodeMap *>
>> +      (lgs_cb->clm_node_db));
>> +
>> +  if (clmNodeMap) {
>> +    ClmNodeMap::iterator it(clmNodeMap->find(clm_node_id));
>> +
>> +    if (it != clmNodeMap->end()) {
>> +      clmNodeMap->erase(it);
> [Vu] Need to free the allocated memory of the second before erase?
>
>> +      rc = NCSCC_RC_SUCCESS;
>> +    } else {
>> +      TRACE("clm_node_id delete  failed : %x", clm_node_id);
>> +      rc = NCSCC_RC_FAILURE;
>> +    }
>> +  } else {
>> +    TRACE("clm_node_id delete to map not exist failed : %x",
> clm_node_id);
>> +    rc = NCSCC_RC_FAILURE;
>> +  }
>> +
>> +  TRACE_LEAVE();
>> +  return rc;
>> +}
>> +
>> +/**
>> + * @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 clusterChange,
>> +    unsigned int client_id, MDS_DEST mdsDest) {
>> +  uint32_t rc;
>> +  NCSMDS_INFO mds_info = {0};
>> +  lgsv_msg_t msg;
>> +  TRACE_ENTER();
>> +  TRACE_3("change:%u, client_id: %u", clusterChange, 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 =
>> clusterChange;
>> +
>> +  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  Sends CLM membership status of the node to all the clients
>> + *         on the node except A11 clients.
>> + * @param  clusterChange (CLM membership status of node).
>> + * @param  NCS clm_node_id.
>> + * @return NCSCC_RC_SUCCESS/NCSCC_RC_FAILURE.
>> + */
>> +uint32_t send_cluster_membership_msg_to_clients(
>> +    SaClmClusterChangesT clusterChange, NODE_ID clm_node_id) {
>> +  uint32_t rc = NCSCC_RC_SUCCESS;
>> +  log_client_t *rp = NULL;
>> +  uint32_t client_id_net;
>> +
>> +  TRACE_ENTER();
>> +  TRACE_3("clm_node_id: %x, change:%u", clm_node_id, clusterChange);
>> +
>> +  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_clm_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_clm_node_id == clm_node_id)
>> +      rc = send_clm_node_status_lib(clusterChange, 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
>> clusterChange,
>> +    NODE_ID clm_node_id) {
>> +  return (send_cluster_membership_msg_to_clients(clusterChange,
>> clm_node_id));
>> +}
>> +
>> +/**
>> + * @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 clm_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(clm_node_id) != NCSCC_RC_SUCCESS)
>> +    return false;
>> +  else
>> +    return true;
>> +}
>> +
>> +/*
>> + * @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 clm_node_id;
>> +  SaClmClusterChangesT clusterChange;
>> +  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;
>> +  }
>> +  clm_initialized = true;
>> +
>> +  for (i = 0; i < notificationBuffer->numberOfItems; i++) {
>> +    switch (step) {
>> +      case SA_CLM_CHANGE_COMPLETED:
>> +        is_member =
> notificationBuffer->notification[i].clusterNode.member;
>> +        clm_node_id =
> notificationBuffer->notification[i].clusterNode.nodeId;
>> +        if (lgs_clm_node_find(clm_node_id) == NCSCC_RC_SUCCESS) {
>> +          TRACE_1("'%x' is present in LGS db", clm_node_id);
>> +          if (!is_member) {
>> +            TRACE("CLM Node : %x Left the cluster", clm_node_id);
>> +            clusterChange = SA_CLM_NODE_LEFT;
>> +            if (lgs_clm_node_del(clm_node_id) == NCSCC_RC_SUCCESS) {
>> +              if (lgs_cb->ha_state == SA_AMF_HA_ACTIVE)
>> +                send_clm_node_status_change(clusterChange, clm_node_id);
>> +            }
>> +          }
>> +        } else {
>> +          TRACE_1("'%x' is not present in LGS db", clm_node_id);
>> +          if (is_member) {
>> +            TRACE("CLM Node : %x Joined the cluster", clm_node_id);
>> +            clusterChange = SA_CLM_NODE_JOINED;
>> +            if (lgs_clm_node_add(clm_node_id) == NCSCC_RC_SUCCESS) {
>> +              if (lgs_cb->ha_state == SA_AMF_HA_ACTIVE)
>> +                send_clm_node_status_change(clusterChange, clm_node_id);
>> +            }
>> +          }
>> +        }
>> +        break;
>> +      default:
>> +        break;
>> +    }
>> +  }
>> +done:
>> +  TRACE_LEAVE();
>> +  return;
>> +}
>> +
>> +/* saClmClusterTrackCallback */
>> +static const SaClmCallbacksT_4 clm_callbacks = {
>> +  0,
>> +  lgs_clm_track_cbk
>> +};
>> +
>> +/*
>> + * @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 = reinterpret_cast<lgs_cb_t *> (cb);
>> +  SaAisErrorT rc;
>> +  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,39 @@
>> +/*      -*- 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
>> + *
>> + */
>> +
>> +#ifndef OSAF_SERVICES_SAF_LOGSV_LGS_LGS_CLM_H_
>> +#define OSAF_SERVICES_SAF_LOGSV_LGS_LGS_CLM_H_
>> +
>> +#include <saClm.h>
>> +#include <map>
>> +#include <utility>
>> +
>> +#define m_LGS_GET_NODE_ID_FROM_ADEST(adest) (NODE_ID)
>> ((uint64_t)adest >> 32)
>> +
>> +typedef struct {
>> +        NODE_ID clm_node_id;
>> +} lgs_clm_node_t;
>> +
>> +/*
>> + * @brief  Creates a thread to initialize with CLM.
>> + */
>> +extern void lgs_init_with_clm(void);
>> +extern bool is_client_clm_member(NODE_ID node_id, SaVersionT *ver);
>> +extern uint32_t lgs_clm_node_map_init(lgs_cb_t *lgs_cb);
>> +extern bool is_client_clm_member(NODE_ID node_id, SaVersionT *ver);
> [Vu] Remove `extern`.
>
>> +
>> +#endif  // OSAF_SERVICES_SAF_LOGSV_LGS_LGS_CLM_H_
>> 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)   \
>> @@ -583,6 +584,8 @@ 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->clmSelectionObject = -1;
>>
>>      /* Assign Version. Currently, hardcoded, This will change later */
>>      lgs_cb->log_version.releaseCode = LOG_RELEASE_CODE;
>> @@ -598,6 +601,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_map_init(lgs_cb)) {
>> +            LOG_ER("LGS: ncs_patricia_tree_init FAILED");
>> +            return NCSCC_RC_FAILURE;
>> +    }
>> +
>>      done:
>>      TRACE_LEAVE();
>>      return rc;
>> @@ -637,6 +646,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;
>> 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;
>>   }


------------------------------------------------------------------------------
_______________________________________________
Opensaf-devel mailing list
Opensaf-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to