From: Dongsheng Yang Date: Thu, 3 Nov 2016 06:34:10 +0000 (-0400) Subject: rbd: import: use read() instead of lseek() when from_stdin is true X-Git-Tag: v12.0.1~342^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=fedf772ba1e84a7ee0296177dcaba6f3c6ebe263;p=ceph.git rbd: import: use read() instead of lseek() when from_stdin is true Signed-off-by: Dongsheng Yang --- diff --git a/src/tools/rbd/action/Export.cc b/src/tools/rbd/action/Export.cc index f938590d3a28..485b0ad841da 100644 --- a/src/tools/rbd/action/Export.cc +++ b/src/tools/rbd/action/Export.cc @@ -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; diff --git a/src/tools/rbd/action/Import.cc b/src/tools/rbd/action/Import.cc index 0fa76f2f5c53..75c07c67d1aa 100644 --- a/src/tools/rbd/action/Import.cc +++ b/src/tools/rbd/action/Import.cc @@ -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; + } } } }