]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mon/ConfigMonitor: maintain history of all config changes
authorSage Weil <sage@redhat.com>
Mon, 5 Mar 2018 01:24:20 +0000 (19:24 -0600)
committerSage Weil <sage@redhat.com>
Thu, 8 Mar 2018 22:52:35 +0000 (16:52 -0600)
Signed-off-by: Sage Weil <sage@redhat.com>
src/mon/ConfigMonitor.cc
src/mon/ConfigMonitor.h

index 6614919662f6340affb300b42594cd374bef3c20..0ccd523c3d82ed4fd9db04738f905e352a2eff9a 100644 (file)
@@ -22,6 +22,7 @@ static ostream& _prefix(std::ostream *_dout, const Monitor *mon,
 }
 
 const string KEY_PREFIX("config/");
+const string HISTORY_PREFIX("config-history/");
 
 ConfigMonitor::ConfigMonitor(Monitor *m, Paxos *p, const string& service_name)
   : PaxosService(m, p, service_name) {
@@ -54,6 +55,7 @@ void ConfigMonitor::create_pending()
 {
   dout(10) << " " << version << dendl;
   pending.clear();
+  pending_description.clear();
 }
 
 void ConfigMonitor::encode_pending(MonitorDBStore::TransactionRef t)
@@ -63,11 +65,28 @@ void ConfigMonitor::encode_pending(MonitorDBStore::TransactionRef t)
 
   // TODO: record changed sections (osd, mds.foo, rack:bar, ...)
 
+  string history = HISTORY_PREFIX + stringify(version+1) + "/";
+  {
+    bufferlist metabl;
+    ::encode(ceph_clock_now(), metabl);
+    ::encode(pending_description, metabl);
+    t->put(CONFIG_PREFIX, history, metabl);
+  }
   for (auto& p : pending) {
     string key = KEY_PREFIX + p.first;
+    auto q = current.find(p.first);
+    if (q != current.end()) {
+      if (p.second && *p.second == q->second) {
+       continue;
+      }
+      t->put(CONFIG_PREFIX, history + "-" + p.first, q->second);
+    } else if (!p.second) {
+      continue;
+    }
     if (p.second) {
       dout(20) << __func__ << " set " << key << dendl;
       t->put(CONFIG_PREFIX, key, *p.second);
+      t->put(CONFIG_PREFIX, history + "+" + p.first, *p.second);
     } else {
       dout(20) << __func__ << " rm " << key << dendl;
       t->erase(CONFIG_PREFIX, key);
@@ -518,11 +537,14 @@ void ConfigMonitor::load_config()
   KeyValueDB::Iterator it = mon->store->get_iterator(CONFIG_PREFIX);
   it->lower_bound(KEY_PREFIX);
   config_map.clear();
+  current.clear();
   while (it->valid() &&
         it->key().compare(0, KEY_PREFIX.size(), KEY_PREFIX) == 0) {
     string key = it->key().substr(KEY_PREFIX.size());
     string value = it->value().to_str();
 
+    current[key] = it->value();
+
     auto last_slash = key.rfind('/');
     string name;
     string who;
index 33e6054c831db5181b341ceedc6a2243e1d0083c..e705534186c9edbf1cb781adf1fc53bf9662409e 100644 (file)
@@ -15,6 +15,9 @@ class ConfigMonitor : public PaxosService
   version_t version = 0;
   ConfigMap config_map;
   map<string,boost::optional<bufferlist>> pending;
+  string pending_description;
+
+  map<string,bufferlist> current;
 
 public:
   ConfigMonitor(Monitor *m, Paxos *p, const string& service_name);