From 145ecb15c2b6b240a4abb5a0d81d081efeb98614 Mon Sep 17 00:00:00 2001 From: weixinwei Date: Tue, 15 Nov 2022 15:31:06 +0800 Subject: [PATCH] librbd: avoid EUCLEAN error after "rbd rm" is interrupted If "rbd rm" command is interrupted (e.g. killed), the image in the trash stays in cls::rbd::TRASH_IMAGE_STATE_MOVING state. Later, when "rbd rm" command is rerun, EUCLEAN error is returned. Fixes: https://tracker.ceph.com/issues/58060 Signed-off-by: weixinwei --- src/librbd/api/Image.cc | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/librbd/api/Image.cc b/src/librbd/api/Image.cc index 7f18ee58314..d9d008f6ace 100644 --- a/src/librbd/api/Image.cc +++ b/src/librbd/api/Image.cc @@ -787,12 +787,24 @@ int Image::remove(IoCtx& io_ctx, const std::string &image_name, r = Trash::list(io_ctx, trash_entries, false); if (r < 0) { return r; - } else if (r >= 0) { - for (auto& entry : trash_entries) { - if (entry.name == image_name && - entry.source == RBD_TRASH_IMAGE_SOURCE_REMOVING) { - return Trash::remove(io_ctx, entry.id, true, prog_ctx); + } + for (auto& entry : trash_entries) { + if (entry.name == image_name && + entry.source == RBD_TRASH_IMAGE_SOURCE_REMOVING) { + cls::rbd::TrashImageSpec spec; + r = cls_client::trash_get(&io_ctx, entry.id, &spec); + if (r < 0) { + lderr(cct) << "error getting image id " << entry.id + << " info from trash: " << cpp_strerror(r) << dendl; + return r; + } + if (spec.state == cls::rbd::TRASH_IMAGE_STATE_MOVING) { + r = Trash::move(io_ctx, entry.source, entry.name, entry.id, 0); + if (r < 0) { + return r; + } } + return Trash::remove(io_ctx, entry.id, true, prog_ctx); } } -- 2.39.5