]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/crush/CrushCompiler.cc
update sources to 12.2.7
[ceph.git] / ceph / src / crush / CrushCompiler.cc
index d59fdaaff5cde43737c6031fee58d1b774c2e8e0..5d8415122495311faf5dfb84aee36fb474cafc9c 100644 (file)
@@ -250,8 +250,8 @@ int CrushCompiler::decompile_choose_arg(crush_choose_arg *arg,
   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;
   }
@@ -269,7 +269,7 @@ int CrushCompiler::decompile_choose_arg_map(crush_choose_arg_map arg_map,
 {
   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)
@@ -291,8 +291,6 @@ int CrushCompiler::decompile_choose_args(const std::pair<const long unsigned int
 
 int CrushCompiler::decompile(ostream &out)
 {
-  crush.cleanup_classes();
-
   out << "# begin crush map\n";
 
   // only dump tunables if they differ from the defaults
@@ -316,10 +314,12 @@ int CrushCompiler::decompile(ostream &out)
 
   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";
@@ -589,11 +589,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;
@@ -734,7 +733,7 @@ int CrushCompiler::parse_bucket(iter_t const& i)
   }
 
   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;
@@ -743,7 +742,9 @@ int CrushCompiler::parse_bucket(iter_t const& i)
   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;
@@ -950,14 +951,14 @@ int CrushCompiler::parse_weight_set_weights(iter_t const& i, int bucket_id, crus
 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 {
@@ -1084,7 +1085,7 @@ int CrushCompiler::parse_crush(iter_t const& i)
     case crush_grammar::_crushrule:
       if (!saw_rule) {
        saw_rule = true;
-       crush.populate_classes();
+       crush.populate_classes(class_bucket);
       }
       r = parse_rule(p);
       break;
@@ -1100,7 +1101,6 @@ int CrushCompiler::parse_crush(iter_t const& i)
   }
 
   //err << "max_devices " << crush.get_max_devices() << std::endl;
-  crush.cleanup_classes();
   crush.finalize();
 
   return 0;