]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: allow mirroring trash images to be restored
authorJason Dillaman <dillaman@redhat.com>
Wed, 11 Sep 2019 18:07:23 +0000 (14:07 -0400)
committerJason Dillaman <dillaman@redhat.com>
Wed, 9 Oct 2019 21:24:08 +0000 (17:24 -0400)
This functionality was accidentally broken when image live-migration
was introduced.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
(cherry picked from commit 0ef0f43da9d112c54e3f17ed786d7197f920b8a2)

Conflicts:
src/librbd/api/Trash.cc: TRASH_IMAGE_SOURCE_USER_PARENT not valid enum

src/librbd/api/Image.cc
src/librbd/api/Migration.cc
src/librbd/api/Trash.cc
src/librbd/api/Trash.h
src/librbd/librbd.cc
src/test/librbd/test_Trash.cc

index 13c5a90d8c547421945af4d0a7bd0484e646abad..3339909350e4e6c05f22809654c9e1e5a2006520 100644 (file)
@@ -782,7 +782,8 @@ int Image<I>::remove(IoCtx& io_ctx, const std::string &image_name,
         if (r == -ENOTEMPTY || r == -EBUSY || r == -EMLINK) {
           // best-effort try to restore the image if the removal
           // failed for possible expected reasons
-          Trash<I>::restore(io_ctx, trash_image_source, image_id, image_name);
+          Trash<I>::restore(io_ctx, {cls::rbd::TRASH_IMAGE_SOURCE_REMOVING},
+                            image_id, image_name);
         }
       }
       return r;
index 0c56959d76ececb0be40712cab4fad5d271a4e00..20c0c417386c932800e0303f035970c61c4c60fe 100644 (file)
@@ -1175,7 +1175,8 @@ template <typename I>
 int Migration<I>::v2_relink_src_image() {
   ldout(m_cct, 10) << dendl;
 
-  int r = Trash<I>::restore(m_src_io_ctx, RBD_TRASH_IMAGE_SOURCE_MIGRATION,
+  int r = Trash<I>::restore(m_src_io_ctx,
+                            {cls::rbd::TRASH_IMAGE_SOURCE_MIGRATION},
                             m_src_image_ctx->id, m_src_image_ctx->name);
   if (r < 0) {
     lderr(m_cct) << "failed restoring image from trash: " << cpp_strerror(r)
index de1f97d90da713aab265b1fadbd254d8e9748906..4fcc106b4e36af7605bcc5e1a9620cfd5fbac337 100644 (file)
 namespace librbd {
 namespace api {
 
+template <typename I>
+const typename Trash<I>::TrashImageSources Trash<I>::RESTORE_SOURCE_WHITELIST {
+    cls::rbd::TRASH_IMAGE_SOURCE_USER,
+    cls::rbd::TRASH_IMAGE_SOURCE_MIRRORING
+  };
+
 namespace {
 
 template <typename I>
@@ -544,7 +550,8 @@ int Trash<I>::remove(IoCtx &io_ctx, const std::string &image_id, bool force,
 }
 
 template <typename I>
-int Trash<I>::restore(librados::IoCtx &io_ctx, rbd_trash_image_source_t source,
+int Trash<I>::restore(librados::IoCtx &io_ctx,
+                      const TrashImageSources& trash_image_sources,
                       const std::string &image_id,
                       const std::string &image_new_name) {
   CephContext *cct((CephContext *)io_ctx.cct());
@@ -559,10 +566,10 @@ int Trash<I>::restore(librados::IoCtx &io_ctx, rbd_trash_image_source_t source,
     return r;
   }
 
-  if (trash_spec.source !=  static_cast<cls::rbd::TrashImageSource>(source)) {
-    lderr(cct) << "Current trash source: " << trash_spec.source
-               << " does not match expected: "
-               << static_cast<cls::rbd::TrashImageSource>(source) << dendl;
+  if (trash_image_sources.count(trash_spec.source) == 0) {
+    lderr(cct) << "Current trash source '" << trash_spec.source << "' "
+               << "does not match expected: "
+               << trash_image_sources << dendl;
     return -EINVAL;
   }
 
index 6122bd9459c6b9dbb4c03e4d7929b91c59bc8190..65b6b8bc4fda166e2335931bd7e874a495cefd3a 100644 (file)
@@ -6,6 +6,8 @@
 
 #include "include/rados/librados_fwd.hpp"
 #include "include/rbd/librbd.hpp"
+#include "cls/rbd/cls_rbd_types.h"
+#include <set>
 #include <string>
 #include <vector>
 
@@ -19,6 +21,8 @@ namespace api {
 
 template <typename ImageCtxT = librbd::ImageCtx>
 struct Trash {
+  typedef std::set<cls::rbd::TrashImageSource> TrashImageSources;
+  static const TrashImageSources RESTORE_SOURCE_WHITELIST;
 
   static int move(librados::IoCtx &io_ctx, rbd_trash_image_source_t source,
                   const std::string &image_name, uint64_t delay);
@@ -34,7 +38,8 @@ struct Trash {
                    float threshold, ProgressContext& pctx);
   static int remove(librados::IoCtx &io_ctx, const std::string &image_id,
                     bool force, ProgressContext& prog_ctx);
-  static int restore(librados::IoCtx &io_ctx, rbd_trash_image_source_t source,
+  static int restore(librados::IoCtx &io_ctx,
+                     const TrashImageSources& trash_image_sources,
                      const std::string &image_id,
                      const std::string &image_new_name);
 
index 605fe133239288c8c28c83241e8d7b23a389ed67..09019012cbad1c4f21ac6a9c3210da65c7b9d16f 100644 (file)
@@ -643,8 +643,8 @@ namespace librbd {
     TracepointProvider::initialize<tracepoint_traits>(get_cct(io_ctx));
     tracepoint(librbd, trash_undelete_enter, io_ctx.get_pool_name().c_str(),
                io_ctx.get_id(), id, name);
-    int r = librbd::api::Trash<>::restore(io_ctx, RBD_TRASH_IMAGE_SOURCE_USER,
-                                          id, name);
+    int r = librbd::api::Trash<>::restore(
+      io_ctx, librbd::api::Trash<>::RESTORE_SOURCE_WHITELIST, id, name);
     tracepoint(librbd, trash_undelete_exit, r);
     return r;
   }
@@ -3298,8 +3298,8 @@ extern "C" int rbd_trash_restore(rados_ioctx_t p, const char *id,
   TracepointProvider::initialize<tracepoint_traits>(get_cct(io_ctx));
   tracepoint(librbd, trash_undelete_enter, io_ctx.get_pool_name().c_str(),
              io_ctx.get_id(), id, name);
-  int r = librbd::api::Trash<>::restore(io_ctx, RBD_TRASH_IMAGE_SOURCE_USER,
-                                        id, name);
+  int r = librbd::api::Trash<>::restore(
+      io_ctx, librbd::api::Trash<>::RESTORE_SOURCE_WHITELIST, id, name);
   tracepoint(librbd, trash_undelete_exit, r);
   return r;
 }
index 0202ed278b9445d4c1d941537ec9729765966818..b477082796a342191499fb0abb4f396647277991 100644 (file)
@@ -89,4 +89,20 @@ TEST_F(TestTrash, UserRemovingSource) {
   ASSERT_EQ(expected_images, images);
 }
 
+TEST_F(TestTrash, RestoreMirroringSource) {
+  REQUIRE_FORMAT_V2();
+
+  librbd::RBD rbd;
+  librbd::Image image;
+  std::string image_id;
+  ASSERT_EQ(0, rbd.open(m_ioctx, image, m_image_name.c_str()));
+  ASSERT_EQ(0, image.get_id(&image_id));
+  ASSERT_EQ(0, image.close());
+
+  ASSERT_EQ(0, api::Trash<>::move(m_ioctx, RBD_TRASH_IMAGE_SOURCE_MIRRORING,
+                                  m_image_name, 0));
+  ASSERT_EQ(0, rbd.trash_restore(m_ioctx, image_id.c_str(),
+                                 m_image_name.c_str()));
+}
+
 } // namespace librbd