From 0ef0f43da9d112c54e3f17ed786d7197f920b8a2 Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Wed, 11 Sep 2019 14:07:23 -0400 Subject: [PATCH] librbd: allow mirroring trash images to be restored This functionality was accidentally broken when image live-migration was introduced. Signed-off-by: Jason Dillaman --- src/librbd/api/Image.cc | 3 ++- src/librbd/api/Migration.cc | 3 ++- src/librbd/api/Trash.cc | 18 +++++++++++++----- src/librbd/api/Trash.h | 7 ++++++- src/librbd/librbd.cc | 8 ++++---- src/test/librbd/test_Trash.cc | 16 ++++++++++++++++ 6 files changed, 43 insertions(+), 12 deletions(-) diff --git a/src/librbd/api/Image.cc b/src/librbd/api/Image.cc index 9fc65b5b529c..ebaaa9e2c2db 100644 --- a/src/librbd/api/Image.cc +++ b/src/librbd/api/Image.cc @@ -807,7 +807,8 @@ int Image::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::restore(io_ctx, trash_image_source, image_id, image_name); + Trash::restore(io_ctx, {cls::rbd::TRASH_IMAGE_SOURCE_REMOVING}, + image_id, image_name); } } return r; diff --git a/src/librbd/api/Migration.cc b/src/librbd/api/Migration.cc index b77039e70971..12a2d9f9b12b 100644 --- a/src/librbd/api/Migration.cc +++ b/src/librbd/api/Migration.cc @@ -1174,7 +1174,8 @@ template int Migration::v2_relink_src_image() { ldout(m_cct, 10) << dendl; - int r = Trash::restore(m_src_io_ctx, RBD_TRASH_IMAGE_SOURCE_MIGRATION, + int r = Trash::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) diff --git a/src/librbd/api/Trash.cc b/src/librbd/api/Trash.cc index c384d534f7d0..1f76b34bdede 100644 --- a/src/librbd/api/Trash.cc +++ b/src/librbd/api/Trash.cc @@ -31,6 +31,13 @@ namespace librbd { namespace api { +template +const typename Trash::TrashImageSources Trash::RESTORE_SOURCE_WHITELIST { + cls::rbd::TRASH_IMAGE_SOURCE_USER, + cls::rbd::TRASH_IMAGE_SOURCE_MIRRORING, + cls::rbd::TRASH_IMAGE_SOURCE_USER_PARENT + }; + namespace { template @@ -545,7 +552,8 @@ int Trash::remove(IoCtx &io_ctx, const std::string &image_id, bool force, } template -int Trash::restore(librados::IoCtx &io_ctx, rbd_trash_image_source_t source, +int Trash::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()); @@ -560,10 +568,10 @@ int Trash::restore(librados::IoCtx &io_ctx, rbd_trash_image_source_t source, return r; } - if (trash_spec.source != static_cast(source)) { - lderr(cct) << "Current trash source: " << trash_spec.source - << " does not match expected: " - << static_cast(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; } diff --git a/src/librbd/api/Trash.h b/src/librbd/api/Trash.h index 6122bd9459c6..65b6b8bc4fda 100644 --- a/src/librbd/api/Trash.h +++ b/src/librbd/api/Trash.h @@ -6,6 +6,8 @@ #include "include/rados/librados_fwd.hpp" #include "include/rbd/librbd.hpp" +#include "cls/rbd/cls_rbd_types.h" +#include #include #include @@ -19,6 +21,8 @@ namespace api { template struct Trash { + typedef std::set 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); diff --git a/src/librbd/librbd.cc b/src/librbd/librbd.cc index 58eb056b4936..3cc45bac04f6 100644 --- a/src/librbd/librbd.cc +++ b/src/librbd/librbd.cc @@ -669,8 +669,8 @@ namespace librbd { TracepointProvider::initialize(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; } @@ -3331,8 +3331,8 @@ extern "C" int rbd_trash_restore(rados_ioctx_t p, const char *id, TracepointProvider::initialize(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; } diff --git a/src/test/librbd/test_Trash.cc b/src/test/librbd/test_Trash.cc index 0202ed278b94..b477082796a3 100644 --- a/src/test/librbd/test_Trash.cc +++ b/src/test/librbd/test_Trash.cc @@ -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 -- 2.47.3