From: Sage Weil Date: Tue, 28 Feb 2017 04:20:26 +0000 (-0600) Subject: crush: add rule/set checks, conversion helpers X-Git-Tag: v12.1.0~27^2~13 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=7af0dd6bc88fcb497dfe7e67d5806c016d6b0727;p=ceph.git crush: add rule/set checks, conversion helpers 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 --- diff --git a/src/crush/CrushWrapper.cc b/src/crush/CrushWrapper.cc index 0def97e1b37f..c94fc6b97d6c 100644 --- a/src/crush/CrushWrapper.cc +++ b/src/crush/CrushWrapper.cc @@ -12,6 +12,65 @@ #define dout_subsys ceph_subsys_crush +bool CrushWrapper::has_legacy_rulesets() const +{ + for (unsigned i=0; imax_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; imax_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; imax_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; imax_rules; i++) { + crush_rule *r = crush->rules[i]; + if (!r) + continue; + for (unsigned j=i+1; jmax_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; imax_rules; i++) { diff --git a/src/crush/CrushWrapper.h b/src/crush/CrushWrapper.h index b4a3bc19ca72..f2c47a990747 100644 --- a/src/crush/CrushWrapper.h +++ b/src/crush/CrushWrapper.h @@ -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;