From: Greg Farnum Date: Thu, 3 Jul 2014 23:30:49 +0000 (-0700) Subject: mon: check changes to the whole CRUSH map and to tunables against cluster features X-Git-Tag: v0.80.2~9 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=6d6039a5a56743c006a0d081157cb6ee9e3b7af6;p=ceph.git mon: check changes to the whole CRUSH map and to tunables against cluster features 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 (cherry picked from commit 54af8104816ccc76aad251aa47a6efc1bf879e7d) --- diff --git a/src/mon/OSDMonitor.cc b/src/mon/OSDMonitor.cc index 81d07b1e39bc..4848571187be 100644 --- a/src/mon/OSDMonitor.cc +++ b/src/mon/OSDMonitor.cc @@ -3014,6 +3014,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 &pools, const string &profile, ostream &ss) @@ -3625,6 +3646,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; @@ -4006,6 +4032,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; diff --git a/src/mon/OSDMonitor.h b/src/mon/OSDMonitor.h index 2d86be1823f6..2d4f3795f418 100644 --- a/src/mon/OSDMonitor.h +++ b/src/mon/OSDMonitor.h @@ -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();