]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mon/ConfigMonitor: make config changes via KVMonitor's pending set 39788/head
authorSage Weil <sage@newdream.net>
Fri, 26 Feb 2021 16:42:52 +0000 (11:42 -0500)
committerSage Weil <sage@newdream.net>
Tue, 2 Mar 2021 17:09:01 +0000 (11:09 -0600)
We need to ensure that changes we make to the kv store (config/...)
are proposed via KVMonitor so that they are properly versioned there
and shared with subscribers (notably, the mgr).

Fixes: bb7ebc41532aeb23cff2241ab07b3f01c2f57ddd
Signed-off-by: Sage Weil <sage@newdream.net>
(cherry picked from commit dab72abd0ae8a3038f73dbe0983b2eaef3937ef6)

src/mon/ConfigMonitor.cc
src/mon/ConfigMonitor.h
src/mon/KVMonitor.h

index d305aa4a24295e1dc965d0da2cb5c4e4aaf254af..7f0ee21e67155f723c6f28f479581c10897d636e 100644 (file)
@@ -96,7 +96,14 @@ void ConfigMonitor::encode_pending(MonitorDBStore::TransactionRef t)
 {
   dout(10) << " " << (version+1) << dendl;
   put_last_committed(t, version+1);
+  // NOTE: caller should have done encode_pending_to_kvmon() and
+  // kvmon->propose_pending() to commit the actual config changes.
+}
 
+void ConfigMonitor::encode_pending_to_kvmon()
+{
+  // we need to pass our data through KVMonitor so that it is properly
+  // versioned and shared with subscribers.
   for (auto& [key, value] : pending_cleanup) {
     if (pending.count(key) == 0) {
       derr << __func__ << " repair: adjusting config key '" << key << "'"
@@ -113,7 +120,7 @@ void ConfigMonitor::encode_pending(MonitorDBStore::TransactionRef t)
     bufferlist metabl;
     ::encode(ceph_clock_now(), metabl);
     ::encode(pending_description, metabl);
-    t->put(KV_PREFIX, history, metabl);
+    mon.kvmon()->enqueue_set(history, metabl);
   }
   for (auto& p : pending) {
     string key = KEY_PREFIX + p.first;
@@ -122,17 +129,17 @@ void ConfigMonitor::encode_pending(MonitorDBStore::TransactionRef t)
       if (p.second && *p.second == q->second) {
        continue;
       }
-      t->put(KV_PREFIX, history + "-" + p.first, q->second);
+      mon.kvmon()->enqueue_set(history + "-" + p.first, q->second);
     } else if (!p.second) {
       continue;
     }
     if (p.second) {
       dout(20) << __func__ << " set " << key << dendl;
-      t->put(KV_PREFIX, key, *p.second);
-      t->put(KV_PREFIX, history + "+" + p.first, *p.second);
-    } else {
+      mon.kvmon()->enqueue_set(key, *p.second);
+      mon.kvmon()->enqueue_set(history + "+" + p.first, *p.second);
+   } else {
       dout(20) << __func__ << " rm " << key << dendl;
-      t->erase(KV_PREFIX, key);
+      mon.kvmon()->enqueue_rm(key);
     }
   }
 }
@@ -513,6 +520,13 @@ bool ConfigMonitor::prepare_command(MonOpRequestRef op)
   std::stringstream ss;
   int err = -EINVAL;
 
+  // make sure kv is writeable.
+  if (!mon.kvmon()->is_writeable()) {
+    dout(10) << __func__ << " waiting for kv mon to be writeable" << dendl;
+    mon.kvmon()->wait_for_writeable(op, new C_RetryMessage(this, op));
+    return false;
+  }
+
   cmdmap_t cmdmap;
   if (!cmdmap_from_json(m->cmd, &cmdmap, ss)) {
     string rs = ss.str();
@@ -724,7 +738,12 @@ update:
     err = 0;
     goto reply;
   }
-  force_immediate_propose();  // faster response
+  // immediately propose *with* KV mon
+  encode_pending_to_kvmon();
+  paxos.plug();
+  mon.kvmon()->propose_pending();
+  paxos.unplug();
+  force_immediate_propose();
   wait_for_finished_proposal(
     op,
     new Monitor::C_Command(
@@ -743,7 +762,11 @@ void ConfigMonitor::tick()
   if (!pending_cleanup.empty()) {
     changed = true;
   }
-  if (changed) {
+  if (changed && mon.kvmon()->is_writeable()) {
+    paxos.plug();
+    encode_pending_to_kvmon();
+    mon.kvmon()->propose_pending();
+    paxos.unplug();
     propose_pending();
   }
 }
index 8d05dc3b46b674a8aa6612c2c9a63a656eed2fed..e6c12a3d7f012d6bfdbbd1a934753b7cc82c4f0e 100644 (file)
@@ -20,6 +20,8 @@ class ConfigMonitor : public PaxosService
 
   std::map<std::string,ceph::buffer::list> current;
 
+  void encode_pending_to_kvmon();
+
 public:
   ConfigMonitor(Monitor &m, Paxos &p, const std::string& service_name);
 
index 8c0204390f53aad5034ffef853be39581243d52d..c14c16380ee3f93d90f02b8c3cd3377bbf88907e 100644 (file)
@@ -55,4 +55,15 @@ public:
   void check_all_subs();
 
   bool maybe_send_update(Subscription *sub);
+
+
+  // used by other services to adjust kv content; note that callers MUST ensure that
+  // propose_pending() is called and a commit is forced to provide atomicity and
+  // proper subscriber notifications.
+  void enqueue_set(const std::string& key, bufferlist &v) {
+    pending[key] = v;
+  }
+  void enqueue_rm(const std::string& key) {
+    pending[key] = boost::none;
+  }
 };