]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
crush: add rule/set checks, conversion helpers
authorSage Weil <sage@redhat.com>
Tue, 28 Feb 2017 04:20:26 +0000 (22:20 -0600)
committerSage Weil <sage@redhat.com>
Mon, 19 Jun 2017 23:08:09 +0000 (19:08 -0400)
Add chekcs to see whether the CRUSH map has legacy ruleset != rule id
or (worse yet) multiple rules sharing the same ruleset.

Add a method to convert the former case, and error out on the latter.

Signed-off-by: Sage Weil <sage@redhat.com>
src/crush/CrushWrapper.cc
src/crush/CrushWrapper.h

index 0def97e1b37f4dc1f1445f27841c1d2152f7908c..c94fc6b97d6ce49d31c15a341eb250b4d1086938 100644 (file)
 
 #define dout_subsys ceph_subsys_crush
 
+bool CrushWrapper::has_legacy_rulesets() const
+{
+  for (unsigned i=0; i<crush->max_rules; i++) {
+    crush_rule *r = crush->rules[i];
+    if (r &&
+       r->mask.ruleset != i) {
+      return true;
+    }
+  }
+  return false;
+}
+
+int CrushWrapper::renumber_rules_by_ruleset()
+{
+  int max_ruleset = 0;
+  for (unsigned i=0; i<crush->max_rules; i++) {
+    crush_rule *r = crush->rules[i];
+    if (r && r->mask.ruleset >= max_ruleset) {
+      max_ruleset = r->mask.ruleset + 1;
+    }
+  }
+  struct crush_rule **newrules =
+    (crush_rule**)calloc(1, max_ruleset * sizeof(crush_rule*));
+  for (unsigned i=0; i<crush->max_rules; i++) {
+    crush_rule *r = crush->rules[i];
+    if (!r)
+      continue;
+    if (newrules[r->mask.ruleset]) {
+      // collision, we can't do it.
+      free(newrules);
+      return -EINVAL;
+    }
+    newrules[r->mask.ruleset] = r;
+  }
+
+  // success, swap!
+  free(crush->rules);
+  crush->rules = newrules;
+  crush->max_rules = max_ruleset;
+  return 0;
+}
+
+bool CrushWrapper::has_multirule_rulesets() const
+{
+  for (unsigned i=0; i<crush->max_rules; i++) {
+    crush_rule *r = crush->rules[i];
+    if (!r)
+      continue;
+    for (unsigned j=i+1; j<crush->max_rules; j++) {
+      crush_rule *s = crush->rules[j];
+      if (!s)
+       continue;
+      if (r->mask.ruleset == s->mask.ruleset)
+       return true;
+    }
+  }
+  return false;
+}
+
 bool CrushWrapper::has_v2_rules() const
 {
   for (unsigned i=0; i<crush->max_rules; i++) {
index b4a3bc19ca72c3c598acc435b2301047f6ac49fc..f2c47a9907475847dbc4cc1df4a0c3253e2f3926 100644 (file)
@@ -105,6 +105,15 @@ public:
     set_tunables_default();
   }
 
+  /// true if any rule has a ruleset != the rule id
+  bool has_legacy_rulesets() const;
+
+  /// fix rules whose ruleid != ruleset
+  int renumber_rules_by_ruleset();
+
+  /// true if any ruleset has more than 1 rule
+  bool has_multirule_rulesets() const;
+
   // tunables
   void set_tunables_argonaut() {
     crush->choose_local_tries = 2;