From: Dongsheng Yang Date: Tue, 11 Oct 2016 11:18:07 +0000 (-0400) Subject: rbd: refactor do_import_diff to accept fd. X-Git-Tag: v12.0.1~342^2~15 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=58c8e8cd00bda7c40fafbd93e7da0436c100a872;p=ceph.git rbd: refactor do_import_diff to accept fd. Signed-off-by: Dongsheng Yang --- diff --git a/src/tools/rbd/action/Import.cc b/src/tools/rbd/action/Import.cc index d1e1ac0528a4..9d039f1cec1b 100644 --- a/src/tools/rbd/action/Import.cc +++ b/src/tools/rbd/action/Import.cc @@ -20,10 +20,10 @@ namespace rbd { namespace action { -int do_import_diff(librbd::Image &image, const char *path, - bool no_progress) +int do_import_diff_fd(librbd::Image &image, int fd, + bool no_progress) { - int fd, r; + int r; struct stat stat_buf; utils::ProgressContext pc("Importing image diff", no_progress); uint64_t size = 0; @@ -31,16 +31,8 @@ int do_import_diff(librbd::Image &image, const char *path, string from, to; char buf[utils::RBD_DIFF_BANNER.size() + 1]; - bool from_stdin = !strcmp(path, "-"); - if (from_stdin) { - fd = 0; - } else { - fd = open(path, O_RDONLY); - if (fd < 0) { - r = -errno; - std::cerr << "rbd: error opening " << path << std::endl; - return r; - } + bool from_stdin = (fd == 0); + if (!from_stdin) { r = ::fstat(fd, &stat_buf); if (r < 0) goto done; @@ -53,7 +45,7 @@ int do_import_diff(librbd::Image &image, const char *path, buf[utils::RBD_DIFF_BANNER.size()] = '\0'; if (strcmp(buf, utils::RBD_DIFF_BANNER.c_str())) { std::cerr << "invalid banner '" << buf << "', expected '" - << utils::RBD_DIFF_BANNER << "'" << std::endl; + << utils::RBD_DIFF_BANNER << "'" << std::endl; r = -EINVAL; goto done; } @@ -70,43 +62,43 @@ int do_import_diff(librbd::Image &image, const char *path, } 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; + goto done; bool exists; r = image.snap_exists2(from.c_str(), &exists); if (r < 0) - goto done; + goto done; if (!exists) { - std::cerr << "start snapshot '" << from - << "' does not exist in the image, aborting" << std::endl; - r = -EINVAL; - goto done; + 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; + goto done; // verify this snap isn't already present bool exists; r = image.snap_exists2(to.c_str(), &exists); if (r < 0) - goto done; + goto done; if (exists) { - std::cerr << "end snapshot '" << to - << "' already exists, aborting" << std::endl; - r = -EEXIST; - goto done; + 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; + goto done; bufferlist bl; bl.append(buf, 8); bufferlist::iterator p = bl.begin(); @@ -114,17 +106,16 @@ int do_import_diff(librbd::Image &image, const char *path, uint64_t cur_size; image.size(&cur_size); if (cur_size != end_size) { - image.resize(end_size); - } else { + image.resize(end_size); } if (from_stdin) - size = end_size; + 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; + goto done; bufferlist bl; bl.append(buf, 16); bufferlist::iterator p = bl.begin(); @@ -132,19 +123,19 @@ int do_import_diff(librbd::Image &image, const char *path, ::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); + 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); + image.discard(off, len); } } else { std::cerr << "unrecognized tag byte " << (int)tag - << " in stream; aborting" << std::endl; + << " in stream; aborting" << std::endl; r = -EINVAL; goto done; } @@ -163,12 +154,33 @@ int do_import_diff(librbd::Image &image, const char *path, r = image.snap_create(to.c_str()); } - done: +done: if (r < 0) pc.fail(); else pc.finish(); - if (!from_stdin) + return r; +} + +int do_import_diff(librbd::Image &image, const char *path, + bool no_progress) +{ + int r; + int fd; + + if (strcmp(path, "-") == 0) { + fd = 0; + } else { + fd = open(path, O_RDONLY); + if (fd < 0) { + r = -errno; + std::cerr << "rbd: error opening " << path << std::endl; + return r; + } + } + r = do_import_diff_fd(image, fd, no_progress); + + if (fd != 0) close(fd); return r; }