mirror of
https://github.com/ceph/ceph
synced 2024-12-16 08:26:25 +00:00
Merge pull request #16372 from dillaman/wip-20643
cls/rbd: trash_list should be iterable Reviewed-by: Mykola Golub <mgolub@mirantis.com>
This commit is contained in:
commit
547aa49d67
@ -5016,6 +5016,11 @@ int trash_remove(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
|
||||
* Returns the list of trash spec entries registered in the rbd_trash
|
||||
* object.
|
||||
*
|
||||
* Input:
|
||||
* @param start_after which name to begin listing after
|
||||
* (use the empty string to start at the beginning)
|
||||
* @param max_return the maximum number of names to list
|
||||
*
|
||||
* Output:
|
||||
* @param data the map between image id and trash spec info
|
||||
*
|
||||
@ -5023,18 +5028,30 @@ int trash_remove(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
|
||||
*/
|
||||
int trash_list(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
|
||||
{
|
||||
string start_after;
|
||||
uint64_t max_return;
|
||||
|
||||
try {
|
||||
bufferlist::iterator iter = in->begin();
|
||||
::decode(start_after, iter);
|
||||
::decode(max_return, iter);
|
||||
} catch (const buffer::error &err) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
map<string, cls::rbd::TrashImageSpec> data;
|
||||
string last_read = trash::image_key("");
|
||||
int max_read = RBD_MAX_KEYS_READ;
|
||||
string last_read = trash::image_key(start_after);
|
||||
|
||||
CLS_LOG(20, "trash_get_images");
|
||||
|
||||
do {
|
||||
while (data.size() < max_return) {
|
||||
map<string, bufferlist> raw_data;
|
||||
int max_read = std::min<int32_t>(RBD_MAX_KEYS_READ,
|
||||
max_return - data.size());
|
||||
int r = cls_cxx_map_get_vals(hctx, last_read, trash::IMAGE_KEY_PREFIX,
|
||||
max_read, &raw_data);
|
||||
if (r < 0) {
|
||||
CLS_ERR("failed to read the vals off of disk: %s", cpp_strerror(r).c_str());
|
||||
CLS_ERR("failed to read the vals off of disk: %s",
|
||||
cpp_strerror(r).c_str());
|
||||
return r;
|
||||
}
|
||||
if (raw_data.empty()) {
|
||||
@ -5051,10 +5068,9 @@ int trash_list(cls_method_context_t hctx, bufferlist *in, bufferlist *out)
|
||||
}
|
||||
|
||||
last_read = raw_data.rbegin()->first;
|
||||
} while (max_read);
|
||||
}
|
||||
|
||||
::encode(data, *out);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2046,9 +2046,12 @@ namespace librbd {
|
||||
return ioctx->operate(RBD_TRASH, &op);
|
||||
}
|
||||
|
||||
void trash_list_start(librados::ObjectReadOperation *op)
|
||||
void trash_list_start(librados::ObjectReadOperation *op,
|
||||
const std::string &start, uint64_t max_return)
|
||||
{
|
||||
bufferlist bl;
|
||||
::encode(start, bl);
|
||||
::encode(max_return, bl);
|
||||
op->exec("rbd", "trash_list", bl);
|
||||
}
|
||||
|
||||
@ -2067,10 +2070,11 @@ namespace librbd {
|
||||
}
|
||||
|
||||
int trash_list(librados::IoCtx *ioctx,
|
||||
const std::string &start, uint64_t max_return,
|
||||
map<string, cls::rbd::TrashImageSpec> *entries)
|
||||
{
|
||||
librados::ObjectReadOperation op;
|
||||
trash_list_start(&op);
|
||||
trash_list_start(&op, start, max_return);
|
||||
|
||||
bufferlist out_bl;
|
||||
int r = ioctx->operate(RBD_TRASH, &op, &out_bl);
|
||||
|
@ -418,10 +418,12 @@ namespace librbd {
|
||||
void trash_remove(librados::ObjectWriteOperation *op,
|
||||
const std::string &id);
|
||||
int trash_remove(librados::IoCtx *ioctx, const std::string &id);
|
||||
void trash_list_start(librados::ObjectReadOperation *op);
|
||||
void trash_list_start(librados::ObjectReadOperation *op,
|
||||
const std::string &start, uint64_t max_return);
|
||||
int trash_list_finish(bufferlist::iterator *it,
|
||||
map<string, cls::rbd::TrashImageSpec> *entries);
|
||||
int trash_list(librados::IoCtx *ioctx,
|
||||
const std::string &start, uint64_t max_return,
|
||||
map<string, cls::rbd::TrashImageSpec> *entries);
|
||||
void trash_get_start(librados::ObjectReadOperation *op,
|
||||
const std::string &id);
|
||||
|
@ -1465,25 +1465,36 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) {
|
||||
CephContext *cct((CephContext *)io_ctx.cct());
|
||||
ldout(cct, 20) << "trash_list " << &io_ctx << dendl;
|
||||
|
||||
map<string, cls::rbd::TrashImageSpec> trash_entries;
|
||||
int r = cls_client::trash_list(&io_ctx, &trash_entries);
|
||||
if (r < 0) {
|
||||
if (r != -ENOENT) {
|
||||
lderr(cct) << "error listing rbd_trash entries: " << cpp_strerror(r)
|
||||
bool more_entries;
|
||||
uint32_t max_read = 1024;
|
||||
std::string last_read = "";
|
||||
do {
|
||||
map<string, cls::rbd::TrashImageSpec> trash_entries;
|
||||
int r = cls_client::trash_list(&io_ctx, last_read, max_read,
|
||||
&trash_entries);
|
||||
if (r < 0 && r != -ENOENT) {
|
||||
lderr(cct) << "error listing rbd trash entries: " << cpp_strerror(r)
|
||||
<< dendl;
|
||||
} else {
|
||||
r = 0;
|
||||
return r;
|
||||
} else if (r == -ENOENT) {
|
||||
break;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
for (const auto &entry : trash_entries) {
|
||||
rbd_trash_image_source_t source =
|
||||
static_cast<rbd_trash_image_source_t>(entry.second.source);
|
||||
entries.push_back({entry.first, entry.second.name, source,
|
||||
entry.second.deletion_time.sec(),
|
||||
entry.second.deferment_end_time.sec()});
|
||||
}
|
||||
if (trash_entries.empty()) {
|
||||
break;
|
||||
}
|
||||
|
||||
for (const auto &entry : trash_entries) {
|
||||
rbd_trash_image_source_t source =
|
||||
static_cast<rbd_trash_image_source_t>(entry.second.source);
|
||||
entries.push_back({entry.first, entry.second.name, source,
|
||||
entry.second.deletion_time.sec(),
|
||||
entry.second.deferment_end_time.sec()});
|
||||
}
|
||||
last_read = trash_entries.rbegin()->first;
|
||||
more_entries = (trash_entries.size() >= max_read);
|
||||
} while (more_entries);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2248,7 +2248,7 @@ TEST_F(TestClsRbd, trash_methods)
|
||||
string id2 = "123456780";
|
||||
|
||||
std::map<string, cls::rbd::TrashImageSpec> entries;
|
||||
ASSERT_EQ(-ENOENT, trash_list(&ioctx, &entries));
|
||||
ASSERT_EQ(-ENOENT, trash_list(&ioctx, "", 1024, &entries));
|
||||
|
||||
utime_t now1 = ceph_clock_now();
|
||||
utime_t now1_delay = now1;
|
||||
@ -2267,27 +2267,28 @@ TEST_F(TestClsRbd, trash_methods)
|
||||
ASSERT_EQ(0, trash_remove(&ioctx, id));
|
||||
ASSERT_EQ(-ENOENT, trash_remove(&ioctx, id));
|
||||
|
||||
ASSERT_EQ(0, trash_list(&ioctx, &entries));
|
||||
ASSERT_EQ(0, trash_list(&ioctx, "", 1024, &entries));
|
||||
ASSERT_TRUE(entries.empty());
|
||||
|
||||
ASSERT_EQ(0, trash_add(&ioctx, id, trash_spec2));
|
||||
ASSERT_EQ(0, trash_add(&ioctx, id2, trash_spec));
|
||||
|
||||
ASSERT_EQ(0, trash_list(&ioctx, &entries));
|
||||
ASSERT_EQ(0, trash_list(&ioctx, "", 1, &entries));
|
||||
ASSERT_TRUE(entries.find(id2) != entries.end());
|
||||
ASSERT_EQ(cls::rbd::TRASH_IMAGE_SOURCE_USER, entries[id2].source);
|
||||
ASSERT_EQ(std::string("name"), entries[id2].name);
|
||||
ASSERT_EQ(now1, entries[id2].deletion_time);
|
||||
ASSERT_EQ(now1_delay, entries[id2].deferment_end_time);
|
||||
|
||||
for (auto& entry : entries) {
|
||||
if (entry.first == id) {
|
||||
ASSERT_EQ(entry.second.source, cls::rbd::TRASH_IMAGE_SOURCE_MIRRORING);
|
||||
ASSERT_EQ(entry.second.name, "name2");
|
||||
ASSERT_EQ(entry.second.deletion_time, now2);
|
||||
ASSERT_EQ(entry.second.deferment_end_time, now2_delay);
|
||||
} else if (entry.first == id2) {
|
||||
ASSERT_EQ(entry.second.source, cls::rbd::TRASH_IMAGE_SOURCE_USER);
|
||||
ASSERT_EQ(entry.second.name, "name");
|
||||
ASSERT_EQ(entry.second.deletion_time, now1);
|
||||
ASSERT_EQ(entry.second.deferment_end_time, now1_delay);
|
||||
}
|
||||
}
|
||||
ASSERT_EQ(0, trash_list(&ioctx, id2, 1, &entries));
|
||||
ASSERT_TRUE(entries.find(id) != entries.end());
|
||||
ASSERT_EQ(cls::rbd::TRASH_IMAGE_SOURCE_MIRRORING, entries[id].source);
|
||||
ASSERT_EQ(std::string("name2"), entries[id].name);
|
||||
ASSERT_EQ(now2, entries[id].deletion_time);
|
||||
ASSERT_EQ(now2_delay, entries[id].deferment_end_time);
|
||||
|
||||
ASSERT_EQ(0, trash_list(&ioctx, id, 1, &entries));
|
||||
ASSERT_TRUE(entries.empty());
|
||||
|
||||
cls::rbd::TrashImageSpec spec_res1;
|
||||
ASSERT_EQ(0, trash_get(&ioctx, id, &spec_res1));
|
||||
|
Loading…
Reference in New Issue
Block a user