From c68c0c64cefb3b2d11a7e40f2b58aca44d8e3cc4 Mon Sep 17 00:00:00 2001 From: Loic Dachary Date: Sat, 18 Feb 2017 23:18:49 +0100 Subject: [PATCH] crush: implement trim_roots_with_class Refs: http://tracker.ceph.com/issues/18943 Signed-off-by: Loic Dachary --- src/crush/CrushWrapper.cc | 20 ++++++++++++++++++++ src/crush/CrushWrapper.h | 9 +++++++++ src/test/crush/CrushWrapper.cc | 30 ++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+) diff --git a/src/crush/CrushWrapper.cc b/src/crush/CrushWrapper.cc index 527abe52696..caae1512567 100644 --- a/src/crush/CrushWrapper.cc +++ b/src/crush/CrushWrapper.cc @@ -1000,6 +1000,26 @@ int CrushWrapper::get_immediate_parent_id(int id, int *parent) return -ENOENT; } +int CrushWrapper::trim_roots_with_class() +{ + set takes; + find_takes(takes); + set 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 roots; diff --git a/src/crush/CrushWrapper.h b/src/crush/CrushWrapper.h index a265004dcb1..7de67b94db0 100644 --- a/src/crush/CrushWrapper.h +++ b/src/crush/CrushWrapper.h @@ -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); /* diff --git a/src/test/crush/CrushWrapper.cc b/src/test/crush/CrushWrapper.cc index f734efb3aaa..ee774e9feef 100644 --- a/src/test/crush/CrushWrapper.cc +++ b/src/test/crush/CrushWrapper.cc @@ -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 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();