]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rbd: import_diff/export_diff: encode length for each tag.
authorDongsheng Yang <dongsheng.yang@easystack.cn>
Wed, 2 Nov 2016 08:30:00 +0000 (04:30 -0400)
committerDongsheng Yang <dongsheng.yang@easystack.cn>
Sun, 19 Feb 2017 12:42:03 +0000 (20:42 +0800)
Signed-off-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
src/tools/rbd/action/Export.cc
src/tools/rbd/action/Import.cc

index 771db32279c1eb058a484a54553b71aa3134581c..b09cca65dfdc07496fb57dc80a01f45604eea8cb 100644 (file)
@@ -21,13 +21,14 @@ namespace action {
 struct ExportDiffContext {
   librbd::Image *image;
   int fd;
+  int export_format;
   uint64_t totalsize;
   utils::ProgressContext pc;
   OrderedThrottle throttle;
 
   ExportDiffContext(librbd::Image *i, int f, uint64_t t, int max_ops,
-                    bool no_progress) :
-    image(i), fd(f), totalsize(t), pc("Exporting image", no_progress),
+                    bool no_progress, int eformat) :
+    image(i), fd(f), export_format(eformat), totalsize(t), pc("Exporting image", no_progress),
     throttle(max_ops, true) {
   }
 };
@@ -35,9 +36,9 @@ struct ExportDiffContext {
 class C_ExportDiff : public Context {
 public:
   C_ExportDiff(ExportDiffContext *edc, uint64_t offset, uint64_t length,
-               bool exists)
+               bool exists, int export_format)
     : m_export_diff_context(edc), m_offset(offset), m_length(length),
-      m_exists(exists) {
+      m_exists(exists), m_export_format(export_format) {
   }
 
   int send() {
@@ -64,10 +65,10 @@ public:
   }
 
   static int export_diff_cb(uint64_t offset, size_t length, int exists,
-                            void *arg) {
+                           void *arg) {
     ExportDiffContext *edc = reinterpret_cast<ExportDiffContext *>(arg);
 
-    C_ExportDiff *context = new C_ExportDiff(edc, offset, length, exists);
+    C_ExportDiff *context = new C_ExportDiff(edc, offset, length, exists, edc->export_format);
     return context->send();
   }
 
@@ -77,7 +78,7 @@ protected:
       if (m_exists) {
         m_exists = !m_read_data.is_zero();
       }
-      r = write_extent(m_export_diff_context, m_offset, m_length, m_exists);
+      r = write_extent(m_export_diff_context, m_offset, m_length, m_exists, m_export_format);
       if (r == 0 && m_exists) {
         r = m_read_data.write_fd(m_export_diff_context->fd);
       }
@@ -90,14 +91,23 @@ private:
   uint64_t m_offset;
   uint64_t m_length;
   bool m_exists;
+  int m_export_format;
   bufferlist m_read_data;
 
   static int write_extent(ExportDiffContext *edc, uint64_t offset,
-                          uint64_t length, bool exists) {
+                          uint64_t length, bool exists, int export_format) {
     // extent
     bufferlist bl;
     __u8 tag = exists ? RBD_DIFF_WRITE : RBD_DIFF_ZERO;
+    uint64_t len = 0;
     ::encode(tag, bl);
+    if (export_format == 2) {
+      if (tag == RBD_DIFF_WRITE)
+       len = 8 + 8 + length;
+      else
+       len = 8 + 8;
+      ::encode(len, bl);
+    }
     ::encode(offset, bl);
     ::encode(length, bl);
     int r = bl.write_fd(edc->fd);
@@ -128,10 +138,15 @@ int do_export_diff_fd(librbd::Image& image, const char *fromsnapname,
       bl.append(utils::RBD_DIFF_BANNER_V2);
 
     __u8 tag;
+    uint64_t len = 0;
     if (fromsnapname) {
       tag = RBD_DIFF_FROM_SNAP;
       ::encode(tag, bl);
       std::string from(fromsnapname);
+      if (export_format == 2) {
+       len = from.length() + 4;
+       ::encode(len, bl);
+      }
       ::encode(from, bl);
     }
 
@@ -139,12 +154,20 @@ int do_export_diff_fd(librbd::Image& image, const char *fromsnapname,
       tag = RBD_DIFF_TO_SNAP;
       ::encode(tag, bl);
       std::string to(endsnapname);
+      if (export_format == 2) {
+       len = to.length() + 4;
+       ::encode(len, bl);
+      }
       ::encode(to, bl);
     }
 
     tag = RBD_DIFF_IMAGE_SIZE;
     ::encode(tag, bl);
     uint64_t endsize = info.size;
+    if (export_format == 2) {
+      len = 8;
+      ::encode(len, bl);
+    }
     ::encode(endsize, bl);
 
     r = bl.write_fd(fd);
@@ -153,7 +176,8 @@ int do_export_diff_fd(librbd::Image& image, const char *fromsnapname,
     }
   }
   ExportDiffContext edc(&image, fd, info.size,
-                        g_conf->rbd_concurrent_management_ops, no_progress);
+                        g_conf->rbd_concurrent_management_ops, no_progress,
+                       export_format);
   r = image.diff_iterate2(fromsnapname, 0, info.size, true, whole_object,
                           &C_ExportDiff::export_diff_cb, (void *)&edc);
   if (r < 0) {
index 8dac188aebb68d77e964999259ac35336f115845..42bbc87409fe83427fc62516a90143de9b3d0640 100644 (file)
@@ -53,6 +53,7 @@ int do_import_diff_fd(librbd::Image &image, int fd,
 
   while (true) {
     __u8 tag;
+    uint64_t length = 0;
     r = safe_read_exact(fd, &tag, 1);
     if (r < 0) {
       goto done;
@@ -60,85 +61,98 @@ int do_import_diff_fd(librbd::Image &image, int fd,
 
     if (tag == RBD_DIFF_END) {
       break;
-    } else if (tag == RBD_DIFF_FROM_SNAP) {
-      r = utils::read_string(fd, 4096, &from);   // 4k limit to make sure we don't get a garbage string
-      if (r < 0)
-       goto done;
-
-      bool exists; 
-      r = image.snap_exists2(from.c_str(), &exists);
-      if (r < 0)
-       goto done;
-
-      if (!exists) {
-       std::cerr << "start snapshot '" << from
-                 << "' does not exist in the image, aborting" << std::endl;
-       r = -EINVAL;
-       goto done;
-      }
-    }
-    else if (tag == RBD_DIFF_TO_SNAP) {
-      r = utils::read_string(fd, 4096, &to);   // 4k limit to make sure we don't get a garbage string
-      if (r < 0)
-       goto done;
-
-      // verify this snap isn't already present
-      bool exists;
-      r = image.snap_exists2(to.c_str(), &exists);
-      if (r < 0)
-       goto done;
-      
-      if (exists) {
-       std::cerr << "end snapshot '" << to
-                 << "' already exists, aborting" << std::endl;
-       r = -EEXIST;
-       goto done;
+    } else {
+      if (format == 2) {
+       r = safe_read_exact(fd, &length, 8);
+       if (r < 0) {
+         return r;
+       }
       }
-    } else if (tag == RBD_DIFF_IMAGE_SIZE) {
-      uint64_t end_size;
-      char buf[8];
-      r = safe_read_exact(fd, buf, 8);
-      if (r < 0)
-       goto done;
-      bufferlist bl;
-      bl.append(buf, 8);
-      bufferlist::iterator p = bl.begin();
-      ::decode(end_size, p);
-      uint64_t cur_size;
-      image.size(&cur_size);
-      if (cur_size != end_size) {
-       image.resize(end_size);
+
+      if (tag == RBD_DIFF_FROM_SNAP) {
+       r = utils::read_string(fd, 4096, &from);   // 4k limit to make sure we don't get a garbage string
+       if (r < 0)
+         goto done;
+
+       bool exists; 
+       r = image.snap_exists2(from.c_str(), &exists);
+       if (r < 0)
+         goto done;
+
+       if (!exists) {
+         std::cerr << "start snapshot '" << from
+                   << "' does not exist in the image, aborting" << std::endl;
+         r = -EINVAL;
+         goto done;
+       }
       }
-      if (from_stdin)
-       size = end_size;
-    } else if (tag == RBD_DIFF_WRITE || tag == RBD_DIFF_ZERO) {
-      uint64_t len;
-      char buf[16];
-      r = safe_read_exact(fd, buf, 16);
-      if (r < 0)
-       goto done;
-      bufferlist bl;
-      bl.append(buf, 16);
-      bufferlist::iterator p = bl.begin();
-      ::decode(off, p);
-      ::decode(len, p);
-
-      if (tag == RBD_DIFF_WRITE) {
-       bufferptr bp = buffer::create(len);
-       r = safe_read_exact(fd, bp.c_str(), len);
+      else if (tag == RBD_DIFF_TO_SNAP) {
+       r = utils::read_string(fd, 4096, &to);   // 4k limit to make sure we don't get a garbage string
        if (r < 0)
          goto done;
-       bufferlist data;
-       data.append(bp);
-       image.write2(off, len, data, LIBRADOS_OP_FLAG_FADVISE_NOCACHE);
+
+       // verify this snap isn't already present
+       bool exists;
+       r = image.snap_exists2(to.c_str(), &exists);
+       if (r < 0)
+         goto done;
+       
+       if (exists) {
+         std::cerr << "end snapshot '" << to
+                   << "' already exists, aborting" << std::endl;
+         r = -EEXIST;
+         goto done;
+       }
+      } else if (tag == RBD_DIFF_IMAGE_SIZE) {
+       uint64_t end_size;
+       char buf[8];
+       r = safe_read_exact(fd, buf, 8);
+       if (r < 0)
+         goto done;
+       bufferlist bl;
+       bl.append(buf, 8);
+       bufferlist::iterator p = bl.begin();
+       ::decode(end_size, p);
+       uint64_t cur_size;
+       image.size(&cur_size);
+       if (cur_size != end_size) {
+         image.resize(end_size);
+       }
+       if (from_stdin)
+         size = end_size;
+      } else if (tag == RBD_DIFF_WRITE || tag == RBD_DIFF_ZERO) {
+       uint64_t len;
+       char buf[16];
+       r = safe_read_exact(fd, buf, 16);
+       if (r < 0)
+         goto done;
+       bufferlist bl;
+       bl.append(buf, 16);
+       bufferlist::iterator p = bl.begin();
+       ::decode(off, p);
+       ::decode(len, p);
+
+       if (tag == RBD_DIFF_WRITE) {
+         bufferptr bp = buffer::create(len);
+         r = safe_read_exact(fd, bp.c_str(), len);
+         if (r < 0)
+           goto done;
+         bufferlist data;
+         data.append(bp);
+         image.write2(off, len, data, LIBRADOS_OP_FLAG_FADVISE_NOCACHE);
+       } else {
+         image.discard(off, len);
+       }
       } else {
-       image.discard(off, len);
+       std::cerr << "unrecognized tag byte " << (int)tag
+                 << " in stream; aborting" << std::endl;
+       if (format == 2) {
+         ::lseek(fd, length, SEEK_CUR);
+       } else {
+         r = -EINVAL;
+         goto done;
+       }
       }
-    } else {
-      std::cerr << "unrecognized tag byte " << (int)tag
-               << " in stream; aborting" << std::endl;
-      r = -EINVAL;
-      goto done;
     }
     if (!from_stdin) {
       // progress through input