]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mon/MonClient: apply MON config before finishing bootstrap
authorJason Dillaman <dillaman@redhat.com>
Thu, 30 Jul 2020 17:00:22 +0000 (13:00 -0400)
committerMykola Golub <mgolub@suse.com>
Mon, 14 Jun 2021 12:14:31 +0000 (15:14 +0300)
In general, non-primitive config options cannot be updated after
the service threads have been marked as running. In librados, this
happens after the MonClient bootstrap process. However, the configs
received from the MON were applied in a separate thread which can
race with librados marking the service threads as running.

Now the received MON configs will be applied within the context of
the bootstrap function call instead of deferring to a separate
thread.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
(cherry picked from commit 313aeaa55d67089e0a2e173718899e603e51ce2e)

Conflicts:
src/mon/MonClient.cc (trivial)

src/mon/MonClient.cc
src/mon/MonClient.h

index b94b4d9a9ead41903fac03dc635c46ebf7d8cbd5..23030db686c71735e1bcf55e19b77dd024b7f7f3 100644 (file)
@@ -137,6 +137,14 @@ int MonClient::get_monmap_and_config()
     }
   });
 
+  want_bootstrap_config = true;
+  auto shutdown_config = make_scope_guard([this] {
+    std::unique_lock l(monc_lock);
+    want_bootstrap_config = false;
+    bootstrap_config.reset();
+  });
+
+  ceph::ref_t<MConfig> config;
   while (tries-- > 0) {
     r = init();
     if (r < 0) {
@@ -160,7 +168,7 @@ int MonClient::get_monmap_and_config()
        r = 0;
        break;
       }
-      while ((!got_config || monmap.get_epoch() == 0) && r == 0) {
+      while ((!bootstrap_config || monmap.get_epoch() == 0) && r == 0) {
        ldout(cct,20) << __func__ << " waiting for monmap|config" << dendl;
        auto status = map_cond.wait_for(l, ceph::make_timespan(
            cct->_conf->mon_client_hunt_interval));
@@ -168,8 +176,10 @@ int MonClient::get_monmap_and_config()
          r = -ETIMEDOUT;
        }
       }
-      if (got_config) {
+
+      if (bootstrap_config) {
        ldout(cct,10) << __func__ << " success" << dendl;
+       config = std::move(bootstrap_config);
        r = 0;
        break;
       }
@@ -179,6 +189,12 @@ int MonClient::get_monmap_and_config()
     continue;
   }
 
+  if (config) {
+    // apply the bootstrap config to ensure its applied prior to completing
+    // the bootstrap
+    cct->_conf.set_mon_vals(cct, config->config, config_cb);
+  }
+
   shutdown();
   return r;
 }
@@ -437,6 +453,15 @@ void MonClient::handle_monmap(MMonMap *m)
 void MonClient::handle_config(MConfig *m)
 {
   ldout(cct,10) << __func__ << " " << *m << dendl;
+
+  if (want_bootstrap_config) {
+    // get_monmap_and_config is waiting for config which it will apply
+    // synchronously
+    bootstrap_config = ceph::ref_t<MConfig>(m, false);
+    map_cond.notify_all();
+    return;
+  }
+
   finisher.queue(new LambdaContext([this, m](int r) {
        cct->_conf.set_mon_vals(cct, m->config, config_cb);
        if (config_notify_cb) {
@@ -444,8 +469,6 @@ void MonClient::handle_config(MConfig *m)
        }
        m->put();
       }));
-  got_config = true;
-  map_cond.notify_all();
 }
 
 // ----------------------
index 80262200b612b53459e5fd822d9d00799a3fadb4..f10b447a6e2f4b5d945cfebe5323eb5aacfa4db9 100644 (file)
@@ -290,7 +290,9 @@ private:
   bool want_monmap;
   ceph::condition_variable map_cond;
   bool passthrough_monmap = false;
-  bool got_config = false;
+
+  bool want_bootstrap_config = false;
+  ceph::ref_t<MConfig> bootstrap_config;
 
   // authenticate
   std::unique_ptr<AuthClientHandler> auth;