From: Sage Weil Date: Mon, 1 May 2017 22:29:24 +0000 (-0500) Subject: osd/OSDMap: upmap: behave when current rule does not touch all osds X-Git-Tag: v12.1.0~10^2~91^2~6 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=a9ba66c46e76b5ef8e5184a5100a37598a7e7695;p=ceph.git osd/OSDMap: upmap: behave when current rule does not touch all osds Previously we relied on identifying target osds of interest by seeing which ones were touched by at least one PG. We also assumed that their target weight was their crush weight, which might not be the case if multiple pool using different rules were in play. Address this by using the get_rule_weight_osd_map. This isn't perfect as the PGs might be different "sizes," so one should still only calculate upmap for multiple pools when the pools have "equivlanet" PGs. Signed-off-by: Sage Weil --- diff --git a/src/osd/OSDMap.cc b/src/osd/OSDMap.cc index 16f3774918a4..1f69ac706444 100644 --- a/src/osd/OSDMap.cc +++ b/src/osd/OSDMap.cc @@ -3407,15 +3407,25 @@ int OSDMap::calc_pg_upmaps( CephContext *cct, float max_deviation, int max, - const set& only_pools, + const set& only_pools_orig, OSDMap::Incremental *pending_inc) { + set only_pools; + if (only_pools_orig.empty()) { + for (auto& i : pools) { + only_pools.insert(i.first); + } + } else { + only_pools = only_pools_orig; + } OSDMap tmp; tmp.deepish_copy_from(*this); int num_changed = 0; while (true) { map> pgs_by_osd; int total_pgs = 0; + float osd_weight_total = 0; + map osd_weight; for (auto& i : pools) { if (!only_pools.empty() && !only_pools.count(i.first)) continue; @@ -3429,18 +3439,29 @@ int OSDMap::calc_pg_upmaps( } } total_pgs += i.second.get_size() * i.second.get_pg_num(); + + map pmap; + int ruleno = tmp.crush->find_rule(i.second.get_crush_ruleset(), + i.second.get_type(), + i.second.get_size()); + tmp.crush->get_rule_weight_osd_map(ruleno, &pmap); + ldout(cct,30) << __func__ << " pool " << i.first << " ruleno " << ruleno << dendl; + for (auto p : pmap) { + osd_weight[p.first] += p.second; + osd_weight_total += p.second; + } } - float osd_weight_total = 0; - map osd_weight; - for (auto& i : pgs_by_osd) { - float w = crush->get_item_weightf(i.first); - osd_weight[i.first] = w; - osd_weight_total += w; - ldout(cct, 20) << " osd." << i.first << " weight " << w - << " pgs " << i.second.size() << dendl; + for (auto& i : osd_weight) { + int pgs = 0; + auto p = pgs_by_osd.find(i.first); + if (p != pgs_by_osd.end()) + pgs = p->second.size(); + else + pgs_by_osd.emplace(i.first, set()); + ldout(cct, 20) << " osd." << i.first << " weight " << i.second + << " pgs " << pgs << dendl; } - // NOTE: we assume we touch all osds with CRUSH! float pgs_per_weight = total_pgs / osd_weight_total; ldout(cct, 10) << " osd_weight_total " << osd_weight_total << dendl; ldout(cct, 10) << " pgs_per_weight " << pgs_per_weight << dendl;