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:start: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_WRAPPER_H_ +#define OPENSAF_SERVICES_SAF_CLMSV_NODEAGENT_ELECTION_STARTER_WRAPPER_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_WRAPPER_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) { ------------------------------------------------------------------------------ Site24x7 APM Insight: Get Deep Visibility into Application Performance APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month Monitor end-to-end web transactions and take corrective actions now Troubleshoot faster and improve end-user experience. Signup Now! http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140 _______________________________________________ Opensaf-devel mailing list Opensaf-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/opensaf-devel