]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
rbd: list primary mirror snapshots in mirror image status
authorMykola Golub <mgolub@suse.com>
Sun, 10 Nov 2019 18:09:34 +0000 (18:09 +0000)
committerMykola Golub <mgolub@suse.com>
Tue, 10 Dec 2019 15:45:30 +0000 (15:45 +0000)
TODO: provide the same in verbose mirror pool status.

Signed-off-by: Mykola Golub <mgolub@suse.com>
src/tools/rbd/action/MirrorImage.cc

index 6d3698b56863ccfb7b1c183094d5a35b1ede1f57..e40b4e1ed8f5cc07ca9ede121e6da698f267b0fd 100644 (file)
@@ -337,7 +337,35 @@ int execute_status(const po::variables_map &vm,
     }
   }
 
+  std::vector<librbd::snap_info_t> snaps;
+  if (status.info.primary && status.info.state == RBD_MIRROR_IMAGE_ENABLED) {
+    librbd::mirror_image_mode_t mode = RBD_MIRROR_IMAGE_MODE_JOURNAL;
+    r = image.mirror_image_get_mode(&mode);
+    if (r < 0) {
+      std::cerr << "rbd: failed to retrieve mirror mode: "
+                << cpp_strerror(r) << std::endl;
+      // not fatal
+    }
+
+    if (mode == RBD_MIRROR_IMAGE_MODE_SNAPSHOT) {
+      image.snap_list(snaps);
+      snaps.erase(
+        remove_if(snaps.begin(),
+                  snaps.end(),
+                  [&image](const librbd::snap_info_t &snap) {
+                    librbd::snap_namespace_type_t type;
+                    int r = image.snap_get_namespace_type(snap.id, &type);
+                    if (r < 0) {
+                      return false;
+                    }
+                    return type != RBD_SNAP_NAMESPACE_TYPE_MIRROR_PRIMARY;
+                  }),
+        snaps.end());
+    }
+  }
+
   auto mirror_service = daemon_service_info.get_by_instance_id(instance_id);
+
   if (formatter != nullptr) {
     formatter->open_object_section("image");
     formatter->dump_string("name", image_name);
@@ -371,6 +399,28 @@ int execute_status(const po::variables_map &vm,
       }
       formatter->close_section(); // peer_sites
     }
+    if (!snaps.empty()) {
+      formatter->open_array_section("snapshots");
+      for (auto &snap : snaps) {
+        librbd::snap_mirror_primary_namespace_t info;
+        r = image.snap_get_mirror_primary_namespace(snap.id, &info,
+                                                    sizeof(info));
+        if (r < 0) {
+          continue;
+        }
+        formatter->open_object_section("snapshot");
+        formatter->dump_unsigned("id", snap.id);
+        formatter->dump_string("name", snap.name);
+        formatter->dump_bool("demoted", info.demoted);
+        formatter->open_array_section("mirror_peer_uuids");
+        for (auto &peer : info.mirror_peer_uuids) {
+          formatter->dump_string("peer_uuid", peer);
+        }
+        formatter->close_section(); // mirror_peer_uuids
+        formatter->close_section(); // snapshot
+      }
+      formatter->close_section(); // snapshots
+    }
     formatter->close_section(); // image
     formatter->flush(std::cout);
   } else {
@@ -409,6 +459,28 @@ int execute_status(const po::variables_map &vm,
                     site.last_update) << std::endl;
       }
     }
+    if (!snaps.empty()) {
+      std::cout << "  snapshots:" << std::endl;
+
+      bool first_site = true;
+      for (auto &snap : snaps) {
+        librbd::snap_mirror_primary_namespace_t info;
+        r = image.snap_get_mirror_primary_namespace(snap.id, &info,
+                                                    sizeof(info));
+        if (r < 0) {
+          continue;
+        }
+
+        if (!first_site) {
+          std::cout << std::endl;
+        }
+
+        first_site = false;
+        std::cout << snap.id << " " << snap.name << " ("
+                  << (info.demoted ? "demoted " : "") << "peer_uuids:["
+                  << info.mirror_peer_uuids << "])";
+      }
+    }
   }
 
   return 0;