]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rbd: import with option --export-format fails to protect snapshot 20613/head
authorsongweibin <song.weibin@zte.com.cn>
Tue, 27 Feb 2018 09:33:54 +0000 (17:33 +0800)
committersongweibin <song.weibin@zte.com.cn>
Thu, 1 Mar 2018 12:48:38 +0000 (20:48 +0800)
Fixes: http://tracker.ceph.com/issues/23038
Signed-off-by: songweibin <song.weibin@zte.com.cn>
doc/dev/rbd-export.rst
src/tools/rbd/Utils.h
src/tools/rbd/action/Export.cc
src/tools/rbd/action/Import.cc

index d009b79953ab4584e438fd63e672a6b363d9be0d..2edb637f6ef15539103842c0deff46b99388519c 100644 (file)
@@ -83,9 +83,21 @@ End
 
 
 Diffs records
-~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~
+
 Record the all snapshots and the HEAD in this section. 
 
+Snap Protection status
+----------------------
+
+Record the snapshot's protection status if `--export-format=2`.
+- u8: 'p'
+- le64: length of appending data (8)
+- u8: snap protection status (0 for false, 1 for true)
+
+Others
+------
+
 - le64: number of diffs
 - Diffs ...
 
index c265249fb3799201a060225e430fd1f611702007..28dc377005fea2b76b4a406dff70e0291a2ea703 100644 (file)
@@ -46,6 +46,8 @@ static const std::string RBD_DIFF_BANNER_V2 ("rbd diff v2\n");
 #define RBD_DIFF_ZERO          'z'
 #define RBD_DIFF_END           'e'
 
+#define RBD_SNAP_PROTECTION_STATUS     'p'
+
 #define RBD_EXPORT_IMAGE_ORDER         'O'
 #define RBD_EXPORT_IMAGE_FEATURES      'T'
 #define RBD_EXPORT_IMAGE_STRIPE_UNIT   'U'
index e8941f8460c34e1e7b3c55977cce1afe5761ece7..8c109e17dea80c372ad0688a91d0e15f3f910d5a 100644 (file)
@@ -156,12 +156,25 @@ int do_export_diff_fd(librbd::Image& image, const char *fromsnapname,
       encode(tag, bl);
       std::string to(endsnapname);
       if (export_format == 2) {
-       len = to.length() + 4;
-       encode(len, bl);
+        len = to.length() + 4;
+        encode(len, bl);
       }
       encode(to, bl);
     }
 
+    if (endsnapname && export_format == 2) {
+      tag = RBD_SNAP_PROTECTION_STATUS;
+      encode(tag, bl);
+      bool is_protected = false;
+      r = image.snap_is_protected(endsnapname, &is_protected);
+      if (r < 0) {
+        return r;
+      }
+      len = 8;
+      encode(len, bl);
+      encode(is_protected, bl);
+    }
+
     tag = RBD_DIFF_IMAGE_SIZE;
     encode(tag, bl);
     uint64_t endsize = info.size;
index ef843f94af8088f1d1c946a941ce0b121baf6e36..f727c17457b485d38d9a3ac9f644452d1e46af6a 100644 (file)
@@ -184,6 +184,21 @@ static int do_image_snap_to(ImportDiffContext *idiffctx, std::string *tosnap)
   return 0;
 }
 
+static int get_snap_protection_status(ImportDiffContext *idiffctx, bool *is_protected)
+{
+  int r;
+  char buf[sizeof(__u8)];
+  r = safe_read_exact(idiffctx->fd, buf, sizeof(buf));
+  if (r < 0) {
+    return r;
+  }
+
+  *is_protected = (buf[0] != 0);
+  idiffctx->update_progress();
+
+  return 0;
+}
+
 static int do_image_resize(ImportDiffContext *idiffctx)
 {
   int r;
@@ -371,6 +386,7 @@ int do_import_diff_fd(librados::Rados &rados, librbd::Image &image, int fd,
 
   // begin image import
   std::string tosnap;
+  bool is_protected = false;
   ImportDiffContext idiffctx(&image, fd, size, no_progress);
   while (r == 0) {
     __u8 tag;
@@ -385,6 +401,8 @@ int do_import_diff_fd(librados::Rados &rados, librbd::Image &image, int fd,
       r = do_image_snap_from(&idiffctx);
     } else if (tag == RBD_DIFF_TO_SNAP) {
       r = do_image_snap_to(&idiffctx, &tosnap);
+    } else if (tag == RBD_SNAP_PROTECTION_STATUS) {
+      r = get_snap_protection_status(&idiffctx, &is_protected);
     } else if (tag == RBD_DIFF_IMAGE_SIZE) {
       r = do_image_resize(&idiffctx);
     } else if (tag == RBD_DIFF_WRITE || tag == RBD_DIFF_ZERO) {
@@ -399,7 +417,10 @@ int do_import_diff_fd(librados::Rados &rados, librbd::Image &image, int fd,
   int temp_r = idiffctx.throttle.wait_for_ret();
   r = (r < 0) ? r : temp_r; // preserve original error
   if (r == 0 && tosnap.length()) {
-    idiffctx.image->snap_create(tosnap.c_str());
+    r = idiffctx.image->snap_create(tosnap.c_str());
+    if (r == 0 && is_protected) {
+      r = idiffctx.image->snap_protect(tosnap.c_str());
+    } 
   }
 
   idiffctx.finish(r);