crush: implement split_id_class

Refs: http://tracker.ceph.com/issues/18943

Signed-off-by: Loic Dachary <ldachary@redhat.com>
This commit is contained in:
Loic Dachary 2017-02-18 23:10:59 +01:00
parent b3c50b1429
commit 09e4d4029f
3 changed files with 54 additions and 0 deletions

View File

@ -104,6 +104,28 @@ bool CrushWrapper::is_v5_rule(unsigned ruleid) const
return false;
}
int CrushWrapper::split_id_class(int i, int *idout, int *classout) const
{
if (!item_exists(i))
return -EINVAL;
string name = get_item_name(i);
size_t pos = name.find("~");
if (pos == string::npos) {
*idout = i;
*classout = -1;
return 0;
}
string name_no_class = name.substr(0, pos);
if (!name_exists(name_no_class))
return -ENOENT;
string class_name = name.substr(pos + 1);
if (!class_exists(class_name))
return -ENOENT;
*idout = get_item_id(name_no_class);
*classout = get_class_id(class_name);
return 0;
}
int CrushWrapper::can_rename_item(const string& srcname,
const string& dstname,
ostream *ss) const

View File

@ -397,7 +397,11 @@ public:
name_rmap[name] = i;
return 0;
}
int split_id_class(int i, int *idout, int *classout) const;
bool class_exists(const string& name) const {
return class_rname.count(name);
}
const char *get_class_name(int i) const {
std::map<int,string>::const_iterator p = class_name.find(i);
if (p != class_name.end())

View File

@ -1012,6 +1012,34 @@ TEST(CrushWrapper, device_class_clone) {
ASSERT_EQ(c.device_class_clone(root_id, 12345, &other_clone_id), -EBADF);
}
TEST(CrushWrapper, split_id_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 class_id = c.get_or_create_class_id("ssd");
c.class_map[item] = class_id;
int item_id = c.get_item_id("default");
int clone_id;
ASSERT_EQ(c.device_class_clone(item_id, class_id, &clone_id), 0);
int retrieved_item_id;
int retrieved_class_id;
ASSERT_EQ(c.split_id_class(clone_id, &retrieved_item_id, &retrieved_class_id), 0);
ASSERT_EQ(item_id, retrieved_item_id);
ASSERT_EQ(class_id, retrieved_class_id);
ASSERT_EQ(c.split_id_class(item_id, &retrieved_item_id, &retrieved_class_id), 0);
ASSERT_EQ(item_id, retrieved_item_id);
ASSERT_EQ(-1, retrieved_class_id);
}
int main(int argc, char **argv) {
vector<const char*> args;
argv_to_vec(argc, (const char **)argv, args);