From: songbaisen Date: Thu, 31 Mar 2016 03:39:44 +0000 (+0800) Subject: crush: when take place the crush map should consider the rule is in used X-Git-Tag: v11.0.0~852^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=09bf6f2858d09c8c314a8c242a9c70d2834718dc;p=ceph.git crush: when take place the crush map should consider the rule is in used Signed-off-by: song baisen song.baisen@zte.com.cn --- diff --git a/src/mon/OSDMonitor.cc b/src/mon/OSDMonitor.cc index 5908ca4c6a83..706b5749ed17 100644 --- a/src/mon/OSDMonitor.cc +++ b/src/mon/OSDMonitor.cc @@ -5289,8 +5289,8 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op, // This should be used as a general guideline for most commands handled // in this function. Adapt as you see fit, but please bear in mind that // this is the expected behavior. - - + + if (prefix == "osd setcrushmap" || (prefix == "osd crush set" && !osdid_present)) { dout(10) << "prepare_command setting new crush map" << dendl; @@ -5310,6 +5310,21 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op, err = -EINVAL; goto reply; } + + if (prefix == "osd setcrushmap") { + const map &osdmap_pools = osdmap.get_pools(); + map::const_iterator pit; + for (pit = osdmap_pools.begin(); pit != osdmap_pools.end(); ++pit) { + const int64_t pool_id = pit->first; + const pg_pool_t &pool = pit->second; + int ruleno = pool.get_crush_ruleset(); + if (!crush.rule_exists(ruleno)) { + ss << " the crush rule no "<< ruleno << " for pool id " << pool_id << " is in use"; + err = -EINVAL; + goto reply; + } + } + } // sanity check: test some inputs to make sure this map isn't totally broken dout(10) << " testing map" << dendl; diff --git a/src/test/mon/osd-crush.sh b/src/test/mon/osd-crush.sh index 4dbbd0442d91..5fc69b6fe52d 100755 --- a/src/test/mon/osd-crush.sh +++ b/src/test/mon/osd-crush.sh @@ -258,8 +258,17 @@ function TEST_crush_repair_faulty_crushmap() { local crushtool_path_old=`ceph-conf --show-config-value crushtool` ceph tell mon.\* injectargs --crushtool "true" + + + #import empty crushmap should failture.because the default pool rbd use the rule + ceph osd setcrushmap -i $empty_map.map 2>&1|grep "Error EINVAL: the crush rule no"|| return 1 + #remove the default pool rbd + ceph osd pool delete rbd rbd --yes-i-really-really-mean-it || return 1 + + #now it can be successful to set the empty crush map ceph osd setcrushmap -i $empty_map.map || return 1 + # should be an empty crush map without any buckets ! test $(ceph osd crush dump --format=xml | \ $XMLSTARLET sel -t -m "//buckets/bucket" -v .) || return 1