From f6192de7af8f21af207bc8a9ca6b74234c7f8314 Mon Sep 17 00:00:00 2001 From: Dongsheng Yang Date: Tue, 11 Oct 2016 05:15:02 -0400 Subject: [PATCH] rbd: squash ImportDiff.cc into Import.cc. Signed-off-by: Dongsheng Yang --- src/tools/rbd/CMakeLists.txt | 1 - src/tools/rbd/action/Import.cc | 212 ++++++++++++++++++++++++++ src/tools/rbd/action/ImportDiff.cc | 235 ----------------------------- 3 files changed, 212 insertions(+), 236 deletions(-) delete mode 100644 src/tools/rbd/action/ImportDiff.cc diff --git a/src/tools/rbd/CMakeLists.txt b/src/tools/rbd/CMakeLists.txt index 645795fe0d8..2a265329aae 100644 --- a/src/tools/rbd/CMakeLists.txt +++ b/src/tools/rbd/CMakeLists.txt @@ -18,7 +18,6 @@ set(rbd_srcs action/Group.cc action/ImageMeta.cc action/Import.cc - action/ImportDiff.cc action/Info.cc action/Journal.cc action/Kernel.cc diff --git a/src/tools/rbd/action/Import.cc b/src/tools/rbd/action/Import.cc index 0a01411de93..237bb88424d 100644 --- a/src/tools/rbd/action/Import.cc +++ b/src/tools/rbd/action/Import.cc @@ -8,12 +8,224 @@ #include "common/blkdev.h" #include "common/errno.h" #include "common/Throttle.h" +#include "include/compat.h" +#include "include/encoding.h" +#include "common/debug.h" +#include "common/errno.h" +#include "common/safe_io.h" #include #include #include namespace rbd { namespace action { +namespace import_diff { + +namespace at = argument_types; +namespace po = boost::program_options; + +static int do_import_diff(librbd::Image &image, const char *path, + bool no_progress) +{ + int fd, r; + struct stat stat_buf; + utils::ProgressContext pc("Importing image diff", no_progress); + uint64_t size = 0; + uint64_t off = 0; + 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; + } + r = ::fstat(fd, &stat_buf); + if (r < 0) + goto done; + size = (uint64_t)stat_buf.st_size; + } + + r = safe_read_exact(fd, buf, utils::RBD_DIFF_BANNER.size()); + if (r < 0) + goto done; + 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; + r = -EINVAL; + goto done; + } + + while (true) { + __u8 tag; + r = safe_read_exact(fd, &tag, 1); + if (r < 0) { + goto done; + } + + 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 (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); + } else { + } + 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 { + std::cerr << "unrecognized tag byte " << (int)tag + << " in stream; aborting" << std::endl; + r = -EINVAL; + goto done; + } + if (!from_stdin) { + // progress through input + uint64_t off = lseek64(fd, 0, SEEK_CUR); + pc.update_progress(off, size); + } else if (size) { + // progress through image offsets. this may jitter if blocks + // aren't in order, but it is better than nothing. + pc.update_progress(off, size); + } + } + // take final snap + if (to.length()) { + r = image.snap_create(to.c_str()); + } + + done: + if (r < 0) + pc.fail(); + else + pc.finish(); + if (!from_stdin) + close(fd); + return r; +} + +void get_arguments(po::options_description *positional, + po::options_description *options) { + at::add_path_options(positional, options, + "import file (or '-' for stdin)"); + at::add_image_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE); + at::add_no_progress_option(options); +} + +int execute(const po::variables_map &vm) { + std::string path; + int r = utils::get_path(vm, utils::get_positional_argument(vm, 0), &path); + if (r < 0) { + return r; + } + + size_t arg_index = 1; + std::string pool_name; + std::string image_name; + std::string snap_name; + r = utils::get_pool_image_snapshot_names( + vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name, + &snap_name, utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_NONE); + if (r < 0) { + return r; + } + + librados::Rados rados; + librados::IoCtx io_ctx; + librbd::Image image; + r = utils::init_and_open_image(pool_name, image_name, "", false, + &rados, &io_ctx, &image); + if (r < 0) { + return r; + } + + r = do_import_diff(image, path.c_str(), vm[at::NO_PROGRESS].as()); + if (r < 0) { + cerr << "rbd: import-diff failed: " << cpp_strerror(r) << std::endl; + return r; + } + return 0; +} + +Shell::Action action( + {"import-diff"}, {}, "Import an incremental diff.", "", &get_arguments, + &execute); + +} // namespace import_diff + namespace import { namespace at = argument_types; diff --git a/src/tools/rbd/action/ImportDiff.cc b/src/tools/rbd/action/ImportDiff.cc deleted file mode 100644 index c9a6b5ee117..00000000000 --- a/src/tools/rbd/action/ImportDiff.cc +++ /dev/null @@ -1,235 +0,0 @@ -// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- -// vim: ts=8 sw=2 smarttab - -#include "include/compat.h" -#include "tools/rbd/ArgumentTypes.h" -#include "tools/rbd/Shell.h" -#include "tools/rbd/Utils.h" -#include "include/encoding.h" -#include "common/debug.h" -#include "common/errno.h" -#include "common/safe_io.h" -#include -#include - -#define dout_context g_ceph_context -#define dout_subsys ceph_subsys_rbd - -namespace rbd { -namespace action { -namespace import_diff { - -namespace at = argument_types; -namespace po = boost::program_options; - -static int do_import_diff(librbd::Image &image, const char *path, - bool no_progress) -{ - int fd, r; - struct stat stat_buf; - utils::ProgressContext pc("Importing image diff", no_progress); - uint64_t size = 0; - uint64_t off = 0; - 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; - } - r = ::fstat(fd, &stat_buf); - if (r < 0) - goto done; - size = (uint64_t)stat_buf.st_size; - } - - r = safe_read_exact(fd, buf, utils::RBD_DIFF_BANNER.size()); - if (r < 0) - goto done; - 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; - r = -EINVAL; - goto done; - } - - while (true) { - __u8 tag; - r = safe_read_exact(fd, &tag, 1); - if (r < 0) { - goto done; - } - - if (tag == RBD_DIFF_END) { - dout(2) << " end diff" << dendl; - 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; - dout(2) << " from snap " << from << dendl; - - 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; - dout(2) << " to snap " << to << dendl; - - // 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) { - dout(2) << "resize " << cur_size << " -> " << end_size << dendl; - image.resize(end_size); - } else { - dout(2) << "size " << end_size << " (no change)" << dendl; - } - 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); - dout(2) << " write " << off << "~" << len << dendl; - image.write2(off, len, data, LIBRADOS_OP_FLAG_FADVISE_NOCACHE); - } else { - dout(2) << " zero " << off << "~" << len << dendl; - image.discard(off, len); - } - } else { - std::cerr << "unrecognized tag byte " << (int)tag - << " in stream; aborting" << std::endl; - r = -EINVAL; - goto done; - } - if (!from_stdin) { - // progress through input - uint64_t off = lseek64(fd, 0, SEEK_CUR); - pc.update_progress(off, size); - } else if (size) { - // progress through image offsets. this may jitter if blocks - // aren't in order, but it is better than nothing. - pc.update_progress(off, size); - } - } - // take final snap - if (to.length()) { - dout(2) << " create end snap " << to << dendl; - r = image.snap_create(to.c_str()); - } - - done: - if (r < 0) - pc.fail(); - else - pc.finish(); - if (!from_stdin) - close(fd); - return r; -} - -void get_arguments(po::options_description *positional, - po::options_description *options) { - at::add_path_options(positional, options, - "import file (or '-' for stdin)"); - at::add_image_spec_options(positional, options, at::ARGUMENT_MODIFIER_NONE); - at::add_no_progress_option(options); -} - -int execute(const po::variables_map &vm) { - std::string path; - int r = utils::get_path(vm, utils::get_positional_argument(vm, 0), &path); - if (r < 0) { - return r; - } - - size_t arg_index = 1; - std::string pool_name; - std::string image_name; - std::string snap_name; - r = utils::get_pool_image_snapshot_names( - vm, at::ARGUMENT_MODIFIER_NONE, &arg_index, &pool_name, &image_name, - &snap_name, utils::SNAPSHOT_PRESENCE_NONE, utils::SPEC_VALIDATION_NONE); - if (r < 0) { - return r; - } - - librados::Rados rados; - librados::IoCtx io_ctx; - librbd::Image image; - r = utils::init_and_open_image(pool_name, image_name, "", false, - &rados, &io_ctx, &image); - if (r < 0) { - return r; - } - - r = do_import_diff(image, path.c_str(), vm[at::NO_PROGRESS].as()); - if (r < 0) { - cerr << "rbd: import-diff failed: " << cpp_strerror(r) << std::endl; - return r; - } - return 0; -} - -Shell::Action action( - {"import-diff"}, {}, "Import an incremental diff.", "", &get_arguments, - &execute); - -} // namespace import_diff -} // namespace action -} // namespace rbd -- 2.39.5