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