Move the reading environment variables to a new class. The new class's
implemented as singleton class.
---
src/osaf/Makefile.am | 6 +-
src/osaf/consensus/consensus.cc | 104 +++++++-----------------
src/osaf/consensus/consensus.h | 12 +--
src/osaf/consensus/consensus_env.cc | 120 ++++++++++++++++++++++++++++
src/osaf/consensus/consensus_env.h | 55 +++++++++++++
5 files changed, 209 insertions(+), 88 deletions(-)
create mode 100644 src/osaf/consensus/consensus_env.cc
create mode 100644 src/osaf/consensus/consensus_env.h
diff --git a/src/osaf/Makefile.am b/src/osaf/Makefile.am
index 9d334b4a4..e60b33ae6 100644
--- a/src/osaf/Makefile.am
+++ b/src/osaf/Makefile.am
@@ -28,7 +28,8 @@ noinst_HEADERS += \
src/osaf/immutil/immutil.h \
src/osaf/saflog/saflog.h \
src/osaf/consensus/key_value.h \
- src/osaf/consensus/consensus.h
+ src/osaf/consensus/consensus.h \
+ src/osaf/consensus/consensus_env.h
# immtools headers
# IMM configuration modifier
@@ -67,7 +68,8 @@ lib_libosaf_common_la_SOURCES = \
src/osaf/immutil/immutil.c \
src/osaf/saflog/saflog.c \
src/osaf/consensus/key_value.cc \
- src/osaf/consensus/consensus.cc
+ src/osaf/consensus/consensus.cc \
+ src/osaf/consensus/consensus_env.cc
# immtools code
# IMM configuration modifier
diff --git a/src/osaf/consensus/consensus.cc b/src/osaf/consensus/consensus.cc
index 0e37fa38d..9e32784ba 100644
--- a/src/osaf/consensus/consensus.cc
+++ b/src/osaf/consensus/consensus.cc
@@ -30,7 +30,7 @@ SaAisErrorT Consensus::PromoteThisNode(const bool
graceful_takeover,
TRACE_ENTER();
SaAisErrorT rc;
- if (use_consensus_ == false) {
+ if (cfg_.use_consensus == false) {
return SA_AIS_OK;
}
@@ -126,7 +126,7 @@ SaAisErrorT Consensus::RemoveTakeoverRequest() {
SaAisErrorT Consensus::Demote(const std::string& node) {
TRACE_ENTER();
- if (use_consensus_ == false) {
+ if (cfg_.use_consensus == false) {
return SA_AIS_OK;
}
@@ -172,11 +172,11 @@ SaAisErrorT Consensus::DemoteThisNode() {
return Demote(base::Conf::NodeName());
}
-bool Consensus::IsEnabled() const { return use_consensus_; }
+bool Consensus::IsEnabled() const { return cfg_.use_consensus; }
bool Consensus::IsWritable() const {
TRACE_ENTER();
- if (use_consensus_ == false) {
+ if (cfg_.use_consensus == false) {
return true;
}
@@ -197,27 +197,29 @@ bool Consensus::IsWritable() const {
}
}
-bool Consensus::IsRemoteFencingEnabled() const { return use_remote_fencing_; }
+bool Consensus::IsRemoteFencingEnabled() const {
+ return cfg_.use_remote_fencing;
+}
bool Consensus::IsRelaxedNodePromotionEnabled() const {
- return relaxed_node_promotion_;
+ return cfg_.relaxed_node_promotion;
}
bool Consensus::PrioritisePartitionSize() const {
- return prioritise_partition_size_;
+ return cfg_.prioritise_partition_size;
}
uint32_t Consensus::PrioritisePartitionSizeWaitTime() const {
- return prioritise_partition_size_mds_wait_time_;
+ return cfg_.prioritise_partition_size_mds_wait_time;
}
uint32_t Consensus::TakeoverValidTime() const {
- return takeover_valid_time_;
+ return cfg_.takeover_valid_time;
}
std::string Consensus::CurrentActive() const {
TRACE_ENTER();
- if (use_consensus_ == false) {
+ if (cfg_.use_consensus == false) {
return "";
}
@@ -252,78 +254,28 @@ Consensus::Consensus() {
Consensus::~Consensus() {}
void Consensus::ProcessEnvironmentSettings() {
- uint32_t split_brain_enable = base::GetEnv("FMS_SPLIT_BRAIN_PREVENTION", 0);
- plugin_path_ = base::GetEnv("FMS_KEYVALUE_STORE_PLUGIN_CMD", "");
- uint32_t use_remote_fencing = base::GetEnv("FMS_USE_REMOTE_FENCING", 0);
- uint32_t prioritise_partition_size =
- base::GetEnv("FMS_TAKEOVER_PRIORITISE_PARTITION_SIZE", 1);
- uint32_t prioritise_partition_size_mds_wait_time =
- base::GetEnv("FMS_TAKEOVER_PRIORITISE_PARTITION_SIZE_MDS_WAIT_TIME", 4);
- uint32_t relaxed_node_promotion =
- base::GetEnv("FMS_RELAXED_NODE_PROMOTION", 0);
- config_file_ = base::GetEnv("FMS_CONF_FILE", "");
-
- // if not specified in fmd.conf,
- // takeover requests are valid for 20 seconds
- takeover_valid_time_ =
- base::GetEnv("FMS_TAKEOVER_REQUEST_VALID_TIME", 20);
- // expiration time of takeover request is twice the max wait time
- max_takeover_retry_ = takeover_valid_time_ / 2;
-
- if (split_brain_enable == 1 && plugin_path_.empty() == false) {
- use_consensus_ = true;
- } else {
- use_consensus_ = false;
- }
-
- if (use_remote_fencing == 1) {
- use_remote_fencing_ = true;
- }
-
- if (prioritise_partition_size == 0) {
- prioritise_partition_size_ = false;
- }
+ ConsensusEnv& env = ConsensusEnv::GetInstance();
- if (use_consensus_ == true && relaxed_node_promotion == 1) {
- relaxed_node_promotion_ = true;
- }
-
- prioritise_partition_size_mds_wait_time_ =
- prioritise_partition_size_mds_wait_time;
+ cfg_ = env.GetConfiguration();
}
bool Consensus::ReloadConfiguration() {
- ConfigFileReader reader;
- ConfigFileReader::SettingsMap map;
+ ConsensusEnv& env = ConsensusEnv::GetInstance();
- if (config_file_.empty() == true) {
- LOG_ER("config file not defined");
+ if (!env.ReloadConfiguration()) {
return false;
}
-
- map = reader.ParseFile(config_file_);
- for (const auto& kv : map) {
- if (kv.first.compare(0, kFmsEnvPrefix.size(), kFmsEnvPrefix) != 0) {
- // we only care about environment variables beginning with 'FMS'
- continue;
- }
- int rc;
- TRACE("Setting '%s' to '%s'", kv.first.c_str(), kv.second.c_str());
- rc = setenv(kv.first.c_str(), kv.second.c_str(), 1);
- osafassert(rc == 0);
- }
-
ProcessEnvironmentSettings();
return true;
}
std::string Consensus::PluginPath() const {
- return plugin_path_;
+ return cfg_.plugin_path;
}
bool Consensus::FenceNode(const std::string& node) {
- if (use_remote_fencing_ == true) {
+ if (cfg_.use_remote_fencing == true) {
LOG_WA("Fencing remote node %s", node.c_str());
// @todo currently passing UINT_MAX as node ID, since
// we can't always obtain a valid node ID?
@@ -339,7 +291,7 @@ bool Consensus::FenceNode(const std::string& node) {
void Consensus::MonitorLock(ConsensusCallback callback,
const uint32_t user_defined) {
TRACE_ENTER();
- if (use_consensus_ == false) {
+ if (cfg_.use_consensus == false) {
return;
}
@@ -349,7 +301,7 @@ void Consensus::MonitorLock(ConsensusCallback callback,
void Consensus::MonitorTakeoverRequest(ConsensusCallback callback,
const uint32_t user_defined) {
TRACE_ENTER();
- if (use_consensus_ == false) {
+ if (cfg_.use_consensus == false) {
return;
}
@@ -374,7 +326,7 @@ void Consensus::CheckForExistingTakeoverRequest() {
// or until the takeover request is gone
rc = ReadTakeoverRequest(tokens);
while (rc == SA_AIS_OK &&
- retries < max_takeover_retry_) {
+ retries < cfg_.max_takeover_retry) {
++retries;
TRACE("Takeover request still present");
std::this_thread::sleep_for(kSleepInterval);
@@ -404,12 +356,12 @@ SaAisErrorT Consensus::CreateTakeoverRequest(const
std::string& current_owner,
SaAisErrorT rc;
uint32_t retries = 0;
rc = KeyValue::Create(kTakeoverRequestKeyname, takeover_request,
- takeover_valid_time_);
+ cfg_.takeover_valid_time);
while (rc == SA_AIS_ERR_FAILED_OPERATION && retries < kMaxRetry) {
++retries;
std::this_thread::sleep_for(kSleepInterval);
rc = KeyValue::Create(kTakeoverRequestKeyname, takeover_request,
- takeover_valid_time_);
+ cfg_.takeover_valid_time);
}
if (rc == SA_AIS_ERR_EXIST) {
@@ -422,7 +374,7 @@ SaAisErrorT Consensus::CreateTakeoverRequest(const
std::string& current_owner,
// or until the takeover request is gone
rc = ReadTakeoverRequest(tokens);
while (rc == SA_AIS_OK &&
- retries < max_takeover_retry_) {
+ retries < cfg_.max_takeover_retry) {
++retries;
TRACE("Takeover request still present");
std::this_thread::sleep_for(kSleepInterval);
@@ -451,7 +403,7 @@ SaAisErrorT Consensus::CreateTakeoverRequest(const
std::string& current_owner,
rc = SA_AIS_ERR_FAILED_OPERATION;
// wait up to max_takeover_retry seconds for request to be answered
retries = 0;
- while (retries < max_takeover_retry_) {
+ while (retries < cfg_.max_takeover_retry) {
std::vector<std::string> tokens;
if (ReadTakeoverRequest(tokens) == SA_AIS_OK) {
const std::string state =
@@ -513,7 +465,7 @@ SaAisErrorT Consensus::WriteTakeoverResult(
// previous value must match
rc =
KeyValue::Set(kTakeoverRequestKeyname, takeover_result,
- takeover_request, takeover_valid_time_);
+ takeover_request, cfg_.takeover_valid_time);
return rc;
}
@@ -578,7 +530,7 @@ Consensus::TakeoverState Consensus::HandleTakeoverRequest(
const std::string& request) {
TRACE_ENTER();
- if (use_consensus_ == false) {
+ if (cfg_.use_consensus == false) {
return TakeoverState::UNDEFINED;
}
@@ -632,7 +584,7 @@ Consensus::TakeoverState Consensus::HandleTakeoverRequest(
return TakeoverState::UNDEFINED;
}
- if (prioritise_partition_size_ == true) {
+ if (cfg_.prioritise_partition_size == true) {
if (proposed_cluster_size > cluster_size) {
result = TakeoverState::ACCEPTED;
} else {
diff --git a/src/osaf/consensus/consensus.h b/src/osaf/consensus/consensus.h
index 1aba56157..d05d57780 100644
--- a/src/osaf/consensus/consensus.h
+++ b/src/osaf/consensus/consensus.h
@@ -20,6 +20,7 @@
#include <vector>
#include "base/macros.h"
#include "osaf/consensus/key_value.h"
+#include "osaf/consensus/consensus_env.h"
#include "saAis.h"
class Consensus {
@@ -98,18 +99,9 @@ class Consensus {
const std::string& request);
private:
- bool use_consensus_{false};
- bool use_remote_fencing_{false};
- bool prioritise_partition_size_{true};
- uint32_t prioritise_partition_size_mds_wait_time_{4};
- bool relaxed_node_promotion_{false};
- uint32_t takeover_valid_time_{20};
- uint32_t max_takeover_retry_{0};
- std::string config_file_{};
- std::string plugin_path_{};
+ ConsensusCfg cfg_;
const std::string kTestKeyname = "opensaf_write_test";
- const std::string kFmsEnvPrefix = "FMS";
const std::chrono::milliseconds kSleepInterval =
std::chrono::milliseconds(1000); // in ms
static constexpr uint32_t kLockTimeout = 0; // lock is persistent by
default
diff --git a/src/osaf/consensus/consensus_env.cc
b/src/osaf/consensus/consensus_env.cc
new file mode 100644
index 000000000..fa4f4838f
--- /dev/null
+++ b/src/osaf/consensus/consensus_env.cc
@@ -0,0 +1,120 @@
+/* -*- OpenSAF -*-
+ *
+ * (C) Copyright 2018 Ericsson AB 2018 - All Rights Reserved.
+ *
+ * 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.
+ *
+ */
+#include "osaf/consensus/consensus_env.h"
+#include "base/getenv.h"
+#include "base/logtrace.h"
+#include "base/config_file_reader.h"
+
+ConsensusEnv& ConsensusEnv::GetInstance() {
+ TRACE_ENTER();
+ static ConsensusEnv env;
+
+ return env;
+}
+
+ConsensusCfg ConsensusEnv::GetConfiguration() {
+ TRACE_ENTER();
+ base::Lock lock(mutex_);
+
+ return cfg_;
+}
+
+bool ConsensusEnv::ReloadConfiguration() {
+ TRACE_ENTER();
+ ConfigFileReader reader;
+ ConfigFileReader::SettingsMap map;
+ base::Lock lock(mutex_);
+
+ if (cfg_.config_file.empty() == true) {
+ LOG_ER("config file not defined");
+ return false;
+ }
+ map = reader.ParseFile(cfg_.config_file);
+ for (const auto& kv : map) {
+ if (kv.first.compare(0, kFmsEnvPrefix.size(), kFmsEnvPrefix) != 0) {
+ // we only care about environment variables beginning with 'FMS'
+ continue;
+ }
+ int rc;
+ TRACE("Setting '%s' to '%s'", kv.first.c_str(), kv.second.c_str());
+ rc = setenv(kv.first.c_str(), kv.second.c_str(), 1);
+ osafassert(rc == 0);
+ }
+ LoadEnv();
+
+ return true;
+}
+
+ConsensusEnv::ConsensusEnv() {
+ TRACE_ENTER();
+
+ base::Lock lock(mutex_);
+ cfg_.use_consensus = false;
+ cfg_.use_remote_fencing = false;
+ cfg_.prioritise_partition_size = true;
+ cfg_.prioritise_partition_size_mds_wait_time = 4;
+ cfg_.relaxed_node_promotion = false;
+ cfg_.takeover_valid_time = 20;
+ cfg_.max_takeover_retry = 0;
+ cfg_.plugin_path = "";
+ cfg_.config_file = "";
+ LoadEnv();
+}
+
+ConsensusEnv::~ConsensusEnv() {
+ TRACE_ENTER();
+}
+
+void ConsensusEnv::LoadEnv() {
+ TRACE_ENTER();
+ uint32_t split_brain_enable = base::GetEnv("FMS_SPLIT_BRAIN_PREVENTION",
0);
+ cfg_.plugin_path = base::GetEnv("FMS_KEYVALUE_STORE_PLUGIN_CMD", "");
+ uint32_t use_remote_fencing = base::GetEnv("FMS_USE_REMOTE_FENCING", 0);
+ uint32_t prioritise_partition_size =
+ base::GetEnv("FMS_TAKEOVER_PRIORITISE_PARTITION_SIZE", 1);
+ uint32_t prioritise_partition_size_mds_wait_time =
+ base::GetEnv("FMS_TAKEOVER_PRIORITISE_PARTITION_SIZE_MDS_WAIT_TIME",
4);
+ uint32_t relaxed_node_promotion =
+ base::GetEnv("FMS_RELAXED_NODE_PROMOTION", 0);
+
+ cfg_.config_file = base::GetEnv("FMS_CONF_FILE", "");
+ // if not specified in fmd.conf,
+ // takeover requests are valid for 20 seconds
+ cfg_.takeover_valid_time =
+ base::GetEnv("FMS_TAKEOVER_REQUEST_VALID_TIME", 20);
+ // expiration time of takeover request is twice the max wait time
+ cfg_.max_takeover_retry = cfg_.takeover_valid_time / 2;
+
+ if (split_brain_enable == 1 && cfg_.plugin_path.empty() == false) {
+ cfg_.use_consensus = true;
+ } else {
+ cfg_.use_consensus = false;
+ }
+
+ if (use_remote_fencing == 1) {
+ cfg_.use_remote_fencing = true;
+ }
+
+ if (prioritise_partition_size == 0) {
+ cfg_.prioritise_partition_size = false;
+ }
+
+ if (cfg_.use_consensus == true && relaxed_node_promotion == 1) {
+ cfg_.relaxed_node_promotion = true;
+ }
+
+ cfg_.prioritise_partition_size_mds_wait_time =
+ prioritise_partition_size_mds_wait_time;
+}
diff --git a/src/osaf/consensus/consensus_env.h
b/src/osaf/consensus/consensus_env.h
new file mode 100644
index 000000000..df4f93a7a
--- /dev/null
+++ b/src/osaf/consensus/consensus_env.h
@@ -0,0 +1,55 @@
+/* -*- OpenSAF -*-
+ *
+ * (C) Copyright 2018 Ericsson AB 2018 - All Rights Reserved.
+ *
+ * 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.
+ *
+ */
+#ifndef OSAF_CONSENSUS_CONSENSUS_ENV_H_
+#define OSAF_CONSENSUS_CONSENSUS_ENV_H_
+
+#include <string>
+#include "base/mutex.h"
+
+typedef struct _ConsensusCfg {
+ bool use_consensus;
+ bool use_remote_fencing;
+ bool prioritise_partition_size;
+ uint32_t prioritise_partition_size_mds_wait_time;
+ bool relaxed_node_promotion;
+ uint32_t takeover_valid_time;
+ uint32_t max_takeover_retry;
+ std::string plugin_path;
+ std::string config_file;
+} ConsensusCfg;
+
+class ConsensusEnv {
+ public:
+ // Get the instance of class
+ static ConsensusEnv &GetInstance();
+ // Get a copy of configurations
+ ConsensusCfg GetConfiguration();
+ // Update the environment variables from the configuration file,
+ // and update the configurations
+ bool ReloadConfiguration();
+ virtual ~ConsensusEnv();
+
+ private:
+ base::Mutex mutex_;
+ ConsensusCfg cfg_;
+ const std::string kFmsEnvPrefix = "FMS";
+
+ // Private constructor
+ ConsensusEnv();
+ // Load configurations from the environment variables
+ void LoadEnv();
+};
+
+#endif // OSAF_CONSENSUS_CONSENSUS_ENV_H_