rbd ls -l | grep clone2 | grep rbd2/clone@s1
rbd -p rbd2 ls | grep -v clone2
+ rbd clone rbd2/clone clone3 |& grep 'snapshot name was not specified'
+ rbd clone rbd2/clone@invalid clone3 |& grep 'failed to open parent image'
+ rbd clone rbd2/clone --snap-id 0 clone3 |& grep 'failed to open parent image'
+ rbd clone rbd2/clone@invalid --snap-id 0 clone3 |&
+ grep 'trying to access snapshot using both name and id'
+ SNAP_ID=$(rbd snap ls rbd2/clone --format json |
+ jq '.[] | select(.name == "s1") | .id')
+ rbd clone --snap-id $SNAP_ID rbd2/clone clone3
+ rbd ls | grep clone3
+ rbd ls -l | grep clone3 | grep rbd2/clone@s1
+ test "$(rbd -p rbd2 ls)" = 'clone'
+ test "$(rbd ls -l | grep -c rbd2/clone@s1)" = '2'
+ rbd flatten clone3
+ test "$(rbd ls -l | grep -c rbd2/clone@s1)" = '1'
+
rbd rm clone2
rbd snap unprotect rbd2/clone@s1
rbd snap rm rbd2/clone@s1
rbd rm rbd2/clone
+ rbd rm clone3
rbd snap unprotect test1@s1
rbd snap rm test1@s1
rbd rm test1
rbd snap create test1@1
rbd clone --rbd-default-clone-format=1 test1@1 test2 && exit 1 || true
rbd clone --rbd-default-clone-format=2 test1@1 test2
- rbd clone --rbd-default-clone-format=2 test1@1 test3
+ SNAP_ID=$(rbd snap ls test1 --format json |
+ jq '.[] | select(.name == "1") | .id')
+ rbd clone --rbd-default-clone-format=2 --snap-id $SNAP_ID test1 test3
rbd snap protect test1@1
rbd clone --rbd-default-clone-format=1 test1@1 test4
rbd help clone
usage: rbd clone [--pool <pool>] [--namespace <namespace>] [--image <image>]
- [--snap <snap>] [--dest-pool <dest-pool>]
- [--dest-namespace <dest-namespace>] [--dest <dest>]
- [--order <order>] [--object-size <object-size>]
+ [--snap <snap>] [--snap-id <snap-id>]
+ [--dest-pool <dest-pool>] [--dest-namespace <dest-namespace>]
+ [--dest <dest>] [--order <order>]
+ [--object-size <object-size>]
[--image-feature <image-feature>] [--image-shared]
[--stripe-unit <stripe-unit>] [--stripe-count <stripe-count>]
[--data-pool <data-pool>]
--namespace arg source namespace name
--image arg source image name
--snap arg source snapshot name
+ --snap-id arg source snapshot id
--dest-pool arg destination pool name
--dest-namespace arg destination namespace name
--dest arg destination image name
#include "tools/rbd/ArgumentTypes.h"
#include "tools/rbd/Shell.h"
#include "tools/rbd/Utils.h"
+#include "include/types.h"
#include "common/errno.h"
#include <iostream>
#include <boost/program_options.hpp>
namespace at = argument_types;
namespace po = boost::program_options;
-int do_clone(librbd::RBD &rbd, librados::IoCtx &p_ioctx,
- const char *p_name, const char *p_snapname,
- librados::IoCtx &c_ioctx, const char *c_name,
- librbd::ImageOptions& opts) {
- return rbd.clone3(p_ioctx, p_name, p_snapname, c_ioctx, c_name, opts);
-}
-
void get_arguments(po::options_description *positional,
po::options_description *options) {
at::add_snap_spec_options(positional, options, at::ARGUMENT_MODIFIER_SOURCE);
+ at::add_snap_id_option(options, at::ARGUMENT_MODIFIER_SOURCE);
at::add_image_spec_options(positional, options, at::ARGUMENT_MODIFIER_DEST);
at::add_create_image_options(options, false);
}
std::string namespace_name;
std::string image_name;
std::string snap_name;
+ uint64_t snap_id = CEPH_NOSNAP;
+
+ if (vm.count(at::SNAPSHOT_ID)) {
+ snap_id = vm[at::SNAPSHOT_ID].as<uint64_t>();
+ }
+
int r = utils::get_pool_image_snapshot_names(
vm, at::ARGUMENT_MODIFIER_SOURCE, &arg_index, &pool_name, &namespace_name,
- &image_name, &snap_name, true, utils::SNAPSHOT_PRESENCE_REQUIRED,
+ &image_name, &snap_name, true,
+ (snap_id == CEPH_NOSNAP ? utils::SNAPSHOT_PRESENCE_REQUIRED :
+ utils::SNAPSHOT_PRESENCE_PERMITTED),
utils::SPEC_VALIDATION_NONE);
if (r < 0) {
return r;
}
+ if (!snap_name.empty() && snap_id != CEPH_NOSNAP) {
+ std::cerr << "rbd: trying to access snapshot using both name and id."
+ << std::endl;
+ return -EINVAL;
+ }
+
std::string dst_pool_name;
std::string dst_namespace_name;
std::string dst_image_name;
}
librbd::RBD rbd;
- r = do_clone(rbd, io_ctx, image_name.c_str(), snap_name.c_str(), dst_io_ctx,
- dst_image_name.c_str(), opts);
+ if (!snap_name.empty()) {
+ r = rbd.clone3(io_ctx, image_name.c_str(), snap_name.c_str(), dst_io_ctx,
+ dst_image_name.c_str(), opts);
+ } else {
+ r = rbd.clone4(io_ctx, image_name.c_str(), snap_id, dst_io_ctx,
+ dst_image_name.c_str(), opts);
+ }
if (r == -EXDEV) {
std::cerr << "rbd: clone v2 required for cross-namespace clones."
<< std::endl;