]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crush: when take place the crush map should consider the rule is in used
authorsongbaisen <song.baisen@zte.com.cn>
Thu, 31 Mar 2016 03:39:44 +0000 (11:39 +0800)
committerNathan Cutler <ncutler@suse.com>
Thu, 31 Aug 2017 20:14:33 +0000 (22:14 +0200)
Signed-off-by: song baisen song.baisen@zte.com.cn
(cherry picked from commit 09bf6f2858d09c8c314a8c242a9c70d2834718dc)

src/mon/OSDMonitor.cc
src/test/mon/osd-crush.sh

index c5f798f2084944f8016a2f94ca891d02498a11ec..cce35c58fcb7189739c01829024b0857a399b2ad 100644 (file)
@@ -5514,8 +5514,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;
@@ -5535,6 +5535,21 @@ bool OSDMonitor::prepare_command_impl(MonOpRequestRef op,
       err = -EINVAL;
       goto reply;
     }
+    
+    if (prefix == "osd setcrushmap") {
+      const map<int64_t,pg_pool_t> &osdmap_pools = osdmap.get_pools();
+      map<int64_t,pg_pool_t>::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;
index 787fefb5da59bcab1f2f617e79449272eb515ffd..7323e352ac6fd270f05d7a7687eb0fd5cd2eae81 100755 (executable)
@@ -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