time_t deferment_end_time;
} trash_image_info_t;
+ typedef struct {
+ std::string pool_name;
+ std::string image_name;
+ std::string image_id;
+ bool trash;
+ } child_info_t;
+
class CEPH_RBD_API RBD
{
public:
return 0;
}
+bool compare_by_name(const child_info_t& c1, const child_info_t& c2)
+{
+ if (c1.pool_name != c2.pool_name)
+ return c1.pool_name < c2.pool_name;
+ else if (c1.image_name != c2.image_name)
+ return c1.image_name < c2.image_name;
+ else
+ return false;
+}
} // anonymous namespace
return 0;
}
- int list_children(ImageCtx *ictx, set<pair<string, string> >& names)
+ int list_children(ImageCtx *ictx,
+ vector<child_info_t> *names)
{
CephContext *cct = ictx->cct;
ldout(cct, 20) << "children list " << ictx->name << dendl;
}
Rados rados(ictx->md_ctx);
- for ( auto &info : image_info){
+ for (auto &info : image_info) {
IoCtx ioctx;
r = rados.ioctx_create2(info.first.first, ioctx);
if (r < 0) {
}
for (auto &id_it : info.second) {
- string name;
- r = cls_client::dir_get_name(&ioctx, RBD_DIRECTORY, id_it, &name);
- if (r < 0) {
- lderr(cct) << "Error looking up name for image id " << id_it
- << " in pool " << info.first.second << dendl;
- return r;
- }
- names.insert(make_pair(info.first.second, name));
+ string name;
+ bool trash = false;
+ r = cls_client::dir_get_name(&ioctx, RBD_DIRECTORY, id_it, &name);
+ if (r == -ENOENT) {
+ cls::rbd::TrashImageSpec trash_spec;
+ r = cls_client::trash_get(&ioctx, id_it, &trash_spec);
+ if (r < 0) {
+ if (r != -EOPNOTSUPP && r != -ENOENT) {
+ lderr(cct) << "Error looking up name for image id " << id_it
+ << " in rbd trash" << dendl;
+ return r;
+ }
+ return -ENOENT;
+ }
+ name = trash_spec.name;
+ trash = true;
+ } else if (r < 0 && r != -ENOENT) {
+ lderr(cct) << "Error looking up name for image id " << id_it
+ << " in pool " << info.first.second << dendl;
+ return r;
+ }
+ names->push_back(
+ child_info_t {
+ info.first.second,
+ name,
+ id_it,
+ trash
+ });
}
}
-
+ std::sort(names->begin(), names->end(), compare_by_name);
+
return 0;
}
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);
+ std::vector<child_info_t> *names);
int create(librados::IoCtx& io_ctx, const char *imgname, uint64_t size,
int *order);
int create(librados::IoCtx& io_ctx, const char *imgname, uint64_t size,
{
ImageCtx *ictx = (ImageCtx *)ctx;
tracepoint(librbd, list_children_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only);
- int r = librbd::list_children(ictx, *children);
+ vector<librbd::child_info_t> children2;
+ int r = librbd::list_children(ictx, &children2);
if (r >= 0) {
- for (set<pair<string, string> >::const_iterator it = children->begin();
- it != children->end(); ++it) {
- tracepoint(librbd, list_children_entry, it->first.c_str(), it->second.c_str());
+ for (std::vector<librbd::child_info_t>::iterator it = children2.begin();
+ it != children2.end(); ++it) {
+ if (!it->trash) {
+ children->insert(make_pair(it->pool_name, it->image_name));
+ tracepoint(librbd, list_children_entry, it->pool_name.c_str(), it->image_name.c_str());
+ }
}
}
tracepoint(librbd, list_children_exit, r);
librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
tracepoint(librbd, list_children_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only);
set<pair<string, string> > image_set;
+ vector<librbd::child_info_t> children;
- int r = librbd::list_children(ictx, image_set);
+ int r = librbd::list_children(ictx, &children);
if (r < 0) {
tracepoint(librbd, list_children_exit, r);
return r;
}
+ for (std::vector<librbd::child_info_t>::iterator it = children.begin();
+ it != children.end(); ++it) {
+ if (!it->trash) {
+ image_set.insert(make_pair(it->pool_name, it->image_name));
+ }
+ }
+
size_t pools_total = 0;
size_t images_total = 0;
for (set<pair<string, string> >::const_iterator it = image_set.begin();