]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
crush: implement class_is_in_use/remove_class_name
authorLoic Dachary <ldachary@redhat.com>
Mon, 3 Apr 2017 15:39:18 +0000 (17:39 +0200)
committerLoic Dachary <ldachary@redhat.com>
Wed, 5 Apr 2017 07:22:24 +0000 (09:22 +0200)
Signed-off-by: Loic Dachary <loic@dachary.org>
src/crush/CrushWrapper.cc
src/crush/CrushWrapper.h
src/test/crush/CrushWrapper.cc

index 868a52d49d34941307921eeac9c11ce12da71399..f1093070538cef9f579d642364006ba14ec8dfd7 100644 (file)
@@ -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<int> roots;
index 50289e0f3733ec071639feb7074ce60e7b8a766d..7a074b8738ac066ed015a5f910b5621e5961680c 100644 (file)
@@ -422,6 +422,18 @@ public:
     else
       return -EINVAL;
   }
+  int remove_class_name(const string& name) {
+    std::map<string,int>::const_iterator p = class_rname.find(name);
+    if (p == class_rname.end())
+      return -ENOENT;
+    int class_id = p->second;
+    std::map<int,string>::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 */
index ac27c719e864b45ee322c629dea20e94797f22c5..ba6cd774f5f9e090c2b26761736cac314437e7a4 100644 (file)
@@ -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<string,string> 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: