From: Sage Weil Date: Wed, 28 May 2014 20:49:52 +0000 (-0700) Subject: crush: add get_rule_weight_map X-Git-Tag: v0.80.6~103^2~2^2~22 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=6164c3ef8d9ced38d878c191e4de3d84a8bda45e;p=ceph.git crush: add get_rule_weight_map Calculate a weight map of OSDs for a given rule. Signed-off-by: Sage Weil (cherry picked from commit 297f6169feecd20e121d102e1b63a505c8b3e74a) --- diff --git a/src/crush/CrushWrapper.cc b/src/crush/CrushWrapper.cc index 4ed3fa9e8223..2ff1327a740d 100644 --- a/src/crush/CrushWrapper.cc +++ b/src/crush/CrushWrapper.cc @@ -794,6 +794,52 @@ int CrushWrapper::add_simple_ruleset(string name, string root_name, return rno; } +int CrushWrapper::get_rule_weight_map(unsigned ruleno, map *pmap) +{ + if (ruleno >= crush->max_rules) + return -ENOENT; + if (crush->rules[ruleno] == NULL) + return -ENOENT; + crush_rule *rule = crush->rules[ruleno]; + + // build a weight map for each TAKE in the rule, and then merge them + for (unsigned i=0; ilen; ++i) { + map m; + float sum = 0; + if (rule->steps[i].op == CRUSH_RULE_TAKE) { + int n = rule->steps[i].arg1; + if (n >= 0) { + m[n] = 1.0; + sum = 1.0; + } else { + list q; + q.push_back(n); + while (!q.empty()) { + int bno = q.front(); + q.pop_front(); + crush_bucket *b = crush->buckets[-1-bno]; + assert(b); + for (unsigned j=0; jsize; ++j) { + float w = crush_get_bucket_item_weight(b, j); + m[b->items[j]] = w; + sum += w; + } + } + } + } + for (map::iterator p = m.begin(); p != m.end(); ++p) { + map::iterator q = pmap->find(p->first); + if (q == pmap->end()) { + (*pmap)[p->first] = p->second / sum; + } else { + q->second += p->second / sum; + } + } + } + + return 0; +} + int CrushWrapper::remove_rule(int ruleno) { if (ruleno >= (int)crush->max_rules) diff --git a/src/crush/CrushWrapper.h b/src/crush/CrushWrapper.h index 282cbebaf9a2..35bd93093b19 100644 --- a/src/crush/CrushWrapper.h +++ b/src/crush/CrushWrapper.h @@ -631,6 +631,18 @@ public: return s->arg2; } + /** + * calculate a map of osds to weights for a given rule + * + * Generate a map of which OSDs get how much relative weight for a + * given rule. + * + * @param ruleno [in] rule id + * @param pmap [out] map of osd to weight + * @return 0 for success, or negative error code + */ + int get_rule_weight_map(unsigned ruleno, map *pmap); + /* modifiers */ int add_rule(int len, int ruleset, int type, int minsize, int maxsize, int ruleno) { if (!crush) return -ENOENT; diff --git a/src/test/crush/TestCrushWrapper.cc b/src/test/crush/TestCrushWrapper.cc index d70a52540f59..7d42da503024 100644 --- a/src/test/crush/TestCrushWrapper.cc +++ b/src/test/crush/TestCrushWrapper.cc @@ -538,6 +538,11 @@ TEST(CrushWrapper, dump_rules) { ss.str().find("default")); } + map wm; + c->get_rule_weight_map(0, &wm); + ASSERT_TRUE(wm.size() == 1); + ASSERT_TRUE(wm[0] == 1.0); + delete c; }