]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mon: include 'max avail' in df output
authorSage Weil <sage@inktank.com>
Sun, 11 May 2014 20:36:03 +0000 (13:36 -0700)
committerSage Weil <sage@redhat.com>
Sat, 2 Aug 2014 00:44:47 +0000 (17:44 -0700)
Include an estimate of the maximum writeable space for each pool.  Note
that this value is a conservative estimate for that pool based on the
most-full OSD.  It is also potentially misleading as it is the available
space if *all* new data were written to this pool; one cannot (generally)
add up the available space for all pools.

Signed-off-by: Sage Weil <sage@inktank.com>
(cherry picked from commit 7a9652b58ea70f9a484a135bde20d872616c5947)

src/mon/PGMonitor.cc
src/mon/PGMonitor.h

index 0e87c637e30aa662921befbbef0e759809163079..078202d0cbd207a1b2015dca0a787cb7a5dd1019 100644 (file)
@@ -1215,11 +1215,13 @@ inline string percentify(const float& a) {
 
 //void PGMonitor::dump_object_stat_sum(stringstream& ss, Formatter *f,
 void PGMonitor::dump_object_stat_sum(TextTable &tbl, Formatter *f,
-    object_stat_sum_t &sum, bool verbose)
+                                    object_stat_sum_t &sum, uint64_t avail,
+                                    bool verbose)
 {
   if (f) {
     f->dump_int("kb_used", SHIFT_ROUND_UP(sum.num_bytes, 10));
     f->dump_int("bytes_used", sum.num_bytes);
+    f->dump_unsigned("max_avail", avail);
     f->dump_int("objects", sum.num_objects);
     if (verbose) {
       f->dump_int("dirty", sum.num_objects_dirty);
@@ -1232,6 +1234,7 @@ void PGMonitor::dump_object_stat_sum(TextTable &tbl, Formatter *f,
     tbl << stringify(si_t(sum.num_bytes));
     int64_t kb_used = SHIFT_ROUND_UP(sum.num_bytes, 10);
     tbl << percentify(((float)kb_used / pg_map.osd_sum.kb)*100);
+    tbl << si_t(avail);
     tbl << sum.num_objects;
     if (verbose) {
       tbl << stringify(si_t(sum.num_objects_dirty))
@@ -1241,6 +1244,22 @@ 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);
+  if (r < 0)
+    return r;
+  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) /
+      (double)p->second;
+    if (min < 0 || proj < min)
+      min = proj;
+  }
+  return min;
+}
+
 void PGMonitor::dump_pool_stats(stringstream &ss, Formatter *f, bool verbose)
 {
   TextTable tbl;
@@ -1254,6 +1273,7 @@ void PGMonitor::dump_pool_stats(stringstream &ss, Formatter *f, bool verbose)
       tbl.define_column("CATEGORY", TextTable::LEFT, TextTable::LEFT);
     tbl.define_column("USED", TextTable::LEFT, TextTable::RIGHT);
     tbl.define_column("%%USED", TextTable::LEFT, TextTable::RIGHT);
+    tbl.define_column("MAX AVAIL", TextTable::LEFT, TextTable::RIGHT);
     tbl.define_column("OBJECTS", TextTable::LEFT, TextTable::RIGHT);
     if (verbose) {
       tbl.define_column("DIRTY", TextTable::LEFT, TextTable::RIGHT);
@@ -1262,6 +1282,7 @@ void PGMonitor::dump_pool_stats(stringstream &ss, Formatter *f, bool verbose)
     }
   }
 
+  map<int,uint64_t> avail_by_rule;
   OSDMap &osdmap = mon->osdmon()->osdmap;
   for (map<int64_t,pg_pool_t>::const_iterator p = osdmap.get_pools().begin();
        p != osdmap.get_pools().end(); ++p) {
@@ -1271,6 +1292,38 @@ void PGMonitor::dump_pool_stats(stringstream &ss, Formatter *f, bool verbose)
     string pool_name = osdmap.get_pool_name(pool_id);
     pool_stat_t &stat = pg_map.pg_pool_sum[pool_id];
 
+    const pg_pool_t *pool = osdmap.get_pg_pool(pool_id);
+    int ruleno = osdmap.crush->find_rule(pool->get_crush_ruleset(),
+                                        pool->get_type(),
+                                        pool->get_size());
+    uint64_t avail;
+    if (avail_by_rule.count(ruleno) == 0) {
+      avail = get_rule_avail(osdmap, ruleno);
+      avail_by_rule[ruleno] = avail;
+    } else {
+      avail = avail_by_rule[ruleno];
+    }
+    switch (pool->get_type()) {
+    case pg_pool_t::TYPE_REPLICATED:
+      avail /= pool->get_size();
+      break;
+    case pg_pool_t::TYPE_ERASURE:
+      {
+       const map<string,string>& ecp =
+         osdmap.get_erasure_code_profile(pool->erasure_code_profile);
+       map<string,string>::const_iterator pm = ecp.find("m");
+       map<string,string>::const_iterator pk = ecp.find("k");
+       if (pm != ecp.end() && pk != ecp.end()) {
+         int k = atoi(pk->second.c_str());
+         int m = atoi(pm->second.c_str());
+         avail = avail * k / (m + k);
+       }
+      }
+      break;
+    default:
+      assert(0 == "unrecognized pool type");
+    }
+
     if (f) {
       f->open_object_section("pool");
       f->dump_string("name", pool_name);
@@ -1282,7 +1335,7 @@ void PGMonitor::dump_pool_stats(stringstream &ss, Formatter *f, bool verbose)
       if (verbose)
         tbl << "-";
     }
-    dump_object_stat_sum(tbl, f, stat.stats.sum, verbose);
+    dump_object_stat_sum(tbl, f, stat.stats.sum, avail, verbose);
     if (f)
       f->close_section(); // stats
     else
@@ -1301,7 +1354,7 @@ void PGMonitor::dump_pool_stats(stringstream &ss, Formatter *f, bool verbose)
               << ""
               << it->first;
         }
-        dump_object_stat_sum(tbl, f, it->second, verbose);
+        dump_object_stat_sum(tbl, f, it->second, avail, verbose);
         if (f)
           f->close_section(); // category name
         else
index 09dd00946ac6ce86070799adcc551846332be6ab..f0073789bb5bd14948ea4c9f5365afd121cf69ba 100644 (file)
@@ -146,7 +146,11 @@ private:
                          vector<string>& args) const;
 
   void dump_object_stat_sum(TextTable &tbl, Formatter *f,
-                            object_stat_sum_t &sum, bool verbose);
+                            object_stat_sum_t &sum,
+                           uint64_t avail,
+                           bool verbose);
+
+  int64_t get_rule_avail(OSDMap& osdmap, int ruleno);
 
 public:
   PGMonitor(Monitor *mn, Paxos *p, const string& service_name)