int r;
out << " {\n";
out << " bucket_id " << bucket_id << "\n";
- if (arg->weight_set_size > 0) {
- r = decompile_weight_set(arg->weight_set, arg->weight_set_size, out);
+ if (arg->weight_set_positions > 0) {
+ r = decompile_weight_set(arg->weight_set, arg->weight_set_positions, out);
if (r < 0)
return r;
}
{
for (__u32 i = 0; i < arg_map.size; i++) {
if ((arg_map.args[i].ids_size == 0) &&
- (arg_map.args[i].weight_set_size == 0))
+ (arg_map.args[i].weight_set_positions == 0))
continue;
int r = decompile_choose_arg(&arg_map.args[i], -1-i, out);
if (r < 0)
int CrushCompiler::decompile(ostream &out)
{
- crush.cleanup_classes();
-
out << "# begin crush map\n";
// only dump tunables if they differ from the defaults
out << "\n# devices\n";
for (int i=0; i<crush.get_max_devices(); i++) {
- out << "device " << i << " ";
- print_item_name(out, i, crush);
- print_item_class(out, i, crush);
- out << "\n";
+ const char *name = crush.get_item_name(i);
+ if (name) {
+ out << "device " << i << " " << name;
+ print_item_class(out, i, crush);
+ out << "\n";
+ }
}
out << "\n# types\n";
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;
}
for (auto &i : class_id)
- crush.class_bucket[id][i.first] = i.second;
+ class_bucket[id][i.first] = i.second;
if (verbose) err << "bucket " << name << " (" << id << ") " << size << " items and weight "
<< (float)bucketweight / (float)0x10000 << std::endl;
item_weight[id] = bucketweight;
assert(id != 0);
- int r = crush.add_bucket(id, alg, hash, type, size, &items[0], &weights[0], NULL);
+ int idout;
+ int r = crush.add_bucket(id, alg, hash, type, size,
+ &items[0], &weights[0], &idout);
if (r < 0) {
if (r == -EEXIST)
err << "Duplicate bucket id " << id << std::endl;
int CrushCompiler::parse_weight_set(iter_t const& i, int bucket_id, crush_choose_arg *arg)
{
// -3 stands for the leading "weight_set" keyword and the enclosing [ ]
- arg->weight_set_size = i->children.size() - 3;
- arg->weight_set = (crush_weight_set *)calloc(arg->weight_set_size, sizeof(crush_weight_set));
+ arg->weight_set_positions = i->children.size() - 3;
+ arg->weight_set = (crush_weight_set *)calloc(arg->weight_set_positions, sizeof(crush_weight_set));
__u32 pos = 0;
for (iter_t p = i->children.begin(); p != i->children.end(); p++) {
int r = 0;
switch((int)p->value.id().to_long()) {
case crush_grammar::_weight_set_weights:
- if (pos < arg->weight_set_size) {
+ if (pos < arg->weight_set_positions) {
r = parse_weight_set_weights(p, bucket_id, &arg->weight_set[pos]);
pos++;
} else {
case crush_grammar::_crushrule:
if (!saw_rule) {
saw_rule = true;
- crush.populate_classes();
+ crush.populate_classes(class_bucket);
}
r = parse_rule(p);
break;
}
//err << "max_devices " << crush.get_max_devices() << std::endl;
- crush.cleanup_classes();
crush.finalize();
return 0;