From a9782d57d14c0928265d399ce0f1fa1d605613ff Mon Sep 17 00:00:00 2001 From: Brad Hubbard Date: Mon, 8 Mar 2021 14:19:32 +1000 Subject: [PATCH] test/lazy-omap-stats: Various enhancements Primarily removal of boost::process call to blocking deep scrub cli command. Fixes: https://tracker.ceph.com/issues/49727 Signed-off-by: Brad Hubbard (cherry picked from commit c3e28a84b04711ea8ccde16d454e5cf963a4f01a) --- src/test/lazy-omap-stats/CMakeLists.txt | 2 +- .../lazy-omap-stats/lazy_omap_stats_test.cc | 147 ++++++++++++------ .../lazy-omap-stats/lazy_omap_stats_test.h | 14 +- 3 files changed, 112 insertions(+), 51 deletions(-) diff --git a/src/test/lazy-omap-stats/CMakeLists.txt b/src/test/lazy-omap-stats/CMakeLists.txt index 1dac35469c23..bddd074c578d 100644 --- a/src/test/lazy-omap-stats/CMakeLists.txt +++ b/src/test/lazy-omap-stats/CMakeLists.txt @@ -4,7 +4,7 @@ add_executable(ceph_test_lazy_omap_stats main.cc lazy_omap_stats_test.cc) target_link_libraries(ceph_test_lazy_omap_stats - librados Boost::system ${UNITTEST_LIBS}) + librados Boost::system ceph-common ${UNITTEST_LIBS}) install(TARGETS ceph_test_lazy_omap_stats DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/src/test/lazy-omap-stats/lazy_omap_stats_test.cc b/src/test/lazy-omap-stats/lazy_omap_stats_test.cc index 97b0208b9bc1..d0b8bd7343c7 100644 --- a/src/test/lazy-omap-stats/lazy_omap_stats_test.cc +++ b/src/test/lazy-omap-stats/lazy_omap_stats_test.cc @@ -15,7 +15,6 @@ #include #include -#include #include #include // uuid class #include // generators @@ -25,11 +24,13 @@ #include #include -#include "lazy_omap_stats_test.h" +#include "common/ceph_json.h" +#include "global/global_init.h" #include "include/compat.h" +#include "lazy_omap_stats_test.h" + using namespace std; -namespace bp = boost::process; void LazyOmapStatsTest::init(const int argc, const char** argv) { @@ -100,6 +101,8 @@ void LazyOmapStatsTest::init(const int argc, const char** argv) << endl; exit(ret); } + + get_pool_id(conf.pool_name); } void LazyOmapStatsTest::shutdown() @@ -167,20 +170,54 @@ void LazyOmapStatsTest::create_payload() << endl; } -void LazyOmapStatsTest::scrub() const +void LazyOmapStatsTest::scrub() { - // Use CLI because we need to block - cout << "Scrubbing" << endl; - error_code ec; - bp::ipstream is; - bp::child c("ceph osd deep-scrub all --block"); - c.wait(ec); - if (ec) { - cout << "Deep scrub command failed! Error: " << ec.value() << " " - << ec.message() << endl; - exit(ec.value()); + + cout << "Before scrub stamps:" << endl; + string target_pool(conf.pool_id); + target_pool.append("."); + bool target_pool_found = false; + map before_scrub = get_scrub_stamps(); + for (auto [pg, stamp] : before_scrub) { + cout << "pg = " << pg << " stamp = " << stamp << endl; + if (pg.rfind(target_pool, 0) == 0) { + target_pool_found = true; + } + } + if (!target_pool_found) { + cout << "Error: Target pool " << conf.pool_name << ":" << conf.pool_id + << " not found!" << endl; + exit(2); // ENOENT + } + cout << endl; + + // Short sleep to make sure the new pool is visible + sleep(5); + + string command = R"({"prefix": "osd deep-scrub", "who": "all"})"; + auto output = get_output(command); + cout << output << endl; + + cout << "Waiting for deep-scrub to complete..." << endl; + while (sleep(1) == 0) { + cout << "Current scrub stamps:" << endl; + bool complete = true; + map current_stamps = get_scrub_stamps(); + for (auto [pg, stamp] : current_stamps) { + cout << "pg = " << pg << " stamp = " << stamp << endl; + if (stamp == before_scrub[pg]) { + // See if stamp for each pg has changed + // If not, we haven't completed the deep-scrub + complete = false; + } + } + cout << endl; + if (complete) { + break; + } } + cout << "Scrubbing complete" << endl; } const int LazyOmapStatsTest::find_matches(string& output, regex& reg) const @@ -195,11 +232,17 @@ const int LazyOmapStatsTest::find_matches(string& output, regex& reg) const } const string LazyOmapStatsTest::get_output(const string command, - const bool silent) + const bool silent, + const CommandTarget target) { librados::bufferlist inbl, outbl; string output; - int ret = rados.mgr_command(command, inbl, &outbl, &output); + int ret = 0; + if (target == CommandTarget::TARGET_MON) { + ret = rados.mon_command(command, inbl, &outbl, &output); + } else { + ret = rados.mgr_command(command, inbl, &outbl, &output); + } if (output.length() && !silent) { cout << output << endl; } @@ -212,6 +255,46 @@ const string LazyOmapStatsTest::get_output(const string command, return string(outbl.c_str(), outbl.length()); } +void LazyOmapStatsTest::get_pool_id(const string& pool) +{ + cout << R"(Querying pool id)" << endl; + + string command = R"({"prefix": "osd pool ls", "detail": "detail", "format": "json"})"; + librados::bufferlist inbl, outbl; + auto output = get_output(command, false, CommandTarget::TARGET_MON); + JSONParser parser; + parser.parse(output.c_str(), output.size()); + for (const auto& pool : parser.get_array_elements()) { + JSONParser parser2; + parser2.parse(pool.c_str(), static_cast(pool.size())); + auto* obj = parser2.find_obj("pool_name"); + if (obj->get_data().compare(conf.pool_name) == 0) { + obj = parser2.find_obj("pool_id"); + conf.pool_id = obj->get_data(); + } + } + if (conf.pool_id.empty()) { + cout << "Failed to find pool ID for pool " << conf.pool_name << "!" << endl; + exit(2); // ENOENT + } else { + cout << "Found pool ID: " << conf.pool_id << endl; + } +} + +map LazyOmapStatsTest::get_scrub_stamps() { + map stamps; + string command = R"({"prefix": "pg dump", "format": "json"})"; + auto output = get_output(command); + JSONParser parser; + parser.parse(output.c_str(), output.size()); + auto* obj = parser.find_obj("pg_map")->find_obj("pg_stats"); + for (auto pg = obj->find_first(); !pg.end(); ++pg) { + stamps.insert({(*pg)->find_obj("pgid")->get_data(), + (*pg)->find_obj("last_deep_scrub_stamp")->get_data()}); + } + return stamps; +} + void LazyOmapStatsTest::check_one() { string full_output = get_output(); @@ -333,34 +416,6 @@ index_t LazyOmapStatsTest::get_indexes(regex& reg, string& output) const return indexes; } -const string LazyOmapStatsTest::get_pool_id(string& pool) -{ - cout << R"(Querying pool id)" << endl; - - string command = R"({"prefix": "osd pool ls", "detail": "detail"})"; - librados::bufferlist inbl, outbl; - string output; - int ret = rados.mon_command(command, inbl, &outbl, &output); - if (output.length()) cout << output << endl; - if (ret < 0) { - ret = -ret; - cerr << "Failed to get pool id! Error: " << ret << " " << strerror(ret) - << endl; - exit(ret); - } - string dump_output(outbl.c_str(), outbl.length()); - cout << dump_output << endl; - - string poolregstring = R"(pool\s(\d+)\s')" + pool + "'"; - regex reg(poolregstring); - smatch match; - regex_search(dump_output, match, reg); - auto pool_id = match[1].str(); - cout << "Found pool ID: " << pool_id << endl; - - return pool_id; -} - void LazyOmapStatsTest::check_pg_dump() { cout << R"(Checking "pg dump" output)" << endl; @@ -459,12 +514,10 @@ void LazyOmapStatsTest::check_pg_dump_pools() "\n"); index_t indexes = get_indexes(reg, dump_output); - auto pool_id = get_pool_id(conf.pool_name); - reg = "\n" R"(()" + - pool_id + + conf.pool_id + R"(\s.*))" "\n"; smatch match; diff --git a/src/test/lazy-omap-stats/lazy_omap_stats_test.h b/src/test/lazy-omap-stats/lazy_omap_stats_test.h index 020c72c7358a..57cbe6e32698 100644 --- a/src/test/lazy-omap-stats/lazy_omap_stats_test.h +++ b/src/test/lazy-omap-stats/lazy_omap_stats_test.h @@ -39,10 +39,16 @@ class LazyOmapStatsTest unsigned keys = 2000; unsigned how_many = 50; std::string pool_name = "lazy_omap_test_pool"; + std::string pool_id; unsigned total_bytes = 0; unsigned total_keys = 0; } conf; + typedef enum { + TARGET_MON, + TARGET_MGR + } CommandTarget; + LazyOmapStatsTest(LazyOmapStatsTest&) = delete; void operator=(LazyOmapStatsTest) = delete; void init(const int argc, const char** argv); @@ -51,7 +57,7 @@ class LazyOmapStatsTest const std::string get_name() const; void create_payload(); void write_many(const unsigned how_many); - void scrub() const; + void scrub(); const int find_matches(std::string& output, std::regex& reg) const; void check_one(); const int find_index(std::string& haystack, std::regex& needle, @@ -61,7 +67,6 @@ class LazyOmapStatsTest void check_column(const int index, const std::string& table, const std::string& type, bool header = true) const; index_t get_indexes(std::regex& reg, std::string& output) const; - const std::string get_pool_id(std::string& pool); void check_pg_dump(); void check_pg_dump_summary(); void check_pg_dump_pgs(); @@ -69,7 +74,10 @@ class LazyOmapStatsTest void check_pg_ls(); const std::string get_output( const std::string command = R"({"prefix": "pg dump"})", - const bool silent = false); + const bool silent = false, + const CommandTarget target = CommandTarget::TARGET_MGR); + void get_pool_id(const std::string& pool); + std::map get_scrub_stamps(); void wait_for_active_clean(); public: -- 2.47.3