From: Gunnar Beutner Date: Wed, 11 May 2016 10:50:08 +0000 (+0200) Subject: Only activate HARunOnce objects once there's a cluster connection X-Git-Tag: v2.5.0~328 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fc1168ed3e1f587fb16f4d616895c054495644b3;p=icinga2 Only activate HARunOnce objects once there's a cluster connection fixes #11765 --- diff --git a/lib/base/application.cpp b/lib/base/application.cpp index b0cdc1286..c9e2c7c33 100644 --- a/lib/base/application.cpp +++ b/lib/base/application.cpp @@ -60,6 +60,7 @@ static bool l_InExceptionHandler = false; int Application::m_ArgC; char **Application::m_ArgV; double Application::m_StartTime; +double Application::m_MainTime; bool Application::m_ScriptDebuggerEnabled = false; /** @@ -885,6 +886,8 @@ int Application::Run(void) return EXIT_FAILURE; } + SetMainTime(Utility::GetTime()); + return Main(); } @@ -1364,6 +1367,16 @@ void Application::SetStartTime(double ts) m_StartTime = ts; } +double Application::GetMainTime(void) +{ + return m_MainTime; +} + +void Application::SetMainTime(double ts) +{ + m_MainTime = ts; +} + bool Application::GetScriptDebuggerEnabled(void) { return m_ScriptDebuggerEnabled; diff --git a/lib/base/application.hpp b/lib/base/application.hpp index d030eb2a7..2174d3e03 100644 --- a/lib/base/application.hpp +++ b/lib/base/application.hpp @@ -134,6 +134,9 @@ public: static double GetStartTime(void); static void SetStartTime(double ts); + static double GetMainTime(void); + static void SetMainTime(double ts); + static bool GetScriptDebuggerEnabled(void); static void SetScriptDebuggerEnabled(bool enabled); @@ -167,6 +170,7 @@ private: static bool m_Debugging; /**< Whether debugging is enabled. */ static LogSeverity m_DebuggingSeverity; /**< Whether debugging severity is set. */ static double m_StartTime; + static double m_MainTime; static bool m_ScriptDebuggerEnabled; #ifndef _WIN32 diff --git a/lib/base/configobject.cpp b/lib/base/configobject.cpp index cfb099480..1cb6e3f3c 100644 --- a/lib/base/configobject.cpp +++ b/lib/base/configobject.cpp @@ -396,7 +396,8 @@ void ConfigObject::Activate(bool runtimeCreated) SetActive(true, true); } - SetAuthority(true); + if (GetHAMode() == HARunEverywhere) + SetAuthority(true); NotifyActive(); } diff --git a/lib/cli/daemoncommand.cpp b/lib/cli/daemoncommand.cpp index f650af3a4..be32b22d6 100644 --- a/lib/cli/daemoncommand.cpp +++ b/lib/cli/daemoncommand.cpp @@ -19,6 +19,7 @@ #include "cli/daemoncommand.hpp" #include "cli/daemonutility.hpp" +#include "remote/apilistener.hpp" #include "config/configcompiler.hpp" #include "config/configcompilercontext.hpp" #include "config/configitembuilder.hpp" @@ -302,5 +303,8 @@ int DaemonCommand::Run(const po::variables_map& vm, const std::vectorRun(); } diff --git a/lib/remote/apilistener.hpp b/lib/remote/apilistener.hpp index 4c860f89b..d4cb5e540 100644 --- a/lib/remote/apilistener.hpp +++ b/lib/remote/apilistener.hpp @@ -97,6 +97,9 @@ public: static Value ConfigDeleteObjectAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params); static Value HelloAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params); + + static void UpdateObjectAuthorityAsync(void); + protected: virtual void OnConfigLoaded(void) override; virtual void OnAllConfigLoaded(void) override; diff --git a/lib/remote/authority.cpp b/lib/remote/authority.cpp index 37a244ee4..cb81fa927 100644 --- a/lib/remote/authority.cpp +++ b/lib/remote/authority.cpp @@ -36,42 +36,60 @@ static bool ObjectNameLessComparer(const ConfigObject::Ptr& a, const ConfigObjec static void AuthorityTimerHandler(void) { - ApiListener::Ptr listener = ApiListener::GetInstance(); + Zone::Ptr my_zone = Zone::GetLocalZone(); - if (!listener || !listener->IsActive()) - return; + std::vector endpoints; + Endpoint::Ptr my_endpoint; - Zone::Ptr my_zone = Zone::GetLocalZone(); - if (!my_zone) - return; + if (my_zone) { + my_endpoint = Endpoint::GetLocalEndpoint(); - Endpoint::Ptr my_endpoint = Endpoint::GetLocalEndpoint(); + int num_total = 0; - std::vector endpoints; - BOOST_FOREACH(const Endpoint::Ptr& endpoint, my_zone->GetEndpoints()) { - if (!endpoint->GetConnected() && endpoint != my_endpoint) - continue; + BOOST_FOREACH(const Endpoint::Ptr& endpoint, my_zone->GetEndpoints()) { + num_total++; - endpoints.push_back(endpoint); - } + if (endpoint != my_endpoint && !endpoint->GetConnected()) + continue; + + endpoints.push_back(endpoint); + } + + double mainTime = Application::GetMainTime(); - std::sort(endpoints.begin(), endpoints.end(), ObjectNameLessComparer); + if (num_total > 1 && endpoints.size() <= 1 && (mainTime == 0 || Utility::GetTime() - mainTime < 60)) + return; + + std::sort(endpoints.begin(), endpoints.end(), ObjectNameLessComparer); + } BOOST_FOREACH(const ConfigType::Ptr& type, ConfigType::GetTypes()) { BOOST_FOREACH(const ConfigObject::Ptr& object, type->GetObjects()) { - Endpoint::Ptr endpoint = endpoints[Utility::SDBM(object->GetName()) % endpoints.size()]; + if (object->GetHAMode() != HARunOnce) + continue; + + bool authority; + + if (!my_zone) + authority = true; + else + authority = endpoints[Utility::SDBM(object->GetName()) % endpoints.size()] == my_endpoint; - if (object->GetHAMode() == HARunOnce) - object->SetAuthority(endpoint == my_endpoint); + object->SetAuthority(authority); } } } +void ApiListener::UpdateObjectAuthorityAsync(void) +{ + l_AuthorityTimer->Reschedule(0); +} + static void StaticInitialize(void) { l_AuthorityTimer = new Timer(); l_AuthorityTimer->OnTimerExpired.connect(boost::bind(&AuthorityTimerHandler)); - l_AuthorityTimer->SetInterval(30); + l_AuthorityTimer->SetInterval(15); l_AuthorityTimer->Start(); }