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
rbd: fix rbd children listing when child is in trash and add rbd_list_children2 method #18483
Conversation
need to fix the cli test first.. |
1e74946
to
6332433
Compare
@dillaman please help to have a review, thanks in advance. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks -- can you also ensure the test cases verify that images in the trash are properly returned?
src/include/rbd/librbd.hpp
Outdated
std::string image_name; | ||
std::string image_id; | ||
} children_info_t; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: child_info_t
(since children
implies more than one)
src/include/rbd/librbd.hpp
Outdated
* Returns a structure of poolname, imagename, imageid for | ||
* each clone of this image at the currently set snapshot. | ||
*/ | ||
int list_children2(std::vector<librbd::children_info_t>& children2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: no need for 2
at the end of the parameter name
src/librbd/internal.h
Outdated
@@ -105,6 +105,8 @@ namespace librbd { | |||
int list(librados::IoCtx& io_ctx, std::vector<std::string>& names); | |||
int list_children(ImageCtx *ictx, | |||
std::set<std::pair<std::string, std::string> > & names); | |||
int list_children2(ImageCtx *ictx, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's not add a duplicate function within the internal API -- instead, update the existing list_children
method to take std::vector<child_info_t>
and update the public API methods to convert between the new type and the old pair
.
src/librbd/librbd.cc
Outdated
@@ -1272,6 +1272,20 @@ namespace librbd { | |||
return r; | |||
} | |||
|
|||
int Image::list_children2(vector<librbd::children_info_t>& children2) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: no need for 2
suffix on param name
src/librbd/internal.cc
Outdated
lderr(cct) << "Error looking up name for image id " << id_it | ||
<< " in pool " << info.first.second << dendl; | ||
return r; | ||
} else if (r == -ENOENT) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: execute the -ENOENT
handling first. If it fails w/ -EOENT, you should allow it to fall through to the generic handling so that the error message is "error looking up name for image id XYZ in pool" instead of "in rbd trash".
src/librbd/internal.cc
Outdated
} else if (r == -ENOENT) { | ||
cls::rbd::TrashImageSpec trash_spec; | ||
r = cls_client::trash_get(&ioctx, id_it, &trash_spec); | ||
if (r < 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to support older OSDs to filter out -EOPNOTSUPP
errors and change them to -ENOENT
so that it falls down into the moved generic error handler clause (from above).
src/tools/rbd/action/Children.cc
Outdated
f->close_section(); | ||
} else { | ||
std::cout << child_it.first << "/" << child_it.second << std::endl; | ||
if (all_flag) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: instead of duplicating all this logic, perhaps always use the new list_children2
API and if --all
wasn't specified, don't print any children that are in the trash.
src/include/rbd/librbd.hpp
Outdated
std::string pool_name; | ||
std::string image_name; | ||
std::string image_id; | ||
} children_info_t; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps add a bool trash
member so that users don't need to re-execute a trash_get
(since it was already performed within the API).
@@ -2232,6 +2235,40 @@ written." % (self.name, ret, length)) | |||
free(c_pools) | |||
free(c_images) | |||
|
|||
def list_children2(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be nicer to switch to an iterator style and return a dict for each child.
@dillaman Thanks for your nicer suggestions, will update later. |
e8399a8
to
f541e87
Compare
@dillaman Updated, please take a look, thanks.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Songweibin The function list_children(ImageCtx *ictx, set<pair<string, string> >& names)
should be removed from internal.h/cc and all "list children" public API methods should use list_children(ImageCtx *ictx, vector<child_info_t>& names)
src/librbd/internal.cc
Outdated
lderr(cct) << "Error looking up name for image id " << id_it | ||
<< " in pool " << info.first.second << dendl; | ||
return r; | ||
} else if (r == -ENOENT) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment still needs to be addressed
src/include/rbd/librbd.h
Outdated
CEPH_RBD_API int rbd_list_children2(rbd_image_t image, | ||
rbd_child_info_t *children, | ||
int *max_children); | ||
CEPH_RBD_API void rbd_list_child_end(rbd_child_info_t *children); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: rename to rbd_list_child_cleanup
and add a size_t num_children
parameter so that all the initialized rbd_child_info_t
structs can be cleaned
src/librbd/internal.cc
Outdated
names.insert(make_pair(info.first.second, name)); | ||
} | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
bool compare_by_name(const child_info_t& c1, const child_info_t& c2) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: add to anonymous namespace near top of file
src/librbd/internal.h
Outdated
@@ -105,6 +105,9 @@ namespace librbd { | |||
int list(librados::IoCtx& io_ctx, std::vector<std::string>& names); | |||
int list_children(ImageCtx *ictx, | |||
std::set<std::pair<std::string, std::string> > & names); | |||
int list_children(ImageCtx *ictx, | |||
std::vector<child_info_t>& names); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pass out-values by pointer instead of reference
88d6557
to
0d2c611
Compare
Signed-off-by: songweibin <song.weibin@zte.com.cn>
0d2c611
to
007d4d9
Compare
@dillaman Updated all, please take a review again, thanks. |
src/include/rbd/librbd.hpp
Outdated
*/ | ||
int list_children(std::set<std::pair<std::string, std::string> > *children); | ||
int list_children(std::vector<librbd::child_info_t> *children); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You cannot change the public API -- you can only change the private API that is implemented in "src/librbd/internal.cc"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, sorry, at first I thought list_children(std::set<std::pair<std::string, std::string> > *children)
was unused, so i changed it directly. Actually there may be other external APPs used it. Already modified, thanks.
@@ -144,7 +144,7 @@ Skip test on FreeBSD as it generates different output there. | |||
--io-type arg IO type (read , write, or readwrite(rw)) | |||
|
|||
rbd help children | |||
usage: rbd children [--pool <pool>] [--image <image>] [--snap <snap>] | |||
usage: rbd children [--pool <pool>] [--image <image>] [--snap <snap>] [--all] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These (related) changes seem to be mixing and matching between commits. The title of this commit is to fix a bug re: listing children for trashed images so it should be limited to handling that fix. The next commit can add the new API methods and expand the rbd CLI to list trashed images.
007d4d9
to
1d603b2
Compare
Signed-off-by: songweibin <song.weibin@zte.com.cn>
1d603b2
to
e6332d0
Compare
@dillaman Done, please help to take a look, thank you. |
src/librbd/librbd.cc
Outdated
children[i].trash = cpp_children[i].trash; | ||
if (!children[i].image_id) { | ||
for (int j = 0; j < i; j++) | ||
free((void *)children[j].image_id); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: re-use rbd_list_children_cleanup
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dillaman fixed, thanks for your carefully review.
src/librbd/librbd.cc
Outdated
children[i].image_name = strdup(cpp_children[i].image_name.c_str()); | ||
children[i].image_id = strdup(cpp_children[i].image_id.c_str()); | ||
children[i].trash = cpp_children[i].trash; | ||
if (!children[i].image_id) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: why only validate the result of image_id
instead of also checking pool_name
and image_name
?
59a20ad
to
5856920
Compare
src/librbd/librbd.cc
Outdated
int r = librbd::list_children(ictx, &cpp_children); | ||
if (r == -ENOENT) { | ||
tracepoint(librbd, list_children_exit, *max_children); | ||
return 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: if r == -NOENT
, just set r = 0
and continue so that max_return
is properly populated and the array is properly null terminated.
src/librbd/librbd.cc
Outdated
children[i].image_name = strdup(cpp_children[i].image_name.c_str()); | ||
children[i].image_id = strdup(cpp_children[i].image_id.c_str()); | ||
children[i].trash = cpp_children[i].trash; | ||
if (!children[i].pool_name && !children[i].image_name && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Swap the &&
operators to ||
since it should fail if any memory allocation fails
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dillaman fixed, thanks.
5856920
to
e4ea1f1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
src/tools/rbd/action/Children.cc
Outdated
std::cout << child_it.first << "/" << child_it.second << std::endl; | ||
if (all_flag) { | ||
std::cout << it->pool_name << "/" << it->image_name << "/" | ||
<< it->image_id; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry -- I missed this during the review but saw it when play-testing the change. I don't like how adding '--all" changes the format to include the image id. The "/" is part of the image-spec (i.e. pool/image) but it's being overloaded here to include the image id. I would include the image id only for items in the trash like the following:
<pool name>/<image name> (trash <image id>)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, sounds more reasonable. Already fixed, thanks.
e4ea1f1
to
ed3753c
Compare
The python tests appear to be failing: |
…ages implement librbd::RBD::list_children2 and rbd_list_children2 methods and expand the rbd CLI to list trashed images Signed-off-by: songweibin <song.weibin@zte.com.cn>
ed3753c
to
9d9a276
Compare
@dillaman Sorry, since |
Add rbd_list_children2 and librbd::RBD::list_children2 methods as @dillaman suggested in #14865 (comment)
and after this fix rbd children listing as follows:
http://tracker.ceph.com/issues/21893
Signed-off-by: songweibin song.weibin@zte.com.cn