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>
(cherry picked from commit
3e4fe5bc7410cecaff86c7c216a3e63eb94f6213)
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;