Avoid concurrent cluster config sync transactions

fixes #6660
This commit is contained in:
Michael Friedrich 2019-05-13 11:26:39 +02:00
parent 2bc78fc1e7
commit 6a8823f879
2 changed files with 9 additions and 0 deletions

View File

@ -15,6 +15,8 @@ using namespace icinga;
REGISTER_APIFUNCTION(Update, config, &ApiListener::ConfigUpdateHandler); REGISTER_APIFUNCTION(Update, config, &ApiListener::ConfigUpdateHandler);
boost::mutex ApiListener::m_ConfigSyncStageLock;
void ApiListener::ConfigGlobHandler(ConfigDirInformation& config, const String& path, const String& file) void ApiListener::ConfigGlobHandler(ConfigDirInformation& config, const String& path, const String& file)
{ {
CONTEXT("Creating config update for file '" + file + "'"); CONTEXT("Creating config update for file '" + file + "'");
@ -274,6 +276,11 @@ Value ApiListener::ConfigUpdateHandler(const MessageOrigin::Ptr& origin, const D
return Empty; return Empty;
} }
/* Only one transaction is allowed, concurrent message handlers need to wait.
* This affects two parent endpoints sending the config in the same moment.
*/
boost::mutex::scoped_lock lock(m_ConfigSyncStageLock);
Log(LogInformation, "ApiListener") Log(LogInformation, "ApiListener")
<< "Applying config update from endpoint '" << origin->FromClient->GetEndpoint()->GetName() << "Applying config update from endpoint '" << origin->FromClient->GetEndpoint()->GetName()
<< "' of zone '" << GetFromZoneName(origin->FromZone) << "'."; << "' of zone '" << GetFromZoneName(origin->FromZone) << "'.";

View File

@ -165,6 +165,8 @@ private:
void RemoveStatusFile(); void RemoveStatusFile();
/* filesync */ /* filesync */
static boost::mutex m_ConfigSyncStageLock;
static ConfigDirInformation LoadConfigDir(const String& dir); static ConfigDirInformation LoadConfigDir(const String& dir);
static Dictionary::Ptr MergeConfigUpdate(const ConfigDirInformation& config); static Dictionary::Ptr MergeConfigUpdate(const ConfigDirInformation& config);
static bool UpdateConfigDir(const ConfigDirInformation& oldConfig, const ConfigDirInformation& newConfig, const String& configDir, bool authoritative); static bool UpdateConfigDir(const ConfigDirInformation& oldConfig, const ConfigDirInformation& newConfig, const String& configDir, bool authoritative);