]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mon: check changes to the whole CRUSH map and to tunables against cluster features 2072/head
authorGreg Farnum <greg@inktank.com>
Thu, 3 Jul 2014 23:30:49 +0000 (16:30 -0700)
committerGreg Farnum <greg@inktank.com>
Thu, 3 Jul 2014 23:32:41 +0000 (16:32 -0700)
When we change the tunables, or set a new CRUSH map, we need to make sure it's
supported by all the monitors and OSDs currently participating in the cluster.

Fixes: #8738
Signed-off-by: Greg Farnum <greg@inktank.com>
src/mon/OSDMonitor.cc
src/mon/OSDMonitor.h

index 9f4dbabe03805f2acb22a60da73f1a755e92db91..b1c804d7da25b7a7b12435a4ee6ec288bfc96c37 100644 (file)
@@ -3035,6 +3035,27 @@ int OSDMonitor::check_cluster_features(uint64_t features,
   return 0;
 }
 
+bool OSDMonitor::validate_crush_against_features(const CrushWrapper *newcrush,
+                                                 stringstream& ss)
+{
+  OSDMap::Incremental new_pending = pending_inc;
+  ::encode(*newcrush, new_pending.crush);
+  OSDMap newmap;
+  newmap.deepish_copy_from(osdmap);
+  newmap.apply_incremental(new_pending);
+  uint64_t features = newmap.get_features(CEPH_ENTITY_TYPE_MON, NULL);
+
+  stringstream features_ss;
+
+  int r = check_cluster_features(features, features_ss);
+
+  if (!r)
+    return true;
+
+  ss << "Could not change CRUSH: " << features_ss.str();
+  return false;
+}
+
 bool OSDMonitor::erasure_code_profile_in_use(const map<int64_t, pg_pool_t> &pools,
                                             const string &profile,
                                             ostream &ss)
@@ -3649,6 +3670,11 @@ bool OSDMonitor::prepare_command_impl(MMonCommand *m,
       goto reply;
     }
 
+    if (!validate_crush_against_features(&crush, ss)) {
+      err = -EINVAL;
+      goto reply;
+    }
+
     // sanity check: test some inputs to make sure this map isn't totally broken
     dout(10) << " testing map" << dendl;
     stringstream ess;
@@ -4066,6 +4092,12 @@ bool OSDMonitor::prepare_command_impl(MMonCommand *m,
       err = -EINVAL;
       goto reply;
     }
+
+    if (!validate_crush_against_features(&newcrush, ss)) {
+      err = -EINVAL;
+      goto reply;
+    }
+
     pending_inc.crush.clear();
     newcrush.encode(pending_inc.crush);
     ss << "adjusted tunables profile to " << profile;
index 80d083e8bd70a8c6f593c00c657ea498fadbfbbe..fbce5fecd182d9c94b50fdc6dd6cd5007fa90ac2 100644 (file)
@@ -186,6 +186,15 @@ private:
 
   void update_msgr_features();
   int check_cluster_features(uint64_t features, stringstream &ss);
+  /**
+   * check if the cluster supports the features required by the
+   * given crush map. Outputs the daemons which don't support it
+   * to the stringstream.
+   *
+   * @returns true if the map is passable, false otherwise
+   */
+  bool validate_crush_against_features(const CrushWrapper *newcrush,
+                                      stringstream &ss);
 
   void share_map_with_random_osd();