Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

librbd: Skip tier pools in list_children and snap_unprotect #2619

Merged
merged 1 commit into from Oct 1, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
22 changes: 21 additions & 1 deletion src/librbd/internal.cc
Expand Up @@ -418,10 +418,20 @@ namespace librbd {

for (std::list<string>::const_iterator it = pools.begin();
it != pools.end(); ++it) {
int64_t pool_id = rados.pool_lookup(it->c_str());
int64_t base_tier;
int r = rados.pool_get_base_tier(pool_id, &base_tier);
if (r < 0) {
return r;
}
if (base_tier != pool_id) {
// pool is a cache; skip it
continue;
}
IoCtx ioctx;
rados.ioctx_create(it->c_str(), ioctx);
set<string> image_ids;
int r = cls_client::get_children(&ioctx, RBD_CHILDREN,
r = cls_client::get_children(&ioctx, RBD_CHILDREN,
parent_spec, image_ids);
if (r < 0 && r != -ENOENT) {
lderr(cct) << "Error reading list of children from pool " << *it
Expand Down Expand Up @@ -637,6 +647,16 @@ namespace librbd {
rados.pool_list(pools);
std::set<std::string> children;
for (std::list<std::string>::const_iterator it = pools.begin(); it != pools.end(); ++it) {
int64_t pool_id = rados.pool_lookup(it->c_str());
int64_t base_tier;
r = rados.pool_get_base_tier(pool_id, &base_tier);
if (r < 0) {
return r;
}
if (base_tier != pool_id) {
// pool is a cache; skip it
continue;
}
IoCtx pool_ioctx;
r = rados.ioctx_create(it->c_str(), pool_ioctx);
if (r < 0) {
Expand Down
118 changes: 118 additions & 0 deletions src/test/librbd/test_librbd.cc
Expand Up @@ -1330,6 +1330,124 @@ TEST(LibRBD, ListChildren)
ASSERT_EQ(0, destroy_one_pool(pool_name2, &cluster));
}

TEST(LibRBD, ListChildrenTiered)
{
rados_t cluster;
string pool_name1 = get_temp_pool_name();
ASSERT_EQ("", create_one_pool(pool_name1, &cluster));
string pool_name2 = get_temp_pool_name();
ASSERT_EQ("", create_one_pool(pool_name2, &cluster));
string pool_name3 = get_temp_pool_name();
ASSERT_EQ("", create_one_pool(pool_name3, &cluster));

std::string cmdstr = "{\"prefix\": \"osd tier add\", \"pool\": \"" +
pool_name1 + "\", \"tierpool\":\"" + pool_name3 + "\", \"force_nonempty\":\"\"}";
char *cmd[1];
cmd[0] = (char *)cmdstr.c_str();
ASSERT_EQ(0, rados_mon_command(cluster, (const char **)cmd, 1, "", 0, NULL, 0, NULL, 0));

cmdstr = "{\"prefix\": \"osd tier cache-mode\", \"pool\": \"" +
pool_name3 + "\", \"mode\":\"writeback\"}";
cmd[0] = (char *)cmdstr.c_str();
ASSERT_EQ(0, rados_mon_command(cluster, (const char **)cmd, 1, "", 0, NULL, 0, NULL, 0));

cmdstr = "{\"prefix\": \"osd tier set-overlay\", \"pool\": \"" +
pool_name1 + "\", \"overlaypool\":\"" + pool_name3 + "\"}";
cmd[0] = (char *)cmdstr.c_str();
ASSERT_EQ(0, rados_mon_command(cluster, (const char **)cmd, 1, "", 0, NULL, 0, NULL, 0));

EXPECT_EQ(0, rados_wait_for_latest_osdmap(cluster));

rados_ioctx_t ioctx1, ioctx2;
rados_ioctx_create(cluster, pool_name1.c_str(), &ioctx1);
rados_ioctx_create(cluster, pool_name2.c_str(), &ioctx2);

int features = RBD_FEATURE_LAYERING;
rbd_image_t parent;
int order = 0;

// make a parent to clone from
ASSERT_EQ(0, create_image_full(ioctx1, "parent", 4<<20, &order,
false, features));
ASSERT_EQ(0, rbd_open(ioctx1, "parent", &parent, NULL));
// create a snapshot, reopen as the parent we're interested in
ASSERT_EQ(0, rbd_snap_create(parent, "parent_snap"));
ASSERT_EQ(0, rbd_snap_set(parent, "parent_snap"));
ASSERT_EQ(0, rbd_snap_protect(parent, "parent_snap"));

ASSERT_EQ(0, rbd_close(parent));
ASSERT_EQ(0, rbd_open(ioctx1, "parent", &parent, "parent_snap"));

ASSERT_EQ(0, rbd_clone(ioctx1, "parent", "parent_snap", ioctx2, "child1",
features, &order));
test_list_children(parent, 1, pool_name2.c_str(), "child1");

ASSERT_EQ(0, rbd_clone(ioctx1, "parent", "parent_snap", ioctx1, "child2",
features, &order));
test_list_children(parent, 2, pool_name2.c_str(), "child1",
pool_name1.c_str(), "child2");

// read from the cache to populate it
rbd_image_t tier_image;
ASSERT_EQ(0, rbd_open(ioctx1, "child2", &tier_image, NULL));
size_t len = 4 * 1024 * 1024;
char* buf = (char*)malloc(len);
ssize_t size = rbd_read(tier_image, 0, len, buf);
ASSERT_GT(size, 0);
free(buf);
ASSERT_EQ(0, rbd_close(tier_image));

ASSERT_EQ(0, rbd_clone(ioctx1, "parent", "parent_snap", ioctx2, "child3",
features, &order));
test_list_children(parent, 3, pool_name2.c_str(), "child1",
pool_name1.c_str(), "child2",
pool_name2.c_str(), "child3");

ASSERT_EQ(0, rbd_clone(ioctx1, "parent", "parent_snap", ioctx2, "child4",
features, &order));
test_list_children(parent, 4, pool_name2.c_str(), "child1",
pool_name1.c_str(), "child2",
pool_name2.c_str(), "child3",
pool_name2.c_str(), "child4");

ASSERT_EQ(0, rbd_remove(ioctx2, "child1"));
test_list_children(parent, 3,
pool_name1.c_str(), "child2",
pool_name2.c_str(), "child3",
pool_name2.c_str(), "child4");

ASSERT_EQ(0, rbd_remove(ioctx2, "child3"));
test_list_children(parent, 2,
pool_name1.c_str(), "child2",
pool_name2.c_str(), "child4");

ASSERT_EQ(0, rbd_remove(ioctx2, "child4"));
test_list_children(parent, 1,
pool_name1.c_str(), "child2");

ASSERT_EQ(0, rbd_remove(ioctx1, "child2"));
test_list_children(parent, 0);

ASSERT_EQ(0, rbd_snap_unprotect(parent, "parent_snap"));
ASSERT_EQ(0, rbd_snap_remove(parent, "parent_snap"));
ASSERT_EQ(0, rbd_close(parent));
ASSERT_EQ(0, rbd_remove(ioctx1, "parent"));
rados_ioctx_destroy(ioctx1);
rados_ioctx_destroy(ioctx2);
// destroy_one_pool also closes the cluster; do this one step at a time
cmdstr = "{\"prefix\": \"osd tier remove-overlay\", \"pool\": \"" +
pool_name1 + "\"}";
cmd[0] = (char *)cmdstr.c_str();
ASSERT_EQ(0, rados_mon_command(cluster, (const char **)cmd, 1, "", 0, NULL, 0, NULL, 0));
cmdstr = "{\"prefix\": \"osd tier remove\", \"pool\": \"" +
pool_name1 + "\", \"tierpool\":\"" + pool_name3 + "\"}";
cmd[0] = (char *)cmdstr.c_str();
ASSERT_EQ(0, rados_mon_command(cluster, (const char **)cmd, 1, "", 0, NULL, 0, NULL, 0));
ASSERT_EQ(0, rados_pool_delete(cluster, pool_name3.c_str()));
ASSERT_EQ(0, rados_pool_delete(cluster, pool_name1.c_str()));
ASSERT_EQ(0, destroy_one_pool(pool_name2, &cluster));
}

TEST(LibRBD, LockingPP)
{
librados::Rados rados;
Expand Down