]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
crush: implement trim_roots_with_class
authorLoic Dachary <ldachary@redhat.com>
Sat, 18 Feb 2017 22:18:49 +0000 (23:18 +0100)
committerLoic Dachary <ldachary@redhat.com>
Wed, 1 Mar 2017 16:24:09 +0000 (17:24 +0100)
Refs: http://tracker.ceph.com/issues/18943

Signed-off-by: Loic Dachary <ldachary@redhat.com>
src/crush/CrushWrapper.cc
src/crush/CrushWrapper.h
src/test/crush/CrushWrapper.cc

index 527abe526960b75c27dfca03de97b3612b1c4ed7..caae1512567586acc6480ec9ed39e16f0b2eadc5 100644 (file)
@@ -1000,6 +1000,26 @@ int CrushWrapper::get_immediate_parent_id(int id, int *parent)
   return -ENOENT;
 }
 
+int CrushWrapper::trim_roots_with_class()
+{
+  set<int> takes;
+  find_takes(takes);
+  set<int> roots;
+  find_roots(roots);
+  for (auto &r : roots) {
+    if (r >= 0)
+      continue;
+    if (!id_has_class(r))
+      continue;
+    int res = remove_unused_root(r);
+    if (res)
+      return res;
+  }
+  // there is no need to reweight because we only remove from the
+  // root and down
+  return 0;
+}
+
 void CrushWrapper::reweight(CephContext *cct)
 {
   set<int> roots;
index a265004dcb1435f84f791da9c965f6b971506693..7de67b94db0f606b653f93031b9e6a93e5e84a84 100644 (file)
@@ -397,6 +397,13 @@ public:
       name_rmap[name] = i;
     return 0;
   }
+  bool id_has_class(int i) {
+    int idout;
+    int classout;
+    if (split_id_class(i, &idout, &classout) != 0)
+      return false;
+    return classout != -1;
+  }
   int split_id_class(int i, int *idout, int *classout) const;
 
   bool class_exists(const string& name) const {
@@ -1082,6 +1089,8 @@ public:
   }
 
   int device_class_clone(int original, int device_class, int *clone);
+  /* remove unused roots generated for class devices */
+  int trim_roots_with_class();
   void start_choose_profile() {
     free(crush->choose_tries);
     /*
index f734efb3aaa23a7ebeb4f2a9bf4e0af7a821c8f4..ee774e9feefffbf361a85ce561a6bd8b2ae681ff 100644 (file)
@@ -972,6 +972,36 @@ TEST(CrushWrapper, remove_unused_root) {
   ASSERT_FALSE(c.name_exists("r12"));
 }
 
+TEST(CrushWrapper, trim_roots_with_class) {
+  CrushWrapper c;
+  c.create();
+  c.set_type_name(1, "root");
+
+  int weight = 1;
+  map<string,string> loc;
+  loc["root"] = "default";
+
+  int item = 1;
+  c.insert_item(g_ceph_context, item, weight, "osd.1", loc);
+  int cl = c.get_or_create_class_id("ssd");
+  c.class_map[item] = cl;
+
+
+  int root_id = c.get_item_id("default");
+  int clone_id;
+  ASSERT_EQ(c.device_class_clone(root_id, cl, &clone_id), 0);
+
+  ASSERT_TRUE(c.name_exists("default"));
+  ASSERT_TRUE(c.name_exists("default~ssd"));
+  c.trim_roots_with_class(); // do nothing because still in use
+  ASSERT_TRUE(c.name_exists("default"));
+  ASSERT_TRUE(c.name_exists("default~ssd"));
+  c.class_bucket.clear();
+  c.trim_roots_with_class(); // do nothing because still in use
+  ASSERT_TRUE(c.name_exists("default"));
+  ASSERT_FALSE(c.name_exists("default~ssd"));
+}
+
 TEST(CrushWrapper, device_class_clone) {
   CrushWrapper c;
   c.create();