From: Douglas Fuller Date: Mon, 17 Jul 2017 21:17:48 +0000 (-0400) Subject: mon/PGMap stats: Support new, filtered MStatfs X-Git-Tag: v12.1.3~24^2~6 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=4aef4eab99c63d6ed84968e7ac6861ca081e737c;p=ceph.git mon/PGMap stats: Support new, filtered MStatfs MStatfs now includes an optional data pool element for filesystems with a single data pool, support this element and return data for a single data pool if requested. Signed-off-by: Douglas Fuller --- diff --git a/src/mon/MgrStatMonitor.cc b/src/mon/MgrStatMonitor.cc index 6a0606a4be9f..3ea5f30032a8 100644 --- a/src/mon/MgrStatMonitor.cc +++ b/src/mon/MgrStatMonitor.cc @@ -17,7 +17,7 @@ class MgrPGStatService : public MonPGStatService { public: MgrPGStatService(PGMapDigest& d) : digest(d) {} - const pool_stat_t* get_pool_stat(int poolid) const override { + const pool_stat_t* get_pool_stat(int64_t poolid) const override { auto i = digest.pg_pool_sum.find(poolid); if (i != digest.pg_pool_sum.end()) { return &i->second; @@ -25,8 +25,9 @@ public: return nullptr; } - ceph_statfs get_statfs() const override { - return digest.get_statfs(); + ceph_statfs get_statfs(OSDMap& osdmap, + boost::optional data_pool) const override { + return digest.get_statfs(osdmap, data_pool); } void print_summary(Formatter *f, ostream *out) const override { @@ -295,6 +296,7 @@ bool MgrStatMonitor::preprocess_statfs(MonOpRequestRef op) op->mark_pgmon_event(__func__); auto statfs = static_cast(op->get_req()); auto session = statfs->get_session(); + if (!session) return true; if (!session->is_capable("pg", MON_CAP_R)) { @@ -316,7 +318,8 @@ bool MgrStatMonitor::preprocess_statfs(MonOpRequestRef op) ver = mon->pgmon()->get_last_committed(); } auto reply = new MStatfsReply(statfs->fsid, statfs->get_tid(), ver); - reply->h.st = mon->pgservice->get_statfs(); + reply->h.st = mon->pgservice->get_statfs(mon->osdmon()->osdmap, + statfs->data_pool); mon->send_reply(op, reply); return true; } diff --git a/src/mon/PGMap.cc b/src/mon/PGMap.cc index c0ead08097ca..8e060935e585 100644 --- a/src/mon/PGMap.cc +++ b/src/mon/PGMap.cc @@ -614,6 +614,68 @@ void PGMapDigest::pool_cache_io_rate_summary(Formatter *f, ostream *out, cache_io_rate_summary(f, out, p->second.first, ts->second); } +static float pool_raw_used_rate(const OSDMap &osd_map, int64_t poolid) +{ + const pg_pool_t *pool = osd_map.get_pg_pool(poolid); + + switch (pool->get_type()) { + case pg_pool_t::TYPE_REPLICATED: + return pool->get_size(); + break; + case pg_pool_t::TYPE_ERASURE: + { + auto& ecp = + osd_map.get_erasure_code_profile(pool->erasure_code_profile); + auto pm = ecp.find("m"); + auto 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()); + int mk = m + k; + assert(mk != 0); + assert(k != 0); + return (float)mk / k; + } else { + return 0.0; + } + } + break; + default: + assert(0 == "unrecognized pool type"); + } +} + +ceph_statfs PGMapDigest::get_statfs(OSDMap &osdmap, + boost::optional data_pool) const +{ + ceph_statfs statfs; + bool filter = false; + object_stat_sum_t sum; + + if (data_pool) { + auto i = pg_pool_sum.find(*data_pool); + if (i != pg_pool_sum.end()) { + sum = i->second.stats.sum; + filter = true; + } + } + + if (filter) { + statfs.kb_used = (sum.num_bytes >> 10); + statfs.kb_avail = get_pool_free_space(osdmap, *data_pool) >> 10; + statfs.num_objects = sum.num_objects; + statfs.kb = statfs.kb_used + statfs.kb_avail; + } else { + // these are in KB. + statfs.kb = osd_sum.kb; + statfs.kb_used = osd_sum.kb_used; + statfs.kb_avail = osd_sum.kb_avail; + statfs.num_objects = pg_sum.stats.sum.num_objects; + } + + return statfs; +} + void PGMapDigest::dump_pool_stats_full( const OSDMap &osd_map, stringstream *ss, @@ -668,33 +730,8 @@ void PGMapDigest::dump_pool_stats_full( } else { avail = avail_by_rule[ruleno]; } - switch (pool->get_type()) { - case pg_pool_t::TYPE_REPLICATED: - avail /= pool->get_size(); - raw_used_rate = pool->get_size(); - break; - case pg_pool_t::TYPE_ERASURE: - { - auto& ecp = - osd_map.get_erasure_code_profile(pool->erasure_code_profile); - auto pm = ecp.find("m"); - auto 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()); - int mk = m + k; - assert(mk != 0); - avail = avail * k / mk; - assert(k != 0); - raw_used_rate = (float)mk / k; - } else { - raw_used_rate = 0.0; - } - } - break; - default: - assert(0 == "unrecognized pool type"); - } + + raw_used_rate = ::pool_raw_used_rate(osd_map, pool_id); if (f) { f->open_object_section("pool"); @@ -824,6 +861,21 @@ void PGMapDigest::dump_object_stat_sum( } } +int64_t PGMapDigest::get_pool_free_space(const OSDMap &osd_map, + int64_t poolid) const +{ + const pg_pool_t *pool = osd_map.get_pg_pool(poolid); + int ruleno = osd_map.crush->find_rule(pool->get_crush_rule(), + pool->get_type(), + pool->get_size()); + int64_t avail; + avail = get_rule_avail(ruleno); + if (avail < 0) + avail = 0; + + return avail / ::pool_raw_used_rate(osd_map, poolid); +} + int64_t PGMap::get_rule_avail(const OSDMap& osdmap, int ruleno) const { map wm; diff --git a/src/mon/PGMap.h b/src/mon/PGMap.h index 3e81c7e05fa6..3432f796633c 100644 --- a/src/mon/PGMap.h +++ b/src/mon/PGMap.h @@ -147,6 +147,12 @@ public: void pool_cache_io_rate_summary(Formatter *f, ostream *out, uint64_t poolid) const; + /** + * Return the number of additional bytes that can be stored in this + * pool before the first OSD fills up, accounting for PG overhead. + */ + int64_t get_pool_free_space(const OSDMap &osd_map, int64_t poolid) const; + virtual void dump_pool_stats_full(const OSDMap &osd_map, stringstream *ss, Formatter *f, bool verbose) const; void dump_fs_stats(stringstream *ss, Formatter *f, bool verbose) const; @@ -171,15 +177,8 @@ public: return p->second.primary; } - ceph_statfs get_statfs() const { - ceph_statfs statfs; - // these are in KB. - statfs.kb = osd_sum.kb; - statfs.kb_used = osd_sum.kb_used; - statfs.kb_avail = osd_sum.kb_avail; - statfs.num_objects = pg_sum.stats.sum.num_objects; - return statfs; - } + ceph_statfs get_statfs(OSDMap &osdmap, + boost::optional data_pool) const; int64_t get_rule_avail(int ruleno) const { auto i = avail_space_by_rule.find(ruleno); @@ -597,7 +596,7 @@ public: bool is_readable() const override { return true; } - const pool_stat_t* get_pool_stat(int poolid) const override { + const pool_stat_t* get_pool_stat(int64_t poolid) const override { auto i = pgmap.pg_pool_sum.find(poolid); if (i != pgmap.pg_pool_sum.end()) { return &i->second; @@ -639,7 +638,8 @@ public: size_t get_num_pg_by_osd(int osd) const override { return pgmap.get_num_pg_by_osd(osd); } - ceph_statfs get_statfs() const override { + ceph_statfs get_statfs(OSDMap& osd_map, + boost::optional data_pool) const override { ceph_statfs statfs; statfs.kb = pgmap.osd_sum.kb; statfs.kb_used = pgmap.osd_sum.kb_used; diff --git a/src/mon/PGStatService.h b/src/mon/PGStatService.h index 7c8cb004bfa1..1354ed3d4cbb 100644 --- a/src/mon/PGStatService.h +++ b/src/mon/PGStatService.h @@ -37,7 +37,7 @@ public: * post-luminous, but not when we are redirecting to the PGMonitor */ virtual bool is_readable() const { return true; } - virtual const pool_stat_t* get_pool_stat(int poolid) const = 0; + virtual const pool_stat_t* get_pool_stat(int64_t poolid) const = 0; virtual const osd_stat_t& get_osd_sum() const { ceph_abort(); } @@ -73,7 +73,8 @@ public: virtual size_t get_num_pg_by_osd(int osd) const { ceph_abort(); } - virtual ceph_statfs get_statfs() const = 0; + virtual ceph_statfs get_statfs(OSDMap &osd_map, + boost::optional data_pool) const = 0; virtual void print_summary(Formatter *f, ostream *out) const = 0; virtual void dump_info(Formatter *f) const = 0; virtual void dump_fs_stats(stringstream *ss, Formatter *f, bool verbose) const = 0;