From 9167c8381f2c04e302b20a0b9febb60210dba1fb Mon Sep 17 00:00:00 2001 From: Kefu Chai Date: Wed, 24 Oct 2018 15:35:05 +0800 Subject: [PATCH] librados: move get_inconsistent_pgs() into RadosClient so we don't need parse the pg string and render it again for librados C API. the downside of this change is that, get_inconsistent_pgs() could be implemented using RadosClient, instead be *in* it. but before we have a place for the helper functions for these higher-level functions, RadosClient is a good place for hosting them. Signed-off-by: Kefu Chai --- src/librados/RadosClient.cc | 49 +++++++++++++++++++++ src/librados/RadosClient.h | 2 + src/librados/librados.cc | 88 ++++++------------------------------- 3 files changed, 65 insertions(+), 74 deletions(-) diff --git a/src/librados/RadosClient.cc b/src/librados/RadosClient.cc index ec7010e487e4b..ff057257b036d 100644 --- a/src/librados/RadosClient.cc +++ b/src/librados/RadosClient.cc @@ -25,6 +25,7 @@ #include "common/ceph_context.h" #include "common/config.h" #include "common/common_init.h" +#include "common/ceph_json.h" #include "common/errno.h" #include "include/buffer.h" #include "include/stringify.h" @@ -1118,3 +1119,51 @@ mon_feature_t librados::RadosClient::get_required_monitor_features() const return monclient.with_monmap([](const MonMap &monmap) { return monmap.get_required_features(); } ); } + +int librados::RadosClient::get_inconsistent_pgs(int64_t pool_id, + std::vector* pgs) +{ + vector cmd = { + "{\"prefix\": \"pg ls\"," + "\"pool\": " + std::to_string(pool_id) + "," + "\"states\": [\"inconsistent\"]," + "\"format\": \"json\"}" + }; + bufferlist inbl, outbl; + string outstring; + if (auto ret = mgr_command(cmd, inbl, &outbl, &outstring); ret) { + return ret; + } + if (!outbl.length()) { + // no pg returned + return 0; + } + JSONParser parser; + if (!parser.parse(outbl.c_str(), outbl.length())) { + return -EINVAL; + } + vector v; + if (!parser.is_array()) { + JSONObj *pgstat_obj = parser.find_obj("pg_stats"); + if (!pgstat_obj) + return 0; + auto s = pgstat_obj->get_data(); + JSONParser pg_stats; + if (!pg_stats.parse(s.c_str(), s.length())) { + return -EINVAL; + } + v = pg_stats.get_array_elements(); + } else { + v = parser.get_array_elements(); + } + for (auto i : v) { + JSONParser pg_json; + if (!pg_json.parse(i.c_str(), i.length())) { + return -EINVAL; + } + string pgid; + JSONDecoder::decode_json("pgid", pgid, &pg_json); + pgs->emplace_back(std::move(pgid)); + } + return 0; +} diff --git a/src/librados/RadosClient.h b/src/librados/RadosClient.h index 1a3fe8c29d5d9..cc0cc00293475 100644 --- a/src/librados/RadosClient.h +++ b/src/librados/RadosClient.h @@ -172,6 +172,8 @@ public: std::map&& status); mon_feature_t get_required_monitor_features() const; + + int get_inconsistent_pgs(int64_t pool_id, std::vector* pgs); }; #endif diff --git a/src/librados/librados.cc b/src/librados/librados.cc index 32627385b52d3..67eebe7643611 100644 --- a/src/librados/librados.cc +++ b/src/librados/librados.cc @@ -2696,77 +2696,21 @@ std::ostream& librados::operator<<(std::ostream& out, return out << pg.impl->pgid; } -namespace { - int decode_json(JSONObj *obj, pg_t& pg) - { - string pg_str; - JSONDecoder::decode_json("pgid", pg_str, obj); - if (pg.parse(pg_str.c_str())) { - return 0; - } else { - return -EINVAL; - } +int librados::Rados::get_inconsistent_pgs(int64_t pool_id, + std::vector* pgs) +{ + std::vector pgids; + if (auto ret = client->get_inconsistent_pgs(pool_id, &pgids); ret) { + return ret; } - - int get_inconsistent_pgs(librados::RadosClient& client, - int64_t pool_id, - std::vector* pgs) - { - vector cmd = { - "{\"prefix\": \"pg ls\"," - "\"pool\": " + std::to_string(pool_id) + "," - "\"states\": [\"inconsistent\"]," - "\"format\": \"json\"}" - }; - bufferlist inbl, outbl; - string outstring; - int ret = client.mgr_command(cmd, inbl, &outbl, &outstring); - if (ret) { - return ret; - } - if (!outbl.length()) { - // no pg returned - return ret; - } - JSONParser parser; - if (!parser.parse(outbl.c_str(), outbl.length())) { + for (const auto& pgid : pgids) { + librados::PlacementGroup pg; + if (!pg.parse(pgid.c_str())) { return -EINVAL; } - - vector v; - if (!parser.is_array()) { - JSONObj *pgstat_obj = parser.find_obj("pg_stats"); - if (NULL == pgstat_obj) - return 0; - string s = pgstat_obj->get_data(); - JSONParser pg_stats; - if (!pg_stats.parse(s.c_str(), s.length())) - return -EINVAL; - v = pg_stats.get_array_elements(); - } - else { - v = parser.get_array_elements(); - } - - for (auto i : v) { - JSONParser pg_json; - if (!pg_json.parse(i.c_str(), i.length())) { - return -EINVAL; - } - librados::PlacementGroup pg; - if (decode_json(&pg_json, pg.impl->pgid)) { - return -EINVAL; - } - pgs->emplace_back(pg); - } - return 0; + pgs->emplace_back(std::move(pg)); } -} - -int librados::Rados::get_inconsistent_pgs(int64_t pool_id, - std::vector* pgs) -{ - return ::get_inconsistent_pgs(*client, pool_id, pgs); + return 0; } int librados::Rados::get_inconsistent_objects(const PlacementGroup& pg, @@ -3378,9 +3322,8 @@ CEPH_RADOS_API int rados_inconsistent_pg_list(rados_t cluster, int64_t pool_id, { tracepoint(librados, rados_inconsistent_pg_list_enter, cluster, pool_id, len); librados::RadosClient *client = (librados::RadosClient *)cluster; - std::vector pgs; - int r = ::get_inconsistent_pgs(*client, pool_id, &pgs); - if (r < 0) { + std::vector pgs; + if (int r = client->get_inconsistent_pgs(pool_id, &pgs); r < 0) { tracepoint(librados, rados_inconsistent_pg_list_exit, r); return r; } @@ -3394,10 +3337,7 @@ CEPH_RADOS_API int rados_inconsistent_pg_list(rados_t cluster, int64_t pool_id, if (b) memset(b, 0, len); int needed = 0; - for (const auto pg : pgs) { - std::ostringstream ss; - ss << pg; - auto s = ss.str(); + for (const auto& s : pgs) { unsigned rl = s.length() + 1; if (b && len >= rl) { tracepoint(librados, rados_inconsistent_pg_list_pg, s.c_str()); -- 2.39.5