From ad8c6660f4b2cd14a4265c4f01c9216c2984edcb Mon Sep 17 00:00:00 2001 From: Loic Dachary Date: Tue, 4 Feb 2014 01:31:52 +0100 Subject: [PATCH] mon: check cluster features before rule create-erasure Encapsulate the logic used when creating an erasure coded pool into the check_cluster_features helper. check_cluster_features(CEPH_FEATURE_CRUSH_V2) is required for crush rule create-erasure because it is expected that the erasure code plugin will use indep instead of firstn and expect the V2 behavior and not the legacy behavior. The CEPH_FEATURE_CRUSH_V2 is added to CEPH_FEATURE_OSD_ERASURE_CODES when an erasure coded pool is created. It is necessary because pool won't function properly if given an indep ruleset that does not implement the V2 behavior. Signed-off-by: Loic Dachary --- src/mon/OSDMonitor.cc | 68 +++++++++++++++++++++++++------------------ src/mon/OSDMonitor.h | 1 + 2 files changed, 40 insertions(+), 29 deletions(-) diff --git a/src/mon/OSDMonitor.cc b/src/mon/OSDMonitor.cc index a793e40b4a87d..1142990af2473 100644 --- a/src/mon/OSDMonitor.cc +++ b/src/mon/OSDMonitor.cc @@ -2760,6 +2760,37 @@ int OSDMonitor::get_erasure_code(const map &properties, return instance.factory(plugin->second, properties, erasure_code); } +int OSDMonitor::check_cluster_features(uint64_t features, + stringstream &ss) +{ + stringstream unsupported_ss; + int unsupported_count = 0; + if (!(mon->get_quorum_features() & features)) { + unsupported_ss << "the monitor cluster"; + ++unsupported_count; + } + + set up_osds; + osdmap.get_up_osds(up_osds); + for (set::iterator it = up_osds.begin(); + it != up_osds.end(); it ++) { + const osd_xinfo_t &xi = osdmap.get_xinfo(*it); + if (!(xi.features & features)) { + if (unsupported_count > 0) + unsupported_ss << ", "; + unsupported_ss << "osd." << *it; + unsupported_count ++; + } + } + + if (unsupported_count > 0) { + ss << "features " << features << " unsupported by: " + << unsupported_ss.str(); + return -ENOTSUP; + } else { + return 0; + } +} int OSDMonitor::prepare_pool_properties(const unsigned pool_type, const vector &properties, @@ -3646,6 +3677,9 @@ bool OSDMonitor::prepare_command(MMonCommand *m) return true; } else if (prefix == "osd crush rule create-erasure") { + err = check_cluster_features(CEPH_FEATURE_CRUSH_V2, ss); + if (err) + goto reply; string name, poolstr; cmd_getval(g_ceph_context, cmdmap, "name", name); vector properties; @@ -4154,35 +4188,11 @@ done: if (pool_type_str == "replicated") { pool_type = pg_pool_t::TYPE_REPLICATED; } else if (pool_type_str == "erasure") { - - // make sure all the daemons support erasure coding - stringstream ec_unsupported_ss; - int ec_unsupported_count = 0; - if (!(mon->get_quorum_features() & CEPH_FEATURE_OSD_ERASURE_CODES)) { - ec_unsupported_ss << "the monitor cluster"; - ++ec_unsupported_count; - } - - set up_osds; - osdmap.get_up_osds(up_osds); - for (set::iterator it = up_osds.begin(); - it != up_osds.end(); it ++) { - const osd_xinfo_t &xi = osdmap.get_xinfo(*it); - if (!(xi.features & CEPH_FEATURE_OSD_ERASURE_CODES)) { - if (ec_unsupported_count > 0) - ec_unsupported_ss << ", "; - ec_unsupported_ss << "osd." << *it; - ec_unsupported_count ++; - } - } - - if (ec_unsupported_count > 0) { - ss << "unable to create erasure pool; unsupported by: " - << ec_unsupported_ss.str(); - err = -ENOTSUP; - goto reply; - } - + err = check_cluster_features(CEPH_FEATURE_CRUSH_V2 | + CEPH_FEATURE_OSD_ERASURE_CODES, + ss); + if (err) + goto reply; pool_type = pg_pool_t::TYPE_ERASURE; } else { ss << "unknown pool type '" << pool_type_str << "'"; diff --git a/src/mon/OSDMonitor.h b/src/mon/OSDMonitor.h index a490d37e5c5a3..e2eadc62a489a 100644 --- a/src/mon/OSDMonitor.h +++ b/src/mon/OSDMonitor.h @@ -182,6 +182,7 @@ private: void encode_trim_extra(MonitorDBStore::Transaction *tx, version_t first); void update_msgr_features(); + int check_cluster_features(uint64_t features, stringstream &ss); void share_map_with_random_osd(); -- 2.39.5