]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rbd: import: use read() instead of lseek() when from_stdin is true
authorDongsheng Yang <dongsheng.yang@easystack.cn>
Thu, 3 Nov 2016 06:34:10 +0000 (02:34 -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 f938590d3a2800abe247b2d5be68d03d8d5ab959..485b0ad841da07c27f8b4d4d41e23b69a21dfb95 100644 (file)
@@ -375,7 +375,6 @@ static int do_export_v2(librbd::Image& image, librbd::image_info_t &info, int fd
                        uint64_t period, int max_concurrent_ops, utils::ProgressContext &pc)
 {
   int r = 0;
-  size_t offset = 0;
   // header
   bufferlist bl;
   bl.append(utils::RBD_IMAGE_BANNER_V2);
@@ -424,9 +423,6 @@ static int do_export_v2(librbd::Image& image, librbd::image_info_t &info, int fd
   if (r < 0) {
     return r;
   }
-  offset += bl.length();
-
-  lseek(fd, offset, SEEK_SET);
 
   // header for snapshots
   bl.clear();
@@ -446,26 +442,22 @@ static int do_export_v2(librbd::Image& image, librbd::image_info_t &info, int fd
     return r;
   }
 
-  if (0 == diff_num) {
-    return r;
-  } else {
-    const char *last_snap = NULL;
-    for (size_t i = 0; i < snaps.size(); ++i) {
-      utils::snap_set(image, snaps[i].name.c_str());
-      r = do_export_diff_fd(image, last_snap, snaps[i].name.c_str(), false, fd, true, 2);
-      if (r < 0) {
-       return r;
-      }
-      pc.update_progress(i, snaps.size() + 1);
-      last_snap = snaps[i].name.c_str();
-    }
-    utils::snap_set(image, std::string(""));
-    r = do_export_diff_fd(image, last_snap, nullptr, false, fd, true, 2);
+  const char *last_snap = NULL;
+  for (size_t i = 0; i < snaps.size(); ++i) {
+    utils::snap_set(image, snaps[i].name.c_str());
+    r = do_export_diff_fd(image, last_snap, snaps[i].name.c_str(), false, fd, true, 2);
     if (r < 0) {
       return r;
     }
-    pc.update_progress(snaps.size() + 1, snaps.size() + 1);
+    pc.update_progress(i, snaps.size() + 1);
+    last_snap = snaps[i].name.c_str();
+  }
+  utils::snap_set(image, std::string(""));
+  r = do_export_diff_fd(image, last_snap, nullptr, false, fd, true, 2);
+  if (r < 0) {
+    return r;
   }
+  pc.update_progress(snaps.size() + 1, snaps.size() + 1);
   return r;
 }
 
@@ -492,7 +484,12 @@ static int do_export_v1(librbd::Image& image, librbd::image_info_t &info, int fd
   if (fd != 1) {
     if (r >= 0) {
       r = ftruncate(fd, file_size);
-      r = lseek(fd, file_size, SEEK_SET);
+      if (r < 0)
+       return r;
+
+      uint64_t chkret = lseek64(fd, file_size, SEEK_SET);
+      if (chkret != file_size)
+       r = errno;
     }
   }
   return r;
index 0fa76f2f5c53c10f9f8ee3aeb3312a0253c31bd2..75c07c67d1aa76afcacc1936de2ccf4827d25f1b 100644 (file)
@@ -152,11 +152,22 @@ int do_import_diff_fd(librbd::Image &image, int fd,
       } else {
        std::cerr << "unrecognized tag byte " << (int)tag
                  << " in stream; aborting" << std::endl;
-       if (format == 2) {
-         ::lseek(fd, length, SEEK_CUR);
+       if (from_stdin) {
+         char buf[4096];
+         uint64_t len = min(length, uint64_t(4096));
+         while (len > 0) {
+           r = safe_read_exact(fd, buf, len);
+           if (r < 0)
+             return r;
+           length -= len;
+           len = min(length, uint64_t(4096));
+         }
        } else {
-         r = -EINVAL;
-         goto done;
+         off64_t offs = lseek64(fd, length, SEEK_CUR);
+         if (offs < 0) {
+           r = -errno;
+           goto done;
+         }
        }
       }
     }
@@ -409,7 +420,23 @@ static int do_import_header(int fd, int import_format, uint64_t &size, librbd::I
        }
       } else {
        std::cerr << "rbd: invalid tag in image properties zone: " << tag << "Skip it." << std::endl;
-       ::lseek(fd, length, SEEK_CUR);
+       if (fd == STDIN_FILENO) {
+         // read the appending data out to skip this tag.
+         char buf[4096];
+         uint64_t len = min(length, uint64_t(4096));
+         while (len > 0) {
+           r = safe_read_exact(fd, buf, len);
+           if (r < 0)
+             return r;
+           length -= len;
+           len = min(length, uint64_t(4096));
+         }
+       } else {
+         // lseek to skip this tag
+         off64_t offs = lseek64(fd, length, SEEK_CUR);
+         if (offs < 0)
+           return -errno;
+       }
       }
     }
   }