Add ReloadConfiguration() function - when called it will
read fmd.conf and look for 'export FMS_XXXXX=', and overwrite
current environment variable settings in the caller.

This allows split brain prevention parameters to be changed at
runtime without a node restart.
---
 src/osaf/consensus/consensus.cc | 67 +++++++++++++++++++++++++++++++----------
 src/osaf/consensus/consensus.h  | 20 ++++++++----
 src/osaf/consensus/key_value.cc | 41 +++++++++++++------------
 3 files changed, 86 insertions(+), 42 deletions(-)

diff --git a/src/osaf/consensus/consensus.cc b/src/osaf/consensus/consensus.cc
index 878e3a7..cf307b3 100644
--- a/src/osaf/consensus/consensus.cc
+++ b/src/osaf/consensus/consensus.cc
@@ -18,6 +18,7 @@
 #include <sstream>
 #include <thread>
 #include "base/conf.h"
+#include "base/config_file_reader.h"
 #include "base/getenv.h"
 #include "base/logtrace.h"
 #include "base/ncssysf_def.h"
@@ -234,22 +235,32 @@ std::string Consensus::CurrentActive() const {
 Consensus::Consensus() {
   TRACE_ENTER();
 
+  // needed for base::Conf::NodeName() later
+  base::Conf::InitNodeName();
+
+  ProcessEnvironmentSettings();
+}
+
+Consensus::~Consensus() {}
+
+void Consensus::ProcessEnvironmentSettings() {
   uint32_t split_brain_enable = base::GetEnv("FMS_SPLIT_BRAIN_PREVENTION", 0);
-  std::string kv_store_cmd = base::GetEnv("FMS_KEYVALUE_STORE_PLUGIN_CMD", "");
+  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 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 =
+  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;
+  max_takeover_retry_ = takeover_valid_time_ / 2;
 
-  if (split_brain_enable == 1 && kv_store_cmd.empty() == false) {
+  if (split_brain_enable == 1 && plugin_path_.empty() == false) {
     use_consensus_ = true;
   } else {
     use_consensus_ = false;
@@ -259,19 +270,43 @@ Consensus::Consensus() {
     use_remote_fencing_ = true;
   }
 
-  if (prioritise_partition_size == 1) {
-    prioritise_partition_size_ = true;
+  if (prioritise_partition_size == 0) {
+    prioritise_partition_size_ = false;
   }
 
   if (use_consensus_ == true && relaxed_node_promotion == 1) {
     relaxed_node_promotion_ = true;
   }
+}
 
-  // needed for base::Conf::NodeName() later
-  base::Conf::InitNodeName();
+bool Consensus::ReloadConfiguration() {
+  ConfigFileReader reader;
+  ConfigFileReader::SettingsMap map;
+
+  if (config_file_.empty() == true) {
+    LOG_ER("config file not defined");
+    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;
+    rc = setenv(kv.first.c_str(), kv.second.c_str(), 1);
+    osafassert(rc == 0);
+  }
+
+  ProcessEnvironmentSettings();
+
+  return true;
 }
 
-Consensus::~Consensus() {}
+std::string Consensus::PluginPath() const {
+  return plugin_path_;
+}
 
 bool Consensus::FenceNode(const std::string& node) {
   if (use_remote_fencing_ == true) {
@@ -325,7 +360,7 @@ void Consensus::CheckForExistingTakeoverRequest() {
   // or until the takeover request is gone
   rc = ReadTakeoverRequest(tokens);
   while (rc == SA_AIS_OK &&
-         retries < max_takeover_retry) {
+         retries < max_takeover_retry_) {
     ++retries;
     TRACE("Takeover request still present");
     std::this_thread::sleep_for(kSleepInterval);
@@ -355,12 +390,12 @@ SaAisErrorT Consensus::CreateTakeoverRequest(const 
std::string& current_owner,
   SaAisErrorT rc;
   uint32_t retries = 0;
   rc = KeyValue::Create(kTakeoverRequestKeyname, takeover_request,
-                        takeover_valid_time);
+                        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);
+                          takeover_valid_time_);
   }
 
   if (rc == SA_AIS_ERR_EXIST) {
@@ -373,7 +408,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 < max_takeover_retry_) {
       ++retries;
       TRACE("Takeover request still present");
       std::this_thread::sleep_for(kSleepInterval);
@@ -400,7 +435,7 @@ SaAisErrorT Consensus::CreateTakeoverRequest(const 
std::string& current_owner,
 
   // wait up to max_takeover_retry seconds for request to be answered
   retries = 0;
-  while (retries < max_takeover_retry) {
+  while (retries < max_takeover_retry_) {
     std::vector<std::string> tokens;
     if (ReadTakeoverRequest(tokens) == SA_AIS_OK) {
       const std::string state =
@@ -462,7 +497,7 @@ SaAisErrorT Consensus::WriteTakeoverResult(
   // previous value must match
   rc =
       KeyValue::Set(kTakeoverRequestKeyname, takeover_result,
-                    takeover_request, takeover_valid_time);
+                    takeover_request, takeover_valid_time_);
 
   return rc;
 }
@@ -569,7 +604,7 @@ Consensus::TakeoverState Consensus::HandleTakeoverRequest(
           .c_str(),
       0, 10);
 
-  LOG_NO("Other network size: %" PRIu64 ", our network size: %" PRIu64,
+  TRACE("Other network size: %" PRIu64 ", our network size: %" PRIu64,
          proposed_cluster_size, cluster_size);
 
   const std::string state_str =
diff --git a/src/osaf/consensus/consensus.h b/src/osaf/consensus/consensus.h
index c408a6f..eb12b2c 100644
--- a/src/osaf/consensus/consensus.h
+++ b/src/osaf/consensus/consensus.h
@@ -66,6 +66,9 @@ class Consensus {
   // of connectivity to the KV store
   bool SelfFence(const std::string& request) const;
 
+  bool ReloadConfiguration();
+  std::string PluginPath() const;
+
   Consensus();
   virtual ~Consensus();
 
@@ -92,13 +95,17 @@ class Consensus {
                                       const std::string& request);
 
  private:
-  bool use_consensus_ = false;
-  bool use_remote_fencing_ = false;
-  bool prioritise_partition_size_ = false;
-  bool relaxed_node_promotion_ = false;
-  uint32_t takeover_valid_time;
-  uint32_t max_takeover_retry;
+  bool use_consensus_{false};
+  bool use_remote_fencing_{false};
+  bool prioritise_partition_size_{true};
+  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_{};
+
   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
@@ -125,6 +132,7 @@ class Consensus {
   bool FenceNode(const std::string& node);
 
   void Split(const std::string& str, std::vector<std::string>& tokens) const;
+  void ProcessEnvironmentSettings();
 
   DELETE_COPY_AND_MOVE_OPERATORS(Consensus);
 };
diff --git a/src/osaf/consensus/key_value.cc b/src/osaf/consensus/key_value.cc
index 73a0e70..692dd3f 100644
--- a/src/osaf/consensus/key_value.cc
+++ b/src/osaf/consensus/key_value.cc
@@ -17,6 +17,7 @@
 #include "base/conf.h"
 #include "base/getenv.h"
 #include "base/logtrace.h"
+#include "osaf/consensus/consensus.h"
 
 int KeyValue::Execute(const std::string& command, std::string& output) {
   TRACE_ENTER();
@@ -45,8 +46,8 @@ int KeyValue::Execute(const std::string& command, 
std::string& output) {
 SaAisErrorT KeyValue::Get(const std::string& key, std::string& value) {
   TRACE_ENTER();
 
-  const std::string kv_store_cmd =
-      base::GetEnv("FMS_KEYVALUE_STORE_PLUGIN_CMD", "");
+  Consensus consensus_service;
+  const std::string kv_store_cmd = consensus_service.PluginPath();
   const std::string command(kv_store_cmd + " get \"" + key + "\"");
   int rc = KeyValue::Execute(command, value);
   TRACE("Read '%s'", value.c_str());
@@ -64,8 +65,8 @@ SaAisErrorT KeyValue::Set(const std::string& key, const 
std::string& value,
                           const unsigned int timeout) {
   TRACE_ENTER();
 
-  const std::string kv_store_cmd =
-      base::GetEnv("FMS_KEYVALUE_STORE_PLUGIN_CMD", "");
+  Consensus consensus_service;
+  const std::string kv_store_cmd = consensus_service.PluginPath();
   const std::string command(kv_store_cmd + " set \"" + key + "\" \"" + value +
                             "\" " + std::to_string(timeout));
   std::string output;
@@ -81,8 +82,8 @@ SaAisErrorT KeyValue::Set(const std::string& key, const 
std::string& value,
 SaAisErrorT KeyValue::Set(const std::string& key, const std::string& value,
                           const std::string& prev_value,
                           const unsigned int timeout) {
-  const std::string kv_store_cmd =
-      base::GetEnv("FMS_KEYVALUE_STORE_PLUGIN_CMD", "");
+  Consensus consensus_service;
+  const std::string kv_store_cmd = consensus_service.PluginPath();
   const std::string command(kv_store_cmd + " set_if_prev \"" + key + "\" \"" +
                             value + "\" \"" + prev_value +
                             "\" " + std::to_string(timeout));
@@ -100,8 +101,8 @@ SaAisErrorT KeyValue::Create(const std::string& key, const 
std::string& value,
                              const unsigned int timeout) {
   TRACE_ENTER();
 
-  const std::string kv_store_cmd =
-      base::GetEnv("FMS_KEYVALUE_STORE_PLUGIN_CMD", "");
+  Consensus consensus_service;
+  const std::string kv_store_cmd = consensus_service.PluginPath();
   const std::string command(kv_store_cmd + " create \"" + key + "\" \"" +
                             value + "\" " + std::to_string(timeout));
   std::string output;
@@ -121,8 +122,8 @@ SaAisErrorT KeyValue::Create(const std::string& key, const 
std::string& value,
 SaAisErrorT KeyValue::Erase(const std::string& key) {
   TRACE_ENTER();
 
-  const std::string kv_store_cmd =
-      base::GetEnv("FMS_KEYVALUE_STORE_PLUGIN_CMD", "");
+  Consensus consensus_service;
+  const std::string kv_store_cmd = consensus_service.PluginPath();
   const std::string command(kv_store_cmd + " erase \"" + key + "\"");
   std::string output;
   int rc = KeyValue::Execute(command, output);
@@ -138,8 +139,8 @@ SaAisErrorT KeyValue::Lock(const std::string& owner,
                            const unsigned int timeout) {
   TRACE_ENTER();
 
-  const std::string kv_store_cmd =
-      base::GetEnv("FMS_KEYVALUE_STORE_PLUGIN_CMD", "");
+  Consensus consensus_service;
+  const std::string kv_store_cmd = consensus_service.PluginPath();
   const std::string command(kv_store_cmd + " lock \"" + owner + "\" " +
                             std::to_string(timeout));
   std::string output;
@@ -160,8 +161,8 @@ SaAisErrorT KeyValue::Lock(const std::string& owner,
 SaAisErrorT KeyValue::Unlock(const std::string& owner) {
   TRACE_ENTER();
 
-  const std::string kv_store_cmd =
-      base::GetEnv("FMS_KEYVALUE_STORE_PLUGIN_CMD", "");
+  Consensus consensus_service;
+  const std::string kv_store_cmd = consensus_service.PluginPath();
   const std::string command(kv_store_cmd + " unlock \"" + owner + "\"");
   std::string output;
   int rc = Execute(command, output);
@@ -180,8 +181,8 @@ SaAisErrorT KeyValue::Unlock(const std::string& owner) {
 SaAisErrorT KeyValue::LockOwner(std::string& owner) {
   TRACE_ENTER();
 
-  const std::string kv_store_cmd =
-      base::GetEnv("FMS_KEYVALUE_STORE_PLUGIN_CMD", "");
+  Consensus consensus_service;
+  const std::string kv_store_cmd = consensus_service.PluginPath();
   const std::string command(kv_store_cmd + " lock_owner");
   std::string output;
   int rc = KeyValue::Execute(command, output);
@@ -207,8 +208,8 @@ void WatchKeyFunction(const std::string& key, const 
ConsensusCallback& callback,
                       const uint32_t user_defined) {
   TRACE_ENTER();
 
-  const std::string kv_store_cmd =
-      base::GetEnv("FMS_KEYVALUE_STORE_PLUGIN_CMD", "");
+  Consensus consensus_service;
+  const std::string kv_store_cmd = consensus_service.PluginPath();
   const std::string command(kv_store_cmd + " watch \"" + key + "\"");
   std::string value;
   uint32_t retries = 0;
@@ -234,8 +235,8 @@ void WatchLockFunction(const ConsensusCallback& callback,
                        const uint32_t user_defined) {
   TRACE_ENTER();
 
-  const std::string kv_store_cmd =
-      base::GetEnv("FMS_KEYVALUE_STORE_PLUGIN_CMD", "");
+  Consensus consensus_service;
+  const std::string kv_store_cmd = consensus_service.PluginPath();
   const std::string command(kv_store_cmd + " watch_lock");
   std::string value;
   uint32_t retries = 0;
-- 
2.7.4



_______________________________________________
Opensaf-devel mailing list
Opensaf-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to