]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
crush: parse "class XXX" after step take
authorLoic Dachary <ldachary@redhat.com>
Sat, 18 Feb 2017 21:20:04 +0000 (22:20 +0100)
committerLoic Dachary <ldachary@redhat.com>
Wed, 1 Mar 2017 16:24:08 +0000 (17:24 +0100)
Refs: http://tracker.ceph.com/issues/18943

Signed-off-by: Loic Dachary <ldachary@redhat.com>
src/crush/CrushCompiler.cc
src/crush/grammar.h
src/test/cli/crushtool/device-class.crush
src/test/cli/osdmaptool/crush.t

index 43d862db9e800a5beca9d822c39eb043fcbe8507..40cc9b37e55060b79d6dc0e6830785576695b6b8 100644 (file)
@@ -52,6 +52,15 @@ static void print_item_class(ostream& out, int t, CrushWrapper &crush)
     out << " class " << c;
 }
 
+static void print_class(ostream& out, int t, CrushWrapper &crush)
+{
+  const char *c = crush.get_class_name(t);
+  if (c)
+    out << " class " << c;
+  else
+    out << " # unexpected class " << t;
+}
+
 static void print_rule_name(ostream& out, int t, CrushWrapper &crush)
 {
   const char *name = crush.get_rule_name(t);
@@ -270,7 +279,19 @@ int CrushCompiler::decompile(ostream &out)
        break;
       case CRUSH_RULE_TAKE:
        out << "\tstep take ";
-       print_item_name(out, crush.get_rule_arg1(i, j), crush);
+       {
+          int step_item = crush.get_rule_arg1(i, j);
+          int original_item;
+          int c;
+          int res = crush.split_id_class(step_item, &original_item, &c);
+          if (res < 0)
+            return res;
+         if (c >= 0)
+            step_item = original_item;
+          print_item_name(out, step_item, crush);
+         if (c >= 0)
+           print_class(out, c, crush);
+       }
        out << "\n";
        break;
       case CRUSH_RULE_EMIT:
@@ -658,7 +679,35 @@ int CrushCompiler::parse_rule(iter_t const& i)
          err << "in rule '" << rname << "' item '" << item << "' not defined" << std::endl;
          return -1;
        }
-       crush.set_rule_step_take(ruleno, step++, item_id[item]);
+        int id = item_id[item];
+        int c = -1;
+        string class_name;
+        if (s->children.size() > 2) {
+          class_name = string_node(s->children[3]);
+          c = crush.get_class_id(class_name);
+          if (c < 0)
+            return c;
+          if (crush.class_bucket.count(id) == 0) {
+            err << "in rule '" << rname << "' step take " << item
+                << " has no class information" << std::endl;
+            return -EINVAL;
+          }
+          if (crush.class_bucket[id].count(c) == 0) {
+            err << "in rule '" << rname << "' step take " << item
+                << " no matching bucket for class " << class_name << std::endl;
+            return -EINVAL;
+          }
+          id = crush.class_bucket[id][c];
+        }
+        if (verbose) {
+          err << "rule " << rname << " take " << item;
+          if (c < 0)
+            err << std::endl;
+          else
+            err << " remapped to " << crush.get_item_name(id) << std::endl;
+        }
+
+       crush.set_rule_step_take(ruleno, step++, id);
       }
       break;
 
index 66c010bb45f48db02c82e6f2a6bd44a429051c0c..f6664bd2bb9d632b53551a45c20e9b3b1114d998 100644 (file)
@@ -124,7 +124,7 @@ struct crush_grammar : public grammar<crush_grammar>
       bucket = name >> name >> '{' >> !bucket_id >> bucket_alg >> *bucket_hash >> *bucket_item >> '}';
 
       // rules
-      step_take = str_p("take") >> name;
+      step_take = str_p("take") >> name >> !( str_p("class") >> name );
       step_set_choose_tries = str_p("set_choose_tries") >> posint;
       step_set_choose_local_tries = str_p("set_choose_local_tries") >> posint;
       step_set_choose_local_fallback_tries = str_p("set_choose_local_fallback_tries") >> posint;
index 2d4a69a9ecaed44d6d33e91118000b5e0ced7444..be681593835f75f135c6a46603092a23832de502 100644 (file)
@@ -51,11 +51,29 @@ root root {
 }
 
 # rules
-rule data {
+rule data-ssd {
        ruleset 1
        type replicated
        min_size 2
        max_size 2
+       step take root class ssd
+       step chooseleaf firstn 0 type rack
+       step emit
+}
+rule data-hdd {
+       ruleset 2
+       type replicated
+       min_size 2
+       max_size 2
+       step take root class hdd
+       step chooseleaf firstn 0 type rack
+       step emit
+}
+rule data {
+       ruleset 3
+       type replicated
+       min_size 2
+       max_size 2
        step take root
        step chooseleaf firstn 0 type rack
        step emit
index d2f27ef736d3b17a836148bb825d79a84aa62757..048285df551e62feca43a8cfc187e152352408e8 100644 (file)
@@ -6,5 +6,5 @@
   osdmaptool: exported crush map to oc
   $ osdmaptool --import-crush oc myosdmap
   osdmaptool: osdmap file 'myosdmap'
-  osdmaptool: imported 492 byte crush map from oc
+  osdmaptool: imported 504 byte crush map from oc
   osdmaptool: writing epoch 3 to myosdmap