]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: fix rbd children listing when child is in trash bin
authorsongweibin <song.weibin@zte.com.cn>
Tue, 31 Oct 2017 10:21:33 +0000 (18:21 +0800)
committersongweibin <song.weibin@zte.com.cn>
Thu, 2 Nov 2017 05:09:51 +0000 (13:09 +0800)
Signed-off-by: songweibin <song.weibin@zte.com.cn>
src/include/rbd/librbd.hpp
src/librbd/internal.cc
src/librbd/internal.h
src/librbd/librbd.cc

index bbf4270bc245d7b13bd1eb4a5700acc3eccf7054..4539ed43d0b4a51a88402417d3578d407be8060a 100644 (file)
@@ -101,6 +101,13 @@ namespace librbd {
     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:
index 9b322997014dc7a06943416853be5cdc432389f9..6ebbf6a48db10dfd1a15627d394535844ead06c2 100644 (file)
@@ -109,6 +109,15 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) {
   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
 
@@ -645,7 +654,8 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) {
     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;
@@ -665,7 +675,7 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) {
     }
 
     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) {
@@ -675,17 +685,38 @@ int validate_pool(IoCtx &io_ctx, CephContext *cct) {
       }
 
       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;
   }
 
index 72633f592ca3b9c08ae8f611c3b132f4b31b9dfc..3dc813f25b38ea64bf7b85b6d8e33ddf8957e5b2 100644 (file)
@@ -104,7 +104,7 @@ 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);
+                    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,
index 999ac25233aa01fd001656ce3bea39d1569827e7..48f5c2504f3c5f9244b1812858e9a732ef31c586 100644 (file)
@@ -1261,11 +1261,15 @@ namespace librbd {
   {
     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);
@@ -3295,13 +3299,21 @@ extern "C" ssize_t rbd_list_children(rbd_image_t image, char *pools,
   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();