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.controller
>@@ -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