]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: disallow migrating when image has group/trash snapshot
authorsongweibin <song.weibin@zte.com.cn>
Thu, 3 Jan 2019 07:34:30 +0000 (15:34 +0800)
committersongweibin <song.weibin@zte.com.cn>
Thu, 3 Jan 2019 08:39:00 +0000 (16:39 +0800)
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 <song.weibin@zte.com.cn>
src/librbd/api/Migration.cc

index 32c13df3786d9a52dfd4b1a916f41625b3f95246..aad7c7394f15e64abe1217862c3714d85eb97d25 100644 (file)
@@ -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<I>::list_snaps(std::vector<librbd::snap_info_t> *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<I>::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;
+      }
     }
   }