]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mon: MDSMonitor: wait for osdmon to be writable when requesting proposal 2744/head
authorJoao Eduardo Luis <joao@redhat.com>
Fri, 17 Oct 2014 18:08:20 +0000 (19:08 +0100)
committerJoao Eduardo Luis <joao@redhat.com>
Fri, 17 Oct 2014 18:08:20 +0000 (19:08 +0100)
Otherwise we may end up requesting the osdmon to propose while it is
mid-proposal.  We can't simply return EAGAIN to the user either because
then we would have to expect the user to be able to successfully race
with the whole cluster in finding a window in which 'mds fs new' command
would succeed -- which is not a realistic expectation.  Having the
command to osdmon()->wait_for_writable() guarantees that the command
will be added to a queue and that we will, eventually, tend to it.

Fixes: #9794
Signed-off-by: Joao Eduardo Luis <joao@redhat.com>
src/mon/MDSMonitor.cc
src/mon/MDSMonitor.h

index 2984cf96ecc1974aaf87ca039280b891670ce642..028b9faee3a59f08f4ff96848ff8fe3809a3a75d 100644 (file)
@@ -929,8 +929,14 @@ bool MDSMonitor::prepare_command(MMonCommand *m)
   }
 
   /* Execute filesystem add/remove, or pass through to filesystem_command */
-  r = management_command(prefix, cmdmap, ss);
-  if (r >= 0 || r != -ENOSYS)
+  r = management_command(m, prefix, cmdmap, ss);
+  if (r >= 0)
+    goto out;
+  
+  if (r == -EAGAIN) {
+    // message has been enqueued for retry; return.
+    return false;
+  } else if (r != -ENOSYS) {
     // MDSMonitor::management_command() returns -ENOSYS if it knows nothing
     // about the command passed to it, in which case we will check whether
     // MDSMonitor::filesystem_command() knows about it.  If on the other hand
@@ -1016,6 +1022,7 @@ int MDSMonitor::_check_pool(
  *         fall through and look for other types of command.
  */
 int MDSMonitor::management_command(
+    MMonCommand *m,
     std::string const &prefix,
     map<string, cmd_vartype> &cmdmap,
     std::stringstream &ss)
@@ -1134,6 +1141,14 @@ int MDSMonitor::management_command(
     // Automatically set crash_replay_interval on data pool if it
     // isn't already set.
     if (data_pool->get_crash_replay_interval() == 0) {
+      // We will be changing osdmon's state and requesting the osdmon to
+      // propose.  We thus need to make sure the osdmon is writeable before
+      // we do this, waiting if it's not.
+      if (!mon->osdmon()->is_writeable()) {
+        mon->osdmon()->wait_for_writeable(new C_RetryMessage(this, m));
+        return -EAGAIN;
+      }
+
       r = mon->osdmon()->set_crash_replay_interval(data, g_conf->osd_default_data_pool_replay_window);
       assert(r == 0);  // We just did get_pg_pool so it must exist and be settable
       request_proposal(mon->osdmon());
index 2824f08eeb8931ef71ec5ddad159ac1f02717ce8..266fb3efcc7eca706f6a96596f3b0d1321784e92 100644 (file)
@@ -102,6 +102,7 @@ class MDSMonitor : public PaxosService {
   bool preprocess_command(MMonCommand *m);
   bool prepare_command(MMonCommand *m);
   int management_command(
+      MMonCommand *m,
       std::string const &prefix,
       map<string, cmd_vartype> &cmdmap,
       std::stringstream &ss);