From 8b7c3199956227bdf051d995c00a331c8ccdf5cb Mon Sep 17 00:00:00 2001 From: xie xingguo Date: Thu, 17 Aug 2017 14:45:13 +0800 Subject: [PATCH] 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) --- src/crush/CrushCompiler.cc | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) 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; -- 2.47.3