]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mon: fix mixed-version MDSMonitor 8238/head 8239/head
authorJohn Spray <john.spray@redhat.com>
Mon, 21 Mar 2016 12:07:25 +0000 (12:07 +0000)
committerJohn Spray <john.spray@redhat.com>
Mon, 21 Mar 2016 12:55:38 +0000 (12:55 +0000)
Encode old-style until mon quorum features indicate
jewel, forbid creating multiple filesystems, and
when creating a single filesystem use the legacy fscid.

Fixes: #15223
Signed-off-by: John Spray <john.spray@redhat.com>
src/mds/FSMap.cc
src/mon/MDSMonitor.cc

index cf8c7aed30aaaea5e7665f0f6b8f6b7141fa330e..094b78e01e16b90572c9fe0a2d2a8898a29e322a 100644 (file)
@@ -213,21 +213,43 @@ void FSMap::get_health(list<pair<health_status_t,string> >& summary,
 
 void FSMap::encode(bufferlist& bl, uint64_t features) const
 {
-  ENCODE_START(6, 6, bl);
-  ::encode(epoch, bl);
-  ::encode(next_filesystem_id, bl);
-  ::encode(legacy_client_fscid, bl);
-  ::encode(compat, bl);
-  ::encode(enable_multiple, bl);
-  std::vector<Filesystem> fs_list;
-  for (auto i : filesystems) {
-    fs_list.push_back(*(i.second));
+  if (features & CEPH_FEATURE_SERVER_JEWEL) {
+    ENCODE_START(6, 6, bl);
+    ::encode(epoch, bl);
+    ::encode(next_filesystem_id, bl);
+    ::encode(legacy_client_fscid, bl);
+    ::encode(compat, bl);
+    ::encode(enable_multiple, bl);
+    std::vector<Filesystem> fs_list;
+    for (auto i : filesystems) {
+      fs_list.push_back(*(i.second));
+    }
+    ::encode(fs_list, bl);
+    ::encode(mds_roles, bl);
+    ::encode(standby_daemons, bl, features);
+    ::encode(standby_epochs, bl);
+    ENCODE_FINISH(bl);
+  } else {
+    if (filesystems.empty()) {
+      MDSMap disabled_map;
+      disabled_map.epoch = epoch;
+      disabled_map.encode(bl, features);
+    } else {
+      // MDSMonitor should never have created multiple filesystems
+      // until the quorum features indicated Jewel
+      assert(filesystems.size() == 1);
+      auto fs = filesystems.begin()->second;
+
+      // Take the MDSMap for the enabled filesystem, and populated its
+      // mds_info with the standbys to get a pre-jewel-style mon MDSMap.
+      MDSMap full_mdsmap = fs->mds_map;
+      full_mdsmap.epoch = epoch;
+      for (const auto p : standby_daemons) {
+        full_mdsmap.mds_info[p.first] = p.second;
+      }
+      full_mdsmap.encode(bl, features);
+    }
   }
-  ::encode(fs_list, bl);
-  ::encode(mds_roles, bl);
-  ::encode(standby_daemons, bl, features);
-  ::encode(standby_epochs, bl);
-  ENCODE_FINISH(bl);
 }
 
 void FSMap::decode(bufferlist::iterator& p)
index 5d943920ccff35fb633eb647bf18d4ec4f0c97da..4394b348710bb0ec3397135bc09dbfb457cb3571 100644 (file)
@@ -98,13 +98,19 @@ void MDSMonitor::create_new_fs(FSMap &fsm, const std::string &name,
   fs->mds_map.session_timeout = g_conf->mds_session_timeout;
   fs->mds_map.session_autoclose = g_conf->mds_session_autoclose;
   fs->mds_map.enabled = true;
-  fs->fscid = fsm.next_filesystem_id++;
+  if (mon->get_quorum_features() & CEPH_FEATURE_SERVER_JEWEL) {
+    fs->fscid = fsm.next_filesystem_id++;
+    // ANONYMOUS is only for upgrades from legacy mdsmaps, we should
+    // have initialized next_filesystem_id such that it's never used here.
+    assert(fs->fscid != FS_CLUSTER_ID_ANONYMOUS);
+  } else {
+    // Use anon fscid because this will get thrown away when encoding
+    // as legacy MDSMap for legacy mons.
+    assert(fsm.filesystems.empty());
+    fs->fscid = FS_CLUSTER_ID_ANONYMOUS;
+  }
   fsm.filesystems[fs->fscid] = fs;
 
-  // ANONYMOUS is only for upgrades from legacy mdsmaps, we should
-  // have initialized next_filesystem_id such that it's never used here.
-  assert(fs->fscid != FS_CLUSTER_ID_ANONYMOUS);
-
   // Created first filesystem?  Set it as the one
   // for legacy clients to use
   if (fsm.filesystems.size() == 1) {
@@ -1507,6 +1513,13 @@ class FlagSetHandler : public FileSystemCommandHandler
         ss << "Invalid boolean value '" << flag_val << "'";
         return r;
       }
+
+      bool jewel = mon->get_quorum_features() && CEPH_FEATURE_SERVER_JEWEL;
+      if (flag_bool && !jewel) {
+        ss << "Multiple-filesystems are forbidden until all mons are updated";
+        return -EINVAL;
+      }
+
       fsmap.set_enable_multiple(flag_bool);
       return 0;
     } else {