Hi Anders,

Thanks. But I don't intend to use this patch yet. The reasons being I have 
already been working on some changes
For the next release and I don't want those to be disturbed; secondly If I 
intend to convert, I would 
Prefer to have a plan and not do it on the fly.

So, you please go ahead to push your original patch (after fixing the return 
type). I will look into the wrapper thing after FC.

Cheers,
Mathi.

>-----Original Message-----
>From: Anders Widell [mailto:anders.wid...@ericsson.com]
>Sent: Thursday, March 31, 2016 8:00 PM
>To: Mathivanan Naickan Palanivelu
>Cc: opensaf-devel@lists.sourceforge.net
>Subject: Re: [PATCH 2 of 2] clm: Supervise and when necessary activate
>system controller functionality [#79]
>
>Hi!
>
>I did a quick stab at converting the CLM node agent to C++, and here is the
>result (without the wrappers). Apply it on top of the patch that is already on
>review.
>
>Due to the stricter type checking in C++, I actually bumped into a potential
>bug: The function clmna_process_dummyup_msg() is declared to return a
>value of type SaAisErrorT, but it actually returns the local variable "rc" 
>which is
>of type uint32_t, and has the possible values NCSCC_RC_SUCCESS and
>NCSCC_RC_FAILURE. Maybe it works anyhow, but it clearly is a type mismatch
>here.
>
>regards,
>Anders Widell
>
>On 03/31/2016 03:50 PM, Anders Widell wrote:
>> I don't like the wrappers either. :-) The alternative is to convert
>> the whole CLM service to C++, in which case the wrappers will go away.
>> I think this is the approach to take if you wish to get rid of the
>> wrappers.
>>
>> / Anders W
>>
>> On 03/31/2016 03:08 PM, Mathivanan Naickan Palanivelu wrote:
>>> Ack for the functional change related to startup and the idea of
>>> election.
>>> But, I do not favour introducing wrapper files.  I will try to give a
>>> c version of The election code by tomorrow, if not we can push patch
>>> 2 tomorrow and
>>>   we can take it up after FC.
>>>
>>> Cheers,
>>> Mathi.
>>>
>>>
>>>> -----Original Message-----
>>>> From: Anders Widell [mailto:anders.wid...@ericsson.com]
>>>> Sent: Monday, February 29, 2016 8:39 PM
>>>> To: Mathivanan Naickan Palanivelu
>>>> Cc: opensaf-devel@lists.sourceforge.net
>>>> Subject: [PATCH 2 of 2] clm: Supervise and when necessary activate
>>>> system controller functionality [#79]
>>>>
>>>> osaf/services/infrastructure/nid/config/nodeinit.conf.controller
>>>> |    2 +-
>>>> osaf/services/saf/clmsv/config/clmna.conf |    8 +
>>>> osaf/services/saf/clmsv/nodeagent/Makefile.am |   11 +-
>>>> osaf/services/saf/clmsv/nodeagent/cb.h |    1 +
>>>> osaf/services/saf/clmsv/nodeagent/election_starter.cc |  142
>>>> ++++++++++
>>>> osaf/services/saf/clmsv/nodeagent/election_starter.h |   94 ++++++
>>>> osaf/services/saf/clmsv/nodeagent/election_starter_wrapper.cc |   46
>>>> +++
>>>> osaf/services/saf/clmsv/nodeagent/election_starter_wrapper.h |   45
>+++
>>>> osaf/services/saf/clmsv/nodeagent/evt.h |    5 +-
>>>> osaf/services/saf/clmsv/nodeagent/main.c |  101 +++++--
>>>> 10 files changed, 421 insertions(+), 34 deletions(-)
>>>>
>>>>
>>>> Add support in the CLM node agent to supervise the existence of
>>>> ACTIVE and STANDBY system controllers. When no ACTIVE or STANDBY
>>>> controllers are present, the CLM node agent will activate the
>>>> controller functionality by setting the RDE role of the node with
>>>> the lowest NODE_ID to ACTIVE.
>>>>
>>>> diff --git
>>>> a/osaf/services/infrastructure/nid/config/nodeinit.conf.controller
>>>> b/osaf/services/infrastructure/nid/config/nodeinit.conf.controller
>>>> ---
>>>> a/osaf/services/infrastructure/nid/config/nodeinit.conf.controller
>>>> +++ b/osaf/services/infrastructure/nid/config/nodeinit.conf.controll
>>>> +++ er
>>>> @@ -54,6 +54,7 @@
>>>>
>>>>
>###########################################################
>>>> ##################
>>>>
>>>> xxCLCCLIDIRxx/osaf-transport:TRANSPORT:S:xxCLCCLIDIRxx/osaf-
>>>> transport:6000:-6:2:1:start:stop
>>>> +xxCLCCLIDIRxx/osaf-clmna:CLMNA:S:xxCLCCLIDIRxx/osaf-
>>>> clmna:8000::9:1:sta
>>>> +rt:stop
>>>> xxCLCCLIDIRxx/osaf-rded:RDE:S:xxCLCCLIDIRxx/osaf-rded:12000:-
>>>> 6:2:1:start:stop
>>>> xxCLCCLIDIRxx/osaf-fmd:HLFM:S:xxCLCCLIDIRxx/osaf-fmd:12000:-
>>>> 6:2:1:start:stop
>>>> xxCLCCLIDIRxx/osaf-immd:IMMD:S:xxCLCCLIDIRxx/osaf-
>>>> immd:4000:4:2:1:start:stop
>>>> @@ -62,6 +63,5 @@ xxCLCCLIDIRxx/osaf-logd:LOGD:S:xxCLCCLID
>>>> xxCLCCLIDIRxx/osaf-ntfd:NTFD:S:xxCLCCLIDIRxx/osaf-
>>>> ntfd:4000:4:2:1:start:stop
>>>> xxCLCCLIDIRxx/osaf-plmd:PLMD:S:xxCLCCLIDIRxx/osaf-
>>>> plmd:6500:4:2:1:start:stop
>>>> xxCLCCLIDIRxx/osaf-clmd:CLMD:S:xxCLCCLIDIRxx/osaf-
>>>> clmd:192000:4:2:1:start:stop
>>>> -xxCLCCLIDIRxx/osaf-clmna:CLMNA:S:xxCLCCLIDIRxx/osaf-
>>>> clmna:4000::9:1:start:stop
>>>> xxCLCCLIDIRxx/osaf-amfd:AMFD:S:xxCLCCLIDIRxx/osaf-amfd:192000:-
>>>> 6:0:1:start:stop
>>>> xxCLCCLIDIRxx/osaf-amfnd:AMFND:S:xxCLCCLIDIRxx/osaf-
>>>> amfnd:192000::0:1:start:stop
>>>> diff --git a/osaf/services/saf/clmsv/config/clmna.conf
>>>> b/osaf/services/saf/clmsv/config/clmna.conf
>>>> --- a/osaf/services/saf/clmsv/config/clmna.conf
>>>> +++ b/osaf/services/saf/clmsv/config/clmna.conf
>>>> @@ -9,5 +9,13 @@
>>>> # Healthcheck keys
>>>> export CLMNA_ENV_HEALTHCHECK_KEY="Default"
>>>>
>>>> +# Time in milliseconds without an SC to wait before starting an
>>>> +election. CLMNA # will detect the presence of system controllers in
>>>> the
>>>> +cluster (ACTIVE and # STANDBY). If no system controller has been
>>>> +seen during the configured time # period, CLMNA will initate an
>>>> +election with the own node as a candidate for a # new active system
>controller.
>>>> +Note that lowering this value will increase the # risk of
>>>> split-brain. Values
>>>> lower than 5000 are not recommended.
>>>> +#export CLMNA_ELECTION_DELAY_TIME=5000
>>>> +
>>>> # Uncomment the next line to enable info level logging #args="--
>>>> loglevel=info"
>>>> diff --git a/osaf/services/saf/clmsv/nodeagent/Makefile.am
>>>> b/osaf/services/saf/clmsv/nodeagent/Makefile.am
>>>> --- a/osaf/services/saf/clmsv/nodeagent/Makefile.am
>>>> +++ b/osaf/services/saf/clmsv/nodeagent/Makefile.am
>>>> @@ -23,7 +23,9 @@ SUBDIRS = scripts
>>>> noinst_HEADERS = \
>>>>     cb.h \
>>>>     clmna.h \
>>>> -    evt.h
>>>> +    evt.h \
>>>> +    election_starter.h \
>>>> +    election_starter_wrapper.h
>>>>
>>>> osaf_execbindir = $(pkglibdir)
>>>> osaf_execbin_PROGRAMS = osafclmna
>>>> @@ -35,9 +37,12 @@ osafclmna_CPPFLAGS = \
>>>>
>>>> osafclmna_SOURCES = \
>>>>     main.c \
>>>> -    amf.c
>>>> +    amf.c \
>>>> +    election_starter.cc \
>>>> +    election_starter_wrapper.cc
>>>>
>>>> osafclmna_LDADD = \
>>>>     $(top_builddir)/osaf/libs/common/clmsv/libclmsv_common.la \
>>>>     $(top_builddir)/osaf/libs/core/libopensaf_core.la \
>>>> -    $(top_builddir)/osaf/libs/saf/libSaAmf/libSaAmf.la
>>>> +    $(top_builddir)/osaf/libs/saf/libSaAmf/libSaAmf.la \
>>>> + $(top_builddir)/osaf/libs/agents/infrastructure/rda/librda.la
>>>> diff --git a/osaf/services/saf/clmsv/nodeagent/cb.h
>>>> b/osaf/services/saf/clmsv/nodeagent/cb.h
>>>> --- a/osaf/services/saf/clmsv/nodeagent/cb.h
>>>> +++ b/osaf/services/saf/clmsv/nodeagent/cb.h
>>>> @@ -57,6 +57,7 @@ typedef struct clmna_cb_t {
>>>>     tmr_t scale_out_retry_tmr;
>>>>     bool is_scale_out_retry_tmr_running;
>>>>     bool nid_started;    /**< true if started by NID */
>>>> +    void* election_starter;
>>>> } CLMNA_CB;
>>>>
>>>>
>>>> diff --git a/osaf/services/saf/clmsv/nodeagent/election_starter.cc
>>>> b/osaf/services/saf/clmsv/nodeagent/election_starter.cc
>>>> new file mode 100644
>>>> --- /dev/null
>>>> +++ b/osaf/services/saf/clmsv/nodeagent/election_starter.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): Ericsson AB
>>>> + *
>>>> + */
>>>> +
>>>> +#ifndef _GNU_SOURCE
>>>> +#define _GNU_SOURCE
>>>> +#endif
>>>> +#include "election_starter.h"
>>>> +#include <cassert>
>>>> +#include <cerrno>
>>>> +#include <cstdlib>
>>>> +#include <cstring>
>>>> +#include <set>
>>>> +#include "ncsgl_defs.h"
>>>> +#include "rda_papi.h"
>>>> +#include "nid_api.h"
>>>> +#include "logtrace.h"
>>>> +#include "base/getenv.h"
>>>> +
>>>> +const char* const ElectionStarter::service_name_[2] = {
>>>> +  "Node",
>>>> +  "Controller"
>>>> +};
>>>> +
>>>> +ElectionStarter::NodeCollection::NodeCollection()
>>>> +    : last_change(base::ReadMonotonicClock()) { }
>>>> +
>>>> +ElectionStarter::ElectionStarter(bool is_nid_started, uint32_t
>>>> own_node_id)
>>>> +    : election_delay_time_(
>>>> +          base::MillisToTimespec(
>>>> +              base::GetEnv("CLMNA_ELECTION_DELAY_TIME",
>>>> +                           kDefaultElectionDelayTime))),
>>>> +      is_nid_started_{is_nid_started},
>>>> +      starting_election_{false},
>>>> + last_election_start_attempt_(base::ReadMonotonicClock()),
>>>> +      own_node_id_{own_node_id},
>>>> +      controller_nodes_{},
>>>> +      nodes_with_lower_node_id_{},
>>>> +      nodes_with_greater_or_equal_node_id_{} { }
>>>> +
>>>> +void ElectionStarter::StartElection() {
>>>> +  TRACE_ENTER();
>>>> +  if (starting_election_ == false) {
>>>> +    LOG_NO("Starting to promote this node to a system controller");
>>>> +    starting_election_ = true;
>>>> +    if (is_nid_started_ && nid_notify(const_cast<char*>("CLMNA"),
>>>> +                                      NCSCC_RC_SUCCESS, nullptr) !=
>>>> +        NCSCC_RC_SUCCESS) {
>>>> +      LOG_ER("nid notify failed");
>>>> +    }
>>>> +  }
>>>> +  SaAmfHAStateT ha_state;
>>>> +  if (rda_get_role(&ha_state) == NCSCC_RC_SUCCESS &&
>>>> +      ha_state == SA_AMF_HA_QUIESCED) {
>>>> +    PCS_RDA_REQ rda_req;
>>>> +    rda_req.req_type = PCS_RDA_SET_ROLE;
>>>> +    rda_req.info.io_role = PCS_RDA_ACTIVE;
>>>> +    if (pcs_rda_request(&rda_req) == PCSRDA_RC_SUCCESS) {
>>>> +      starting_election_ = false;
>>>> +    }
>>>> +  }
>>>> +  last_election_start_attempt_ = base::ReadMonotonicClock();
>>>> +  TRACE_LEAVE();
>>>> +}
>>>> +
>>>> +ElectionStarter::NodeCollection& ElectionStarter::GetNodeCollection(
>>>> +    uint32_t node_id, ServiceType service_type) {
>>>> +  assert(service_type == Controller || service_type == Node);
>>>> +  if (service_type == Controller) {
>>>> +    return controller_nodes_;
>>>> +  } else if (node_id < own_node_id_) {
>>>> +    return nodes_with_lower_node_id_;
>>>> +  } else {
>>>> +    return nodes_with_greater_or_equal_node_id_;
>>>> +  }
>>>> +}
>>>> +
>>>> +void ElectionStarter::UpEvent(uint32_t node_id, ServiceType
>>>> +service_type) {
>>>> +  TRACE_ENTER2("%s up event on node %" PRIx32,
>>>> service_name_[service_type],
>>>> +               node_id);
>>>> +  NodeCollection& nodes = GetNodeCollection(node_id, service_type);
>>>> + std::pair<std::set<uint32_t>::iterator, bool> result =
>>>> nodes.tree.insert(
>>>> +      node_id);
>>>> +  if (result.second) nodes.last_change =
>>>> +base::ReadMonotonicClock();
>>>> +  TRACE_LEAVE();
>>>> +}
>>>> +
>>>> +void ElectionStarter::DownEvent(uint32_t node_id, ServiceType
>>>> +service_type) {
>>>> +  TRACE_ENTER2("%s down event on node %" PRIx32,
>>>> service_name_[service_type],
>>>> +               node_id);
>>>> +  NodeCollection& nodes = GetNodeCollection(node_id, service_type);
>>>> +  std::set<uint32_t>::size_type result = nodes.tree.erase(node_id);
>>>> +  if (result != 0) nodes.last_change = base::ReadMonotonicClock();
>>>> +  TRACE_LEAVE();
>>>> +}
>>>> +
>>>> +timespec ElectionStarter::Poll() {
>>>> +  TRACE_ENTER();
>>>> +  timespec timeout = CalculateTimeRemainingUntilNextEvent();
>>>> +  if (timeout == base::kZeroSeconds) {
>>>> +    StartElection();
>>>> +    timeout = base::kOneHundredMilliseconds;
>>>> +  }
>>>> +  TRACE_LEAVE2("timeout = %f", base::TimespecToDouble(timeout));
>>>> +  return timeout;
>>>> +}
>>>> +
>>>> +timespec ElectionStarter::CalculateTimeRemainingUntilNextEvent()
>>>> +const {
>>>> +  timespec timeout;
>>>> +  if (controller_nodes_.tree.size() == 0 &&
>>>> +      nodes_with_lower_node_id_.tree.size() == 0) {
>>>> +    timeout =
>>>> +        base::Max(controller_nodes_.last_change +
>>>> election_delay_time_,
>>>> +                  nodes_with_lower_node_id_.last_change +
>>>> election_delay_time_,
>>>> +                  last_election_start_attempt_ +
>>>> +base::kOneHundredMilliseconds);
>>>> +  } else {
>>>> +    timeout = base::kTimespecMax;
>>>> +  }
>>>> +  return CalculateTimeRemainingUntil(timeout);
>>>> +}
>>>> +
>>>> +timespec ElectionStarter::CalculateTimeRemainingUntil(
>>>> +    const timespec& time_stamp) {
>>>> +  timespec current_time = base::ReadMonotonicClock();
>>>> +  if (time_stamp >= current_time) return time_stamp - current_time;
>>>> +  else return base::kZeroSeconds;
>>>> +}
>>>> diff --git a/osaf/services/saf/clmsv/nodeagent/election_starter.h
>>>> b/osaf/services/saf/clmsv/nodeagent/election_starter.h
>>>> new file mode 100644
>>>> --- /dev/null
>>>> +++ b/osaf/services/saf/clmsv/nodeagent/election_starter.h
>>>> @@ -0,0 +1,94 @@
>>>> +/*      -*- 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): Ericsson AB
>>>> + *
>>>> + */
>>>> +
>>>> +#ifndef
>>>> OPENSAF_SERVICES_SAF_CLMSV_NODEAGENT_ELECTION_STARTER_H_
>>>> +#define
>>>> OPENSAF_SERVICES_SAF_CLMSV_NODEAGENT_ELECTION_STARTER_H_
>>>> +
>>>> +#include <stdint.h>
>>>> +#include <set>
>>>> +#include "base/macros.h"
>>>> +#include "base/time.h"
>>>> +
>>>> +class ElectionStarter {
>>>> +  DELETE_COPY_AND_MOVE_OPERATORS(ElectionStarter);
>>>> + public:
>>>> +  enum ServiceType {
>>>> +    /**
>>>> +     *  A service that runs on all nodes in the cluster, including
>>>> all system
>>>> +     *  controller nodes.
>>>> +     */
>>>> +    Node,
>>>> +    /**
>>>> +     *  A service that only runs on ACTIVE and STANDBY (i.e. not
>>>> spare) system
>>>> +     *  controller nodes.
>>>> +     */
>>>> +    Controller
>>>> +  };
>>>> +
>>>> +  /**
>>>> +   *  Report the service up event of a service which of type @a
>>>> service_type
>>>> on
>>>> +   *  the node @a node_id. Note that you have to call Poll() after
>>>> calling this
>>>> +   *  method.
>>>> +   */
>>>> +  ElectionStarter(bool is_nid_started, uint32_t own_node_id);
>>>> +  /**
>>>> +   *  Report the service up event of a service which of type @a
>>>> service_type
>>>> on
>>>> +   *  the node @a node_id. Note that you have to call Poll() after
>>>> calling this
>>>> +   *  method.
>>>> +   */
>>>> +  void UpEvent(uint32_t node_id, ServiceType service_type);
>>>> +  /**
>>>> +   *  Report the service down event of a service which of type @a
>>>> service_type
>>>> +   *  on the node @a node_id. Note that you have to call Poll()
>>>> after calling
>>>> +   *  this method.
>>>> +   */
>>>> +  void DownEvent(uint32_t node_id, ServiceType service_type);
>>>> +  /**
>>>> +   *  Do the work and return the time you can wait until you need
>>>> to call Poll()
>>>> +   *  again Note that you always have to call Poll() immediately
>>>> after any
>>>> +   *  UpEvent() or DownEvent(), regardless of the return value from
>>>> any
>>>> previous
>>>> +   *  call to Poll().
>>>> +   */
>>>> +  timespec Poll();
>>>> +
>>>> + private:
>>>> +  static const uint64_t kDefaultElectionDelayTime = 5000;
>>>> +
>>>> +  struct NodeCollection {
>>>> +    NodeCollection();
>>>> +    std::set<uint32_t> tree;
>>>> +    timespec last_change;
>>>> +  };
>>>> +
>>>> +  void StartElection();
>>>> +  NodeCollection& GetNodeCollection(uint32_t node_id, ServiceType
>>>> + service);  timespec CalculateTimeRemainingUntilNextEvent() const;
>>>> + static timespec CalculateTimeRemainingUntil(const timespec&
>>>> + time_stamp);
>>>> +
>>>> +  timespec election_delay_time_;
>>>> +  bool is_nid_started_;
>>>> +  bool starting_election_;
>>>> +  timespec last_election_start_attempt_;  uint32_t own_node_id_;
>>>> +
>>>> +  NodeCollection controller_nodes_;  NodeCollection
>>>> + nodes_with_lower_node_id_;  NodeCollection
>>>> + nodes_with_greater_or_equal_node_id_;
>>>> +  static const char* const service_name_[2]; };
>>>> +
>>>> +#endif /*
>>>> OPENSAF_SERVICES_SAF_CLMSV_NODEAGENT_ELECTION_STARTER_H_
>*/ diff
>>>> --git
>>>> a/osaf/services/saf/clmsv/nodeagent/election_starter_wrapper.cc
>>>> b/osaf/services/saf/clmsv/nodeagent/election_starter_wrapper.cc
>>>> new file mode 100644
>>>> --- /dev/null
>>>> +++ b/osaf/services/saf/clmsv/nodeagent/election_starter_wrapper.cc
>>>> @@ -0,0 +1,46 @@
>>>> +/*      -*- 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): Ericsson AB
>>>> + *
>>>> + */
>>>> +
>>>> +#ifndef _GNU_SOURCE
>>>> +#define _GNU_SOURCE
>>>> +#endif
>>>> +#include "election_starter_wrapper.h"
>>>> +#include "election_starter.h"
>>>> +
>>>> +void ElectionStarterUpEvent(void* instance, uint32_t node_id,
>>>> +                            enum ElectionStarterServiceType
>>>> +service) {
>>>> +  static_cast<ElectionStarter*>(instance)->UpEvent(
>>>> +      node_id,
>>>> +      service == ElectionStarterServiceNode ?
>>>> +          ElectionStarter::Node : ElectionStarter::Controller); }
>>>> +
>>>> +void ElectionStarterDownEvent(void* instance, uint32_t node_id,
>>>> +                              enum ElectionStarterServiceType
>>>> +service) {  static_cast<ElectionStarter*>(instance)->DownEvent(
>>>> +      node_id,
>>>> +      service == ElectionStarterServiceNode ?
>>>> +          ElectionStarter::Node : ElectionStarter::Controller); }
>>>> +
>>>> +struct timespec ElectionStarterPoll(void* instance) {
>>>> +  return static_cast<ElectionStarter*>(instance)->Poll();
>>>> +}
>>>> +
>>>> +void* ElectionStarterConstructor(bool is_nid_started, uint32_t
>>>> +own_node_id) {
>>>> +  return new ElectionStarter(is_nid_started, own_node_id); }
>>>> diff --git
>>>> a/osaf/services/saf/clmsv/nodeagent/election_starter_wrapper.h
>>>> b/osaf/services/saf/clmsv/nodeagent/election_starter_wrapper.h
>>>> new file mode 100644
>>>> --- /dev/null
>>>> +++ b/osaf/services/saf/clmsv/nodeagent/election_starter_wrapper.h
>>>> @@ -0,0 +1,45 @@
>>>> +/*      -*- 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): Ericsson AB
>>>> + *
>>>> + */
>>>> +
>>>> +#ifndef
>>>>
>+OPENSAF_SERVICES_SAF_CLMSV_NODEAGENT_ELECTION_STARTER_WRAP
>>>> PER_H_
>>>> +#define
>>>>
>+OPENSAF_SERVICES_SAF_CLMSV_NODEAGENT_ELECTION_STARTER_WRAP
>>>> PER_H_
>>>> +
>>>> +#include <stdbool.h>
>>>> +#include <stdint.h>
>>>> +#include <time.h>
>>>> +
>>>> +#ifdef    __cplusplus
>>>> +extern "C" {
>>>> +#endif
>>>> +
>>>> +enum ElectionStarterServiceType {
>>>> +  ElectionStarterServiceNode,
>>>> +  ElectionStarterServiceController
>>>> +};
>>>> +
>>>> +void ElectionStarterUpEvent(void* instance, uint32_t node_id,
>>>> +                            enum ElectionStarterServiceType
>>>> +service); void ElectionStarterDownEvent(void* instance, uint32_t
>node_id,
>>>> +                              enum ElectionStarterServiceType
>>>> service);
>>>> +struct timespec ElectionStarterPoll(void* instance);
>>>> +void* ElectionStarterConstructor(bool is_nid_started, uint32_t
>>>> +own_node_id);
>>>> +
>>>> +#ifdef    __cplusplus
>>>> +}
>>>> +#endif
>>>> +
>>>> +#endif    /*
>>>>
>OPENSAF_SERVICES_SAF_CLMSV_NODEAGENT_ELECTION_STARTER_WRAPP
>>>> ER_H_ */
>>>> diff --git a/osaf/services/saf/clmsv/nodeagent/evt.h
>>>> b/osaf/services/saf/clmsv/nodeagent/evt.h
>>>> --- a/osaf/services/saf/clmsv/nodeagent/evt.h
>>>> +++ b/osaf/services/saf/clmsv/nodeagent/evt.h
>>>> @@ -24,7 +24,7 @@
>>>> typedef NCS_IPC_MSG CLMNA_MBX_MSG;
>>>> typedef enum clmna_evt_type {
>>>>     CLMNA_EVT_INVALID = 0,
>>>> -    CLMNA_EVT_DUMMY_MSG,
>>>> +    CLMNA_EVT_CHANGE_MSG,
>>>>     CLMNA_EVT_MAX_MSG
>>>> } CLMNA_EVT_TYPE;
>>>>
>>>> @@ -32,6 +32,9 @@ typedef struct clmna_evt_tags {
>>>>     CLMNA_MBX_MSG next;
>>>>     CLMNA_EVT_TYPE type;
>>>>     bool caused_by_timer_expiry;
>>>> +    NCSMDS_CHG change;
>>>> +    NODE_ID node_id;
>>>> +    MDS_SVC_ID svc_id;
>>>> } CLMNA_EVT;
>>>>
>>>>
>>>> diff --git a/osaf/services/saf/clmsv/nodeagent/main.c
>>>> b/osaf/services/saf/clmsv/nodeagent/main.c
>>>> --- a/osaf/services/saf/clmsv/nodeagent/main.c
>>>> +++ b/osaf/services/saf/clmsv/nodeagent/main.c
>>>> @@ -16,6 +16,10 @@
>>>>   *
>>>>   */
>>>>
>>>> +#define _GNU_SOURCE
>>>> +#include <errno.h>
>>>> +#include <stdlib.h>
>>>> +#include <string.h>
>>>> #include <stdbool.h>
>>>> #include "cb.h"
>>>> #include <ncs_main_papi.h>
>>>> @@ -30,7 +34,11 @@
>>>> #include "clmsv_enc_dec.h"
>>>> #include "evt.h"
>>>> #include "clmna.h"
>>>> -#include<errno.h>
>>>> +#include "osaf_poll.h"
>>>> +#include "osaf_time.h"
>>>> +#include "ncsgl_defs.h"
>>>> +#include "mds_papi.h"
>>>> +#include "election_starter_wrapper.h"
>>>>
>>>> enum {
>>>>     FD_TERM = 0,
>>>> @@ -47,7 +55,7 @@ static NCS_SEL_OBJ usr1_sel_obj;
>>>>
>>>>
>>>> #define CLMNA_MDS_SUB_PART_VERSION   1
>>>> -#define CLMS_NODEUP_WAIT_TIME 1000
>>>> +#define CLMS_NODEUP_WAIT_TIME 60000
>>>> #define CLMNA_SCALE_OUT_RETRY_TIME 100 #define
>>>> CLMNA_SVC_PVT_SUBPART_VERSION  1  #define
>>>> CLMNA_WRT_CLMS_SUBPART_VER_AT_MIN_MSG_FMT 1 @@ -156,6
>>>> +164,36 @@ static uint32_t clmna_mds_rcv(struct ncs
>>>>     return NCSCC_RC_SUCCESS;
>>>> }
>>>>
>>>> +static void clmna_handle_mds_change_evt(bool
>caused_by_timer_expiry,
>>>> +    NCSMDS_CHG change, NODE_ID node_id, MDS_SVC_ID svc_id) {
>>>> +    if ((change == NCSMDS_NEW_ACTIVE || change == NCSMDS_UP) &&
>>>> +        svc_id == NCSMDS_SVC_ID_CLMS && clmna_cb->server_synced ==
>>>> false) {
>>>> +        if (clmna_process_dummyup_msg(caused_by_timer_expiry)
>>>> != SA_AIS_OK) {
>>>> +            /* NID will anyway stop and retry */
>>>> +            LOG_ER("Exiting");
>>>> +        }
>>>> +    }
>>>> +
>>>> +    if (caused_by_timer_expiry == false &&
>>>> +        (change == NCSMDS_UP || change == NCSMDS_DOWN) &&
>>>> +        (svc_id == NCSMDS_SVC_ID_CLMNA || svc_id ==
>>>> NCSMDS_SVC_ID_RDE)) {
>>>> +        if (change == NCSMDS_UP) {
>>>> + ElectionStarterUpEvent(clmna_cb->election_starter,
>>>> +                           node_id,
>>>> +                           svc_id ==
>>>> NCSMDS_SVC_ID_CLMNA ?
>>>> +                           ElectionStarterServiceNode :
>>>> +                           ElectionStarterServiceController);
>>>> +        } else {
>>>> +            ElectionStarterDownEvent(clmna_cb-
>>>>> election_starter,
>>>> +                         node_id,
>>>> +                         svc_id ==
>>>> NCSMDS_SVC_ID_CLMNA ?
>>>> +                         ElectionStarterServiceNode :
>>>> +
>>>> ElectionStarterServiceController);
>>>> +        }
>>>> +    }
>>>> +}
>>>> +
>>>> static uint32_t clmna_mds_svc_evt(struct ncsmds_callback_info
>>>> *mds_cb_info)  {
>>>>     TRACE_ENTER2("%d", mds_cb_info->info.svc_evt.i_change);
>>>> @@ -169,11 +207,6 @@ static uint32_t clmna_mds_svc_evt(struct
>>>>             clmna_cb->clms_mds_dest = mds_cb_info-
>>>>> info.svc_evt.i_dest;
>>>>             TRACE("subpart version: %u", mds_cb_info-
>>>>> info.svc_evt.i_rem_svc_pvt_ver);
>>>>             TRACE("svc_id %d", mds_cb_info-
>>>>> info.svc_evt.i_svc_id);
>>>> -            evt = calloc(1, sizeof(CLMNA_EVT));
>>>> -            evt->type = CLMNA_EVT_DUMMY_MSG;
>>>> -            evt->caused_by_timer_expiry = false;
>>>> -            if (m_NCS_IPC_SEND(&clmna_cb->mbx, evt,
>>>> NCS_IPC_PRIORITY_VERY_HIGH) != NCSCC_RC_SUCCESS)
>>>> -                LOG_ER("IPC send to mailbox failed: %s",
>>>> __FUNCTION__);
>>>>             break;
>>>>         default:
>>>>             break;
>>>> @@ -183,6 +216,17 @@ static uint32_t clmna_mds_svc_evt(struct
>>>>         break;
>>>>     }
>>>>
>>>> +    evt = calloc(1, sizeof(CLMNA_EVT));
>>>> +    evt->type = CLMNA_EVT_CHANGE_MSG;
>>>> +    evt->caused_by_timer_expiry = false;
>>>> +    evt->change = mds_cb_info->info.svc_evt.i_change;
>>>> +    evt->node_id = mds_cb_info->info.svc_evt.i_node_id;
>>>> +    evt->svc_id = mds_cb_info->info.svc_evt.i_svc_id;
>>>> +    if (m_NCS_IPC_SEND(&clmna_cb->mbx, evt,
>>>> NCS_IPC_PRIORITY_VERY_HIGH) !=
>>>> +        NCSCC_RC_SUCCESS) {
>>>> +        LOG_ER("IPC send to mailbox failed: %s", __FUNCTION__);
>>>> +    }
>>>> +
>>>>     TRACE_LEAVE();
>>>>     return NCSCC_RC_SUCCESS;
>>>> }
>>>> @@ -302,7 +346,8 @@ static uint32_t clmna_mds_init(void)
>>>>     NCSADA_INFO ada_info;
>>>>     NCSMDS_INFO mds_info;
>>>>     uint32_t rc = NCSCC_RC_SUCCESS;
>>>> -    MDS_SVC_ID svc = NCSMDS_SVC_ID_CLMS;
>>>> +    MDS_SVC_ID svc[] = { NCSMDS_SVC_ID_CLMS,
>>>> NCSMDS_SVC_ID_CLMNA,
>>>> +        NCSMDS_SVC_ID_RDE };
>>>>
>>>>     TRACE_ENTER();
>>>>
>>>> @@ -345,8 +390,8 @@ static uint32_t clmna_mds_init(void)
>>>>     mds_info.i_op = MDS_SUBSCRIBE;
>>>>
>>>>     mds_info.info.svc_subscribe.i_scope = NCSMDS_SCOPE_NONE;
>>>> -    mds_info.info.svc_subscribe.i_num_svcs = 1;
>>>> -    mds_info.info.svc_subscribe.i_svc_ids = &svc;
>>>> +    mds_info.info.svc_subscribe.i_num_svcs = 3;
>>>> +    mds_info.info.svc_subscribe.i_svc_ids = svc;
>>>>
>>>>     rc = ncsmds_api(&mds_info);
>>>>     if (rc != NCSCC_RC_SUCCESS) {
>>>> @@ -434,8 +479,11 @@ static void scale_out_tmr_exp(void *arg)
>>>>     if (clmna_cb->is_scale_out_retry_tmr_running == true) {
>>>>         CLMNA_EVT *evt = calloc(1, sizeof(CLMNA_EVT));
>>>>         if (evt != NULL) {
>>>> -            evt->type = CLMNA_EVT_DUMMY_MSG;
>>>> +            evt->type = CLMNA_EVT_CHANGE_MSG;
>>>>             evt->caused_by_timer_expiry = true;
>>>> +            evt->change = NCSMDS_UP;
>>>> +            evt->node_id = 0;
>>>> +            evt->svc_id = NCSMDS_SVC_ID_CLMS;
>>>>             if (m_NCS_IPC_SEND(&clmna_cb->mbx, evt,
>>>>                 NCS_IPC_PRIORITY_VERY_HIGH) !=
>>>> NCSCC_RC_SUCCESS)
>>>>                 LOG_ER("IPC send to mailbox failed: %s", @@
>>>> -567,17 +615,11 @@ void clmna_process_mbx(SYSF_MBX *mbx)
>>>>         goto done;
>>>>     }
>>>>     switch (msg->type) {
>>>> -    case CLMNA_EVT_DUMMY_MSG:
>>>> -        if (clmna_cb->server_synced == false) {
>>>> -            if (clmna_process_dummyup_msg(msg->
>>>> -                caused_by_timer_expiry) != SA_AIS_OK) {
>>>> -                /* NID will anyway stop and retry */
>>>> -                LOG_ER("Exiting");
>>>> -                free(msg);
>>>> -                msg = NULL;
>>>> -            } else
>>>> -                goto done;
>>>> -        }
>>>> +    case CLMNA_EVT_CHANGE_MSG:
>>>> +        clmna_handle_mds_change_evt(msg-
>>>>> caused_by_timer_expiry,
>>>> +            msg->change,
>>>> +            msg->node_id,
>>>> +            msg->svc_id);
>>>>         break;
>>>>     default:
>>>>         TRACE("Invalid message type"); @@ -673,6 +715,10 @@ int
>>>> main(int argc, char *argv[])
>>>>         goto done;
>>>>     }
>>>>
>>>> +    clmna_cb->election_starter =
>>>> +        ElectionStarterConstructor(clmna_cb->nid_started,
>>>> +                       clmna_cb->node_info.node_id);
>>>> +
>>>>     fds[FD_TERM].fd = term_fd;
>>>>     fds[FD_TERM].events = POLLIN;
>>>>     fds[FD_AMF].fd = clmna_cb->nid_started ?
>>>> @@ -682,14 +728,11 @@ int main(int argc, char *argv[])
>>>>     fds[FD_MBX].events = POLLIN;
>>>>
>>>>     while (1) {
>>>> -        ret = poll(fds, nfds, -1);
>>>> +        struct timespec timeout = ElectionStarterPoll(clmna_cb-
>>>>> election_starter);
>>>> +        ret = osaf_ppoll(fds, nfds, &timeout, NULL);
>>>>
>>>> -        if (ret == -1) {
>>>> -            if (errno == EINTR)
>>>> -                continue;
>>>> -
>>>> -            LOG_ER("%s: poll failed - %s", __FUNCTION__,
>>>> strerror(errno));
>>>> -            break;
>>>> +        if (ret == 0) {
>>>> +            continue;
>>>>         }
>>>>
>>>>         if (fds[FD_TERM].revents & POLLIN) {
>>
>

------------------------------------------------------------------------------
Transform Data into Opportunity.
Accelerate data analysis in your applications with
Intel Data Analytics Acceleration Library.
Click to learn more.
http://pubads.g.doubleclick.net/gampad/clk?id=278785471&iu=/4140
_______________________________________________
Opensaf-devel mailing list
Opensaf-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to