From: xie xingguo Date: Thu, 17 Aug 2017 06:45:13 +0000 (+0800) Subject: crush: fix CrushCompiler won't compile maps with empty shadow tree X-Git-Tag: v12.2.0~17^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F17228%2Fhead;p=ceph.git crush: fix CrushCompiler won't compile maps with empty shadow tree 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 (cherry picked from commit 3e4fe5bc7410cecaff86c7c216a3e63eb94f6213) --- diff --git a/src/crush/CrushCompiler.cc b/src/crush/CrushCompiler.cc index eb4f7b7cf4a..15ef9be15d4 100644 --- a/src/crush/CrushCompiler.cc +++ b/src/crush/CrushCompiler.cc @@ -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;