From 75226f1be27cfde36370f4b4253b28fa7954a65f Mon Sep 17 00:00:00 2001 From: Prasanna Kumar Kalever Date: Mon, 31 Oct 2022 11:38:18 +0530 Subject: [PATCH] rbd-nbd: provide a way to map snapshots by id Currently we don't have a way to map arbitrary snapshots, this commit provides --snap-id option to all such snapshots $ rbd --cluster=site-a snap ls pool1/test_image --all --format=json --pretty-format [ { "id": 4, "name": ".mirror.primary.c6fe94fd-3f9b-4ce0-aecc-e9d07472fd46.528a3f48-1b5c-4abb-9089-5a454328aeb3", "size": 1073741824, "protected": "false", "timestamp": "Thu Oct 27 22:09:12 2022", "namespace": { "type": "mirror", "state": "primary", "mirror_peer_uuids": [ "3e99dc15-78ca-46bd-8934-93d8063c0081" ], "complete": true } } ] $ rbd-nbd --cluster=site-a map --snap-id=4 pool1/test_image /dev/nbd0 $ rbd-nbd list-mapped id pool namespace image snap device cookie 511989 pool1 test_image @4 /dev/nbd0 68de2ef3-1d22-43b9-8318-03f3d31ec8b5 513439 pool1 test_image @5 /dev/nbd1 f3222c04-4048-4c61-a0b1-28536c4a29a7 Signed-off-by: Prasanna Kumar Kalever --- doc/man/8/rbd-nbd.rst | 6 ++++- src/tools/rbd_nbd/rbd-nbd.cc | 45 +++++++++++++++++++++++++++++------- 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/doc/man/8/rbd-nbd.rst b/doc/man/8/rbd-nbd.rst index 5f901995d4085..a7bf15332e5ab 100644 --- a/doc/man/8/rbd-nbd.rst +++ b/doc/man/8/rbd-nbd.rst @@ -9,7 +9,7 @@ Synopsis ======== -| **rbd-nbd** [-c conf] [--read-only] [--device *nbd device*] [--nbds_max *limit*] [--max_part *limit*] [--exclusive] [--notrim] [--encryption-format *format*] [--encryption-passphrase-file *passphrase-file*] [--io-timeout *seconds*] [--reattach-timeout *seconds*] map *image-spec* | *snap-spec* +| **rbd-nbd** [-c conf] [--read-only] [--device *nbd device*] [--snap-id *snap-id*] [--nbds_max *limit*] [--max_part *limit*] [--exclusive] [--notrim] [--encryption-format *format*] [--encryption-passphrase-file *passphrase-file*] [--io-timeout *seconds*] [--reattach-timeout *seconds*] map *image-spec* | *snap-spec* | **rbd-nbd** unmap *nbd device* | *image-spec* | *snap-spec* | **rbd-nbd** list-mapped | **rbd-nbd** attach --device *nbd device* *image-spec* | *snap-spec* @@ -71,6 +71,10 @@ Options attached after the old process is detached. The default is 30 second. +.. option:: --snap-id *snapid* + + Specify a snapshot to map/unmap/attach/detach by ID instead of by name. + Image and snap specs ==================== diff --git a/src/tools/rbd_nbd/rbd-nbd.cc b/src/tools/rbd_nbd/rbd-nbd.cc index 8ddeeb39423f4..90f3c2b1f2439 100644 --- a/src/tools/rbd_nbd/rbd-nbd.cc +++ b/src/tools/rbd_nbd/rbd-nbd.cc @@ -125,6 +125,7 @@ struct Config { Command command = None; int pid = 0; std::string cookie; + uint64_t snapid = CEPH_NOSNAP; std::string image_spec() const { std::string spec = poolname + "/"; @@ -168,6 +169,11 @@ static void usage() << " --try-netlink Use the nbd netlink interface\n" << " --show-cookie Show device cookie\n" << " --cookie Specify device cookie\n" + << " --snap-id Specify snapshot by ID instead of by name\n" + << "\n" + << "Unmap and detach options:\n" + << " --device Specify nbd device path (/dev/nbd{num})\n" + << " --snap-id Specify snapshot by ID instead of by name\n" << "\n" << "List options:\n" << " --format plain|json|xml Output format (default: plain)\n" @@ -1657,10 +1663,20 @@ static int do_map(int argc, const char *argv[], Config *cfg, bool reconnect) } } - if (!cfg->snapname.empty()) { + if (cfg->snapid != CEPH_NOSNAP) { + r = image.snap_set_by_id(cfg->snapid); + if (r < 0) { + cerr << "rbd-nbd: failed to set snap id: " << cpp_strerror(r) + << std::endl; + goto close_fd; + } + } else if (!cfg->snapname.empty()) { r = image.snap_set(cfg->snapname.c_str()); - if (r < 0) + if (r < 0) { + cerr << "rbd-nbd: failed to set snap name: " << cpp_strerror(r) + << std::endl; goto close_fd; + } } if (encryption_format_count > 0) { @@ -1958,23 +1974,23 @@ static int do_list_mapped_devices(const std::string &format, bool pretty_format) Config cfg; NBDListIterator it; while (it.get(&cfg)) { + std::string snap = (cfg.snapid != CEPH_NOSNAP ? + "@" + std::to_string(cfg.snapid) : cfg.snapname); if (f) { f->open_object_section("device"); f->dump_int("id", cfg.pid); f->dump_string("pool", cfg.poolname); f->dump_string("namespace", cfg.nsname); f->dump_string("image", cfg.imgname); - f->dump_string("snap", cfg.snapname); + f->dump_string("snap", snap); f->dump_string("device", cfg.devpath); f->dump_string("cookie", cfg.cookie); f->close_section(); } else { should_print = true; - if (cfg.snapname.empty()) { - cfg.snapname = "-"; - } tbl << cfg.pid << cfg.poolname << cfg.nsname << cfg.imgname - << cfg.snapname << cfg.devpath << cfg.cookie << TextTable::endrow; + << (snap.empty() ? "-" : snap) << cfg.devpath << cfg.cookie + << TextTable::endrow; } } @@ -1995,7 +2011,8 @@ static bool find_mapped_dev_by_spec(Config *cfg, int skip_pid=-1) { if (c.pid != skip_pid && c.poolname == cfg->poolname && c.nsname == cfg->nsname && c.imgname == cfg->imgname && c.snapname == cfg->snapname && - (cfg->devpath.empty() || c.devpath == cfg->devpath)) { + (cfg->devpath.empty() || c.devpath == cfg->devpath) && + c.snapid == cfg->snapid) { *cfg = c; return true; } @@ -2038,6 +2055,7 @@ static int parse_args(vector& args, std::ostream *err_msg, std::vector::iterator i; std::ostringstream err; std::string arg_value; + long long snapid; for (i = args.begin(); i != args.end(); ) { if (ceph_argparse_flag(args, i, "-h", "--help", (char*)NULL)) { @@ -2114,6 +2132,17 @@ static int parse_args(vector& args, std::ostream *err_msg, } else if (ceph_argparse_flag(args, i, "--show-cookie", (char *)NULL)) { cfg->show_cookie = true; } else if (ceph_argparse_witharg(args, i, &cfg->cookie, "--cookie", (char *)NULL)) { + } else if (ceph_argparse_witharg(args, i, &snapid, err, + "--snap-id", (char *)NULL)) { + if (!err.str().empty()) { + *err_msg << "rbd-nbd: " << err.str(); + return -EINVAL; + } + if (snapid < 0) { + *err_msg << "rbd-nbd: Invalid argument for snap-id!"; + return -EINVAL; + } + cfg->snapid = snapid; } else if (ceph_argparse_witharg(args, i, &arg_value, "--encryption-format", (char *)NULL)) { if (arg_value == "luks1") { -- 2.39.5