From e7d91eb4e85727fc381dd0348df5635d841a4dcd Mon Sep 17 00:00:00 2001 From: Loic Dachary Date: Mon, 3 Apr 2017 17:39:18 +0200 Subject: [PATCH] crush: implement class_is_in_use/remove_class_name Signed-off-by: Loic Dachary --- src/crush/CrushWrapper.cc | 14 ++++++++++++++ src/crush/CrushWrapper.h | 13 +++++++++++++ src/test/crush/CrushWrapper.cc | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+) diff --git a/src/crush/CrushWrapper.cc b/src/crush/CrushWrapper.cc index 868a52d49d34..f1093070538c 100644 --- a/src/crush/CrushWrapper.cc +++ b/src/crush/CrushWrapper.cc @@ -1014,6 +1014,20 @@ int CrushWrapper::get_immediate_parent_id(int id, int *parent) const return -ENOENT; } +bool CrushWrapper::class_is_in_use(int class_id) +{ + for (auto &i : class_bucket) + for (auto &j : i.second) + if (j.first == class_id) + return true; + + for (auto &i : class_map) + if (i.second == class_id) + return true; + + return false; +} + int CrushWrapper::populate_classes() { set roots; diff --git a/src/crush/CrushWrapper.h b/src/crush/CrushWrapper.h index 50289e0f3733..7a074b8738ac 100644 --- a/src/crush/CrushWrapper.h +++ b/src/crush/CrushWrapper.h @@ -422,6 +422,18 @@ public: else return -EINVAL; } + int remove_class_name(const string& name) { + std::map::const_iterator p = class_rname.find(name); + if (p == class_rname.end()) + return -ENOENT; + int class_id = p->second; + std::map::const_iterator q = class_name.find(class_id); + if (q == class_name.end()) + return -ENOENT; + class_rname.erase(name); + class_name.erase(class_id); + return 0; + } int get_or_create_class_id(const string& name) { int c = get_class_id(name); if (c < 0) { @@ -1091,6 +1103,7 @@ public: int update_device_class(CephContext *cct, int id, const string& class_name, const string& name); int device_class_clone(int original, int device_class, int *clone); + bool class_is_in_use(int class_id); int populate_classes(); int rebuild_roots_with_classes(); /* remove unused roots generated for class devices */ diff --git a/src/test/crush/CrushWrapper.cc b/src/test/crush/CrushWrapper.cc index ac27c719e864..ba6cd774f5f9 100644 --- a/src/test/crush/CrushWrapper.cc +++ b/src/test/crush/CrushWrapper.cc @@ -1093,6 +1093,37 @@ TEST(CrushWrapper, populate_and_cleanup_classes) { ASSERT_FALSE(c.name_exists("default~ssd")); } +TEST(CrushWrapper, class_is_in_use) { + CrushWrapper c; + c.create(); + c.set_type_name(1, "root"); + + int weight = 1; + map loc; + loc["root"] = "default"; + + ASSERT_FALSE(c.class_is_in_use(0)); + + int item = 1; + c.insert_item(g_ceph_context, item, weight, "osd.1", loc); + int class_id = c.get_or_create_class_id("ssd"); + c.class_map[item] = class_id; + + ASSERT_TRUE(c.class_is_in_use(c.get_class_id("ssd"))); + ASSERT_EQ(0, c.remove_class_name("ssd")); + ASSERT_FALSE(c.class_is_in_use(c.get_class_id("ssd"))); +} + +TEST(CrushWrapper, remove_class_name) { + CrushWrapper c; + c.create(); + + ASSERT_EQ(-ENOENT, c.remove_class_name("ssd")); + ASSERT_GE(0, c.get_or_create_class_id("ssd")); + ASSERT_EQ(0, c.remove_class_name("ssd")); + ASSERT_EQ(-ENOENT, c.remove_class_name("ssd")); +} + TEST(CrushWrapper, try_remap_rule) { // build a simple 2 level map CrushWrapper c; @@ -1282,3 +1313,6 @@ int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } +// Local Variables: +// compile-command: "cd ../../../build ; make -j4 unittest_crush_wrapper && bin/unittest_crush_wrapper" +// End: -- 2.47.3