From: Sage Weil Date: Sun, 23 Jul 2017 03:50:27 +0000 (-0400) Subject: crush/CrushWrapper: refactor get_rule_weight_osd_map to work with roots too X-Git-Tag: v13.0.1~987^2~8 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=69454e0570274ff7f252e7f081965dcc9bb04459;p=ceph.git crush/CrushWrapper: refactor get_rule_weight_osd_map to work with roots too Allow us to specify a root node in the hierarchy instead of a rule. This way we can use it in conjunction with find_takes(). Signed-off-by: Sage Weil --- diff --git a/src/crush/CrushWrapper.cc b/src/crush/CrushWrapper.cc index e1b0723a1176..a84fc6bc1c23 100644 --- a/src/crush/CrushWrapper.cc +++ b/src/crush/CrushWrapper.cc @@ -1625,7 +1625,56 @@ int CrushWrapper::add_simple_rule( rule_type, -1, err); } -int CrushWrapper::get_rule_weight_osd_map(unsigned ruleno, map *pmap) +float CrushWrapper::_get_take_weight_osd_map(int root, + map *pmap) const +{ + float sum = 0.0; + list q; + q.push_back(root); + //breadth first iterate the OSD tree + 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) { + int item_id = b->items[j]; + if (item_id >= 0) { //it's an OSD + float w = crush_get_bucket_item_weight(b, j); + (*pmap)[item_id] = w; + sum += w; + } else { //not an OSD, expand the child later + q.push_back(item_id); + } + } + } + return sum; +} + +void CrushWrapper::_normalize_weight_map(float sum, + const map& m, + map *pmap) const +{ + for (auto& p : m) { + map::iterator q = pmap->find(p.first); + if (q == pmap->end()) { + (*pmap)[p.first] = p.second / sum; + } else { + q->second += p.second / sum; + } + } +} + +int CrushWrapper::get_take_weight_osd_map(int root, map *pmap) const +{ + map m; + float sum = _get_take_weight_osd_map(root, &m); + _normalize_weight_map(sum, m, pmap); + return 0; +} + +int CrushWrapper::get_rule_weight_osd_map(unsigned ruleno, + map *pmap) const { if (ruleno >= crush->max_rules) return -ENOENT; @@ -1648,35 +1697,10 @@ int CrushWrapper::get_rule_weight_osd_map(unsigned ruleno, map *pmap) m[n] = 1.0; sum = 1.0; } else { - list q; - q.push_back(n); - //breadth first iterate the OSD tree - 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) { - int item_id = b->items[j]; - if (item_id >= 0) { //it's an OSD - float w = crush_get_bucket_item_weight(b, j); - m[item_id] = w; - sum += w; - } else { //not an OSD, expand the child later - q.push_back(item_id); - } - } - } - } - } - 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; + sum += _get_take_weight_osd_map(n, &m); } } + _normalize_weight_map(sum, m, pmap); } return 0; diff --git a/src/crush/CrushWrapper.h b/src/crush/CrushWrapper.h index cefcd8fee17f..6d290dc0409b 100644 --- a/src/crush/CrushWrapper.h +++ b/src/crush/CrushWrapper.h @@ -1017,6 +1017,12 @@ public: return s->arg2; } +private: + float _get_take_weight_osd_map(int root, map *pmap) const; + void _normalize_weight_map(float sum, const map& m, + map *pmap) const; + +public: /** * calculate a map of osds to weights for a given rule * @@ -1027,7 +1033,19 @@ public: * @param pmap [out] map of osd to weight * @return 0 for success, or negative error code */ - int get_rule_weight_osd_map(unsigned ruleno, map *pmap); + int get_rule_weight_osd_map(unsigned ruleno, map *pmap) const; + + /** + * calculate a map of osds to weights for a given starting root + * + * Generate a map of which OSDs get how much relative weight for a + * given starting root + * + * @param root node + * @param pmap [out] map of osd to weight + * @return 0 for success, or negative error code + */ + int get_take_weight_osd_map(int root, map *pmap) const; /* modifiers */