From: Jason Dillaman Date: Wed, 10 Mar 2021 20:15:26 +0000 (-0500) Subject: librbd/api: allow an interrupted trash move to be restarted X-Git-Tag: v17.1.0~2635^2~3 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=ed2d696e1eafaa59d29ce6fac952e4e5f4f1e920;p=ceph.git librbd/api: allow an interrupted trash move to be restarted Search the trash entries for a matching image name that is still in the moving state and allow the operation to be restarted. Signed-off-by: Jason Dillaman --- diff --git a/src/librbd/api/Trash.cc b/src/librbd/api/Trash.cc index 0d8496e62e788..6869d5a84a1c1 100644 --- a/src/librbd/api/Trash.cc +++ b/src/librbd/api/Trash.cc @@ -25,6 +25,7 @@ #include #include "librbd/journal/DisabledPolicy.h" #include "librbd/image/ListWatchersRequest.h" +#include #define dout_subsys ceph_subsys_rbd #undef dout_prefix @@ -288,15 +289,37 @@ int Trash::move(librados::IoCtx &io_ctx, rbd_trash_image_source_t source, return -EOPNOTSUPP; } - // image doesn't exist -- perhaps already in the trash since removing - // from the directory is the last step - return -ENOENT; + // search for an interrupted trash move request + std::map trash_image_specs; + int r = list_trash_image_specs(io_ctx, &trash_image_specs, true); + if (r < 0) { + return r; + } + + std::experimental::erase_if( + trash_image_specs, [image_name](const auto& pair) { + const auto& spec = pair.second; + return (spec.source != cls::rbd::TRASH_IMAGE_SOURCE_USER || + spec.state != cls::rbd::TRASH_IMAGE_STATE_MOVING || + spec.name != image_name); + }); + if (trash_image_specs.empty()) { + return -ENOENT; + } + + image_id = trash_image_specs.begin()->first; + ldout(cct, 15) << "derived image id " << image_id << " from existing " + << "trash entry" << dendl; } else if (r < 0) { lderr(cct) << "failed to retrieve image id: " << cpp_strerror(r) << dendl; return r; } - ceph_assert(!image_name.empty() && !image_id.empty()); + if (image_name.empty() || image_id.empty()) { + lderr(cct) << "invalid image name/id" << dendl; + return -EINVAL; + } + return Trash::move(io_ctx, source, image_name, image_id, delay); }