]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crush: fix CrushCompiler won't compile maps with empty shadow tree
authorxie xingguo <xie.xingguo@zte.com.cn>
Thu, 17 Aug 2017 06:45:13 +0000 (14:45 +0800)
committerxie xingguo <xie.xingguo@zte.com.cn>
Thu, 17 Aug 2017 10:11:36 +0000 (18:11 +0800)
Steps to reproduce:
(1) ceph osd crush rm-device-class osd.0
(2) ceph osd crush set-device-class foo osd.0
(3) ceph osd crush rule create-replicated foo_rule default host foo
(4) ceph osd crush rm-device-class osd.0
(5) ceph osd getcrushmap -o crushmap
(6) crushtool -d crushmap -o crushmap.txt
(7) crushtool -c crushmap.txt -o crushmap
    unknown device class 'foo'

Signed-off-by: xie xingguo <xie.xingguo@zte.com.cn>
src/crush/CrushCompiler.cc

index eb4f7b7cf4a6e70144da8341918ac18abcc7a309..15ef9be15d45341be77c016db5c2232b6e9257ac 100644 (file)
@@ -587,11 +587,10 @@ int CrushCompiler::parse_bucket(iter_t const& i)
       if (verbose) err << "bucket " << name << " id " << maybe_id;
       if (sub->children.size() > 2) {
         string class_name = string_node(sub->children[3]);
-        if (!crush.class_exists(class_name)) {
-          err << " unknown device class '" << class_name << "'" << std::endl;
-          return -EINVAL;
-        }
-        int cid = crush.get_class_id(class_name);
+        // note that we do not verify class existence here,
+        // as this bucket might come from an empty shadow tree
+        // which currently has no OSDs but is still referenced by a rule!
+        int cid = crush.get_or_create_class_id(class_name);
         if (class_id.count(cid) != 0) {
           err << "duplicate device class " << class_name << " for bucket " << name << std::endl;
           return -ERANGE;