From: songweibin Date: Thu, 3 Jan 2019 07:34:30 +0000 (+0800) Subject: librbd: disallow migrating when image has group/trash snapshot X-Git-Tag: v14.1.0~428^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=9c9dd1cfadc6cee352a10c0be82e9afddcd11afe;p=ceph.git librbd: disallow migrating when image has group/trash snapshot Fixes: Two potential problems with group/trash snapshot: (1) ENOENT is returned when retrieving the snapshot status; (2) if ignore ENOENT from (1) and allow migrating, it will failed too when removing src image in the `migration commit` step. So disallowing migration directly. ``` [swb@ ~/ceph/ceph-dev/build]$ rbd snap rm img1@snap1 Removing snap: 100% complete...done. [swb@ ~/ceph/ceph-dev/build]$ rbd snap ls -a img1 SNAPID NAME SIZE PROTECTED TIMESTAMP NAMESPACE 4 cfeca8c8-237e-4682-b0b8-2875fd17251d 10 MiB Thu Jan 3 15:58:59 2019 trash (snap1) [swb@ ~/ceph/ceph-dev/build]$ rbd migration prepare img1 m1 2019-01-03 16:00:09.374 7fa758b1d040 -1 librbd::Migration: list_snaps: failed retrieving snapshot status: (2) No such file or directory rbd: preparing migration failed: (2) No such file or directory ``` Signed-off-by: songweibin --- diff --git a/src/librbd/api/Migration.cc b/src/librbd/api/Migration.cc index 32c13df3786d..aad7c7394f15 100644 --- a/src/librbd/api/Migration.cc +++ b/src/librbd/api/Migration.cc @@ -14,6 +14,7 @@ #include "librbd/Utils.h" #include "librbd/api/Config.h" #include "librbd/api/Group.h" +#include "librbd/api/Snapshot.h" #include "librbd/api/Trash.h" #include "librbd/deep_copy/MetadataCopyRequest.h" #include "librbd/deep_copy/SnapshotCopyRequest.h" @@ -967,17 +968,32 @@ int Migration::list_snaps(std::vector *snapsptr) { } for (auto &snap : snaps) { - bool is_protected; - r = snap_is_protected(m_src_image_ctx, snap.name.c_str(), &is_protected); + librbd::snap_namespace_type_t namespace_type; + r = Snapshot::get_namespace_type(m_src_image_ctx, snap.id, &namespace_type); if (r < 0) { - lderr(m_cct) << "failed retrieving snapshot status: " << cpp_strerror(r) + lderr(m_cct) << "error getting snap namespace type: " << cpp_strerror(r) << dendl; return r; } - if (is_protected) { - lderr(m_cct) << "image has protected snapshot '" << snap.name << "'" + + if (namespace_type == RBD_SNAP_NAMESPACE_TYPE_GROUP || + namespace_type == RBD_SNAP_NAMESPACE_TYPE_TRASH) { + lderr(m_cct) << "image has group or trash snapshot '" << snap.name << "'" << dendl; return -EBUSY; + } else { + bool is_protected; + r = snap_is_protected(m_src_image_ctx, snap.name.c_str(), &is_protected); + if (r < 0) { + lderr(m_cct) << "failed retrieving snapshot status: " << cpp_strerror(r) + << dendl; + return r; + } + if (is_protected) { + lderr(m_cct) << "image has protected snapshot '" << snap.name << "'" + << dendl; + return -EBUSY; + } } }