]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rbd-nbd: provide a way to map snapshots by id
authorPrasanna Kumar Kalever <prasanna.kalever@redhat.com>
Mon, 31 Oct 2022 06:08:18 +0000 (11:38 +0530)
committerPrasanna Kumar Kalever <prasanna.kalever@redhat.com>
Thu, 10 Nov 2022 13:58:24 +0000 (19:28 +0530)
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 <prasanna.kalever@redhat.com>
doc/man/8/rbd-nbd.rst
src/tools/rbd_nbd/rbd-nbd.cc

index 5f901995d40853b9c8c76db8a033d60e3c6c28f4..a7bf15332e5ab8f5c0380d74c154a76839d068a1 100644 (file)
@@ -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
 ====================
 
index 8ddeeb39423f402d802711a0bf63eb7c96860067..90f3c2b1f24397465048d9d4ccb54be075fa2e69 100644 (file)
@@ -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 <snap-id>           Specify snapshot by ID instead of by name\n"
+            << "\n"
+            << "Unmap and detach options:\n"
+            << "  --device <device path>        Specify nbd device path (/dev/nbd{num})\n"
+            << "  --snap-id <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<const char*>& args, std::ostream *err_msg,
   std::vector<const char*>::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<const char*>& 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") {