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