PGMonitor: fix bug in caculating pool avail space

Currently for pools with different rules, "ceph df" cannot report
right available space for them, respectively. For detail assisment
of the bug ,pls refer to bug report #8943

This patch fix this bug and make ceph df works correctlly.

Fixes Bug #8943

Signed-off-by: Xiaoxi Chen <xiaoxi.chen@intel.com>
This commit is contained in:
Xiaoxi Chen 2014-07-28 16:54:48 +08:00
parent 288908b331
commit 04d0526718
3 changed files with 16 additions and 7 deletions

View File

@ -821,7 +821,7 @@ int CrushWrapper::add_simple_ruleset(string name, string root_name,
return rno;
}
int CrushWrapper::get_rule_weight_map(unsigned ruleno, map<int,float> *pmap)
int CrushWrapper::get_rule_weight_osd_map(unsigned ruleno, map<int,float> *pmap)
{
if (ruleno >= crush->max_rules)
return -ENOENT;
@ -841,15 +841,22 @@ int CrushWrapper::get_rule_weight_map(unsigned ruleno, map<int,float> *pmap)
} else {
list<int> 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; j<b->size; ++j) {
float w = crush_get_bucket_item_weight(b, j);
m[b->items[j]] = w;
sum += w;
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);
}
}
}

View File

@ -646,7 +646,7 @@ public:
* @param pmap [out] map of osd to weight
* @return 0 for success, or negative error code
*/
int get_rule_weight_map(unsigned ruleno, map<int,float> *pmap);
int get_rule_weight_osd_map(unsigned ruleno, map<int,float> *pmap);
/* modifiers */
int add_rule(int len, int ruleset, int type, int minsize, int maxsize, int ruleno) {

View File

@ -1252,12 +1252,14 @@ void PGMonitor::dump_object_stat_sum(TextTable &tbl, Formatter *f,
int64_t PGMonitor::get_rule_avail(OSDMap& osdmap, int ruleno)
{
map<int,float> wm;
int r = osdmap.crush->get_rule_weight_map(ruleno, &wm);
int r = osdmap.crush->get_rule_weight_osd_map(ruleno, &wm);
if (r < 0)
return r;
if(wm.size() == 0)
return 0;
int64_t min = -1;
for (map<int,float>::iterator p = wm.begin(); p != wm.end(); ++p) {
int64_t proj = (float)(pg_map.osd_sum.kb_avail * 1024ull) /
int64_t proj = (float)(pg_map.osd_stat[p->first].kb_avail * 1024ull) /
(double)p->second;
if (min < 0 || proj < min)
min = proj;