]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
librbd: collapse API mirror primary/non-primary namespaces to single type
authorJason Dillaman <dillaman@redhat.com>
Mon, 3 Feb 2020 20:09:28 +0000 (15:09 -0500)
committerJason Dillaman <dillaman@redhat.com>
Wed, 19 Feb 2020 15:36:40 +0000 (10:36 -0500)
Eventually we will want to be able to chain multiple peers together.
In order to avoid special logic for syncing non-primary snapshots from
a peer, just treat all mirror snapshots the same.

This also clears some confusion for how to handle demoted snapshots
since otherwise it would involve creating a primary-snapshot on the
non-primary image before the image was fully synced.

Finally, the copied flag was renamed to completed since we should
eventually only set this to true on primary snapshots after the
image state has been created.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/include/rbd/librbd.h
src/include/rbd/librbd.hpp
src/librbd/api/Snapshot.cc
src/librbd/api/Snapshot.h
src/librbd/librbd.cc
src/pybind/rbd/rbd.pyx
src/test/librbd/test_mirroring.cc
src/test/pybind/test_rbd.py
src/tools/rbd/action/MirrorImage.cc
src/tools/rbd/action/Snap.cc

index c4c8c5ddaef10025e757cff648f31063e9848507..25068dbf4e59c659083d83708ebda0000977ef1c 100644 (file)
@@ -75,11 +75,10 @@ typedef int (*librbd_progress_fn_t)(uint64_t offset, uint64_t total, void *ptr);
 typedef void (*rbd_update_callback_t)(void *arg);
 
 typedef enum {
-  RBD_SNAP_NAMESPACE_TYPE_USER               = 0,
-  RBD_SNAP_NAMESPACE_TYPE_GROUP              = 1,
-  RBD_SNAP_NAMESPACE_TYPE_TRASH              = 2,
-  RBD_SNAP_NAMESPACE_TYPE_MIRROR_PRIMARY     = 3,
-  RBD_SNAP_NAMESPACE_TYPE_MIRROR_NON_PRIMARY = 4,
+  RBD_SNAP_NAMESPACE_TYPE_USER   = 0,
+  RBD_SNAP_NAMESPACE_TYPE_GROUP  = 1,
+  RBD_SNAP_NAMESPACE_TYPE_TRASH  = 2,
+  RBD_SNAP_NAMESPACE_TYPE_MIRROR = 3,
 } rbd_snap_namespace_type_t;
 
 typedef struct {
@@ -254,18 +253,22 @@ typedef struct {
   char *group_snap_name;
 } rbd_snap_group_namespace_t;
 
+typedef enum {
+  RBD_SNAP_MIRROR_STATE_PRIMARY,
+  RBD_SNAP_MIRROR_STATE_PRIMARY_DEMOTED,
+  RBD_SNAP_MIRROR_STATE_NON_PRIMARY,
+  RBD_SNAP_MIRROR_STATE_NON_PRIMARY_DEMOTED
+} rbd_snap_mirror_state_t;
+
 typedef struct {
-  bool demoted;
+  rbd_snap_mirror_state_t state;
   size_t mirror_peer_uuids_count;
   char *mirror_peer_uuids;
-} rbd_snap_mirror_primary_namespace_t;
-
-typedef struct {
+  bool complete;
   char *primary_mirror_uuid;
   uint64_t primary_snap_id;
-  bool copied;
   uint64_t last_copied_object_number;
-} rbd_snap_mirror_non_primary_namespace_t;
+} rbd_snap_mirror_namespace_t;
 
 typedef enum {
   RBD_LOCK_MODE_EXCLUSIVE = 0,
@@ -857,18 +860,11 @@ CEPH_RBD_API int rbd_snap_get_trash_namespace(rbd_image_t image,
                                               uint64_t snap_id,
                                               char* original_name,
                                               size_t max_length);
-CEPH_RBD_API int rbd_snap_get_mirror_primary_namespace(
-    rbd_image_t image, uint64_t snap_id,
-    rbd_snap_mirror_primary_namespace_t *mirror_snap, size_t mirror_snap_size);
-CEPH_RBD_API int rbd_snap_mirror_primary_namespace_cleanup(
-    rbd_snap_mirror_primary_namespace_t *mirror_snap, size_t mirror_snap_size);
-CEPH_RBD_API int rbd_snap_get_mirror_non_primary_namespace(
+CEPH_RBD_API int rbd_snap_get_mirror_namespace(
     rbd_image_t image, uint64_t snap_id,
-    rbd_snap_mirror_non_primary_namespace_t *mirror_snap,
-    size_t mirror_snap_size);
-CEPH_RBD_API int rbd_snap_mirror_non_primary_namespace_cleanup(
-    rbd_snap_mirror_non_primary_namespace_t *mirror_snap,
-    size_t mirror_snap_size);
+    rbd_snap_mirror_namespace_t *mirror_snap, size_t mirror_snap_size);
+CEPH_RBD_API int rbd_snap_mirror_namespace_cleanup(
+    rbd_snap_mirror_namespace_t *mirror_snap, size_t mirror_snap_size);
 
 CEPH_RBD_API int rbd_flatten(rbd_image_t image);
 
index 3fb8f7cda055753bb16ef3773a80f4376a5fb14c..ca2d7449baf39fa3a0d34761967e9ac720a72391 100644 (file)
@@ -73,17 +73,16 @@ namespace librbd {
     std::string group_snap_name;
   } snap_group_namespace_t;
 
-  typedef struct {
-    bool demoted;
-    std::set<std::string> mirror_peer_uuids;
-  } snap_mirror_primary_namespace_t;
+  typedef rbd_snap_mirror_state_t snap_mirror_state_t;
 
   typedef struct {
+    snap_mirror_state_t state;
+    std::set<std::string> mirror_peer_uuids;
+    bool complete;
     std::string primary_mirror_uuid;
     uint64_t primary_snap_id;
-    bool copied;
     uint64_t last_copied_object_number;
-  } snap_mirror_non_primary_namespace_t;
+  } snap_mirror_namespace_t;
 
   typedef struct {
     std::string client;
@@ -621,11 +620,8 @@ public:
                                snap_group_namespace_t *group_namespace,
                                size_t snap_group_namespace_size);
   int snap_get_trash_namespace(uint64_t snap_id, std::string* original_name);
-  int snap_get_mirror_primary_namespace(
-      uint64_t snap_id, snap_mirror_primary_namespace_t *mirror_namespace,
-      size_t snap_mirror_namespace_size);
-  int snap_get_mirror_non_primary_namespace(
-      uint64_t snap_id, snap_mirror_non_primary_namespace_t *mirror_namespace,
+  int snap_get_mirror_namespace(
+      uint64_t snap_id, snap_mirror_namespace_t *mirror_namespace,
       size_t snap_mirror_namespace_size);
 
   /* I/O */
index 20f4bf8c404100825d343a28f5cc1dc09d18afff..d13ac77581619354a40a89bcca9f3b2a6e85a5d6 100644 (file)
@@ -10,6 +10,7 @@
 #include "librbd/Operations.h"
 #include "librbd/Utils.h"
 #include "librbd/api/Image.h"
+#include "librbd/api/Mirror.h"
 #include <boost/variant.hpp>
 #include "include/Context.h"
 #include "common/Cond.h"
@@ -99,12 +100,14 @@ public:
   }
 };
 
-class GetMirrorPrimaryVisitor : public boost::static_visitor<int> {
+class GetMirrorVisitor : public boost::static_visitor<int> {
 public:
-  snap_mirror_primary_namespace_t *mirror_snap;
+  snap_mirror_namespace_t *mirror_snap;
+  std::string mirror_uuid;
 
-  explicit GetMirrorPrimaryVisitor(snap_mirror_primary_namespace_t *mirror_snap)
-    : mirror_snap(mirror_snap) {
+  explicit GetMirrorVisitor(snap_mirror_namespace_t *mirror_snap,
+                            const std::string& mirror_uuid)
+    : mirror_snap(mirror_snap), mirror_uuid(mirror_uuid) {
   }
 
   template <typename T>
@@ -114,31 +117,22 @@ public:
 
   inline int operator()(
       const cls::rbd::MirrorPrimarySnapshotNamespace& snap_namespace) {
-    mirror_snap->demoted = snap_namespace.demoted;
+    if (snap_namespace.demoted) {
+      mirror_snap->state = RBD_SNAP_MIRROR_STATE_PRIMARY_DEMOTED;
+    } else {
+      mirror_snap->state = RBD_SNAP_MIRROR_STATE_PRIMARY;
+    }
     mirror_snap->mirror_peer_uuids = snap_namespace.mirror_peer_uuids;
+    mirror_snap->complete = true;
     return 0;
   }
-};
-
-class GetMirrorNonPrimaryVisitor : public boost::static_visitor<int> {
-public:
-  snap_mirror_non_primary_namespace_t *mirror_snap;
-
-  explicit GetMirrorNonPrimaryVisitor(
-      snap_mirror_non_primary_namespace_t *mirror_snap)
-    : mirror_snap(mirror_snap) {
-  }
-
-  template <typename T>
-  inline int operator()(const T&) const {
-    return -EINVAL;
-  }
 
   inline int operator()(
       const cls::rbd::MirrorNonPrimarySnapshotNamespace& snap_namespace) {
+    mirror_snap->state = RBD_SNAP_MIRROR_STATE_NON_PRIMARY;
     mirror_snap->primary_mirror_uuid = snap_namespace.primary_mirror_uuid;
     mirror_snap->primary_snap_id = snap_namespace.primary_snap_id;
-    mirror_snap->copied = snap_namespace.copied;
+    mirror_snap->complete = snap_namespace.copied;
     mirror_snap->last_copied_object_number =
       snap_namespace.last_copied_object_number;
     return 0;
@@ -194,8 +188,8 @@ int Snapshot<I>::get_trash_namespace(I *ictx, uint64_t snap_id,
 }
 
 template <typename I>
-int Snapshot<I>::get_mirror_primary_namespace(
-    I *ictx, uint64_t snap_id, snap_mirror_primary_namespace_t *mirror_snap) {
+int Snapshot<I>::get_mirror_namespace(
+    I *ictx, uint64_t snap_id, snap_mirror_namespace_t *mirror_snap) {
   int r = ictx->state->refresh_if_required();
   if (r < 0) {
     return r;
@@ -207,31 +201,14 @@ int Snapshot<I>::get_mirror_primary_namespace(
     return -ENOENT;
   }
 
-  auto gmv = GetMirrorPrimaryVisitor(mirror_snap);
-  r = boost::apply_visitor(gmv, snap_info->snap_namespace);
+  // TODO temporary
+  std::string mirror_uuid;
+  r = Mirror<I>::uuid_get(ictx->md_ctx, &mirror_uuid);
   if (r < 0) {
     return r;
   }
 
-  return 0;
-}
-
-template <typename I>
-int Snapshot<I>::get_mirror_non_primary_namespace(
-    I *ictx, uint64_t snap_id,
-    snap_mirror_non_primary_namespace_t *mirror_snap) {
-  int r = ictx->state->refresh_if_required();
-  if (r < 0) {
-    return r;
-  }
-
-  std::shared_lock image_locker{ictx->image_lock};
-  auto snap_info = ictx->get_snap_info(snap_id);
-  if (snap_info == nullptr) {
-    return -ENOENT;
-  }
-
-  auto gmv = GetMirrorNonPrimaryVisitor(mirror_snap);
+  auto gmv = GetMirrorVisitor(mirror_snap, mirror_uuid);
   r = boost::apply_visitor(gmv, snap_info->snap_namespace);
   if (r < 0) {
     return r;
index a791a481a2fc022fad7d7df848c00dc0f2fbd7da..ce5252c78d8f698e72c1a16ac30a2af5cb47848a 100644 (file)
@@ -23,13 +23,9 @@ struct Snapshot {
   static int get_trash_namespace(ImageCtxT *ictx, uint64_t snap_id,
                                  std::string *original_name);
 
-  static int get_mirror_primary_namespace(
+  static int get_mirror_namespace(
       ImageCtxT *ictx, uint64_t snap_id,
-      snap_mirror_primary_namespace_t *mirror_snap);
-
-  static int get_mirror_non_primary_namespace(
-      ImageCtxT *ictx, uint64_t snap_id,
-      snap_mirror_non_primary_namespace_t *mirror_snap);
+      snap_mirror_namespace_t *mirror_snap);
 
   static int get_namespace_type(ImageCtxT *ictx, uint64_t snap_id,
                                snap_namespace_type_t *namespace_type);
index 28f00367d9d8291738f3f7cc399fe940c7ba4bff..ca1009e0ee54db351be19b174041bb9f4b09f576 100644 (file)
@@ -2347,30 +2347,16 @@ namespace librbd {
                                                         original_name);
   }
 
-  int Image::snap_get_mirror_primary_namespace(
-      uint64_t snap_id, snap_mirror_primary_namespace_t *mirror_snap,
+  int Image::snap_get_mirror_namespace(
+      uint64_t snap_id, snap_mirror_namespace_t *mirror_snap,
       size_t mirror_snap_size) {
     ImageCtx *ictx = (ImageCtx *)ctx;
 
-    if (mirror_snap_size != sizeof(snap_mirror_primary_namespace_t)) {
+    if (mirror_snap_size != sizeof(snap_mirror_namespace_t)) {
       return -ERANGE;
     }
 
-    int r = librbd::api::Snapshot<>::get_mirror_primary_namespace(
-        ictx, snap_id, mirror_snap);
-    return r;
-  }
-
-  int Image::snap_get_mirror_non_primary_namespace(
-      uint64_t snap_id, snap_mirror_non_primary_namespace_t *mirror_snap,
-      size_t mirror_snap_size) {
-    ImageCtx *ictx = (ImageCtx *)ctx;
-
-    if (mirror_snap_size != sizeof(snap_mirror_non_primary_namespace_t)) {
-      return -ERANGE;
-    }
-
-    int r = librbd::api::Snapshot<>::get_mirror_non_primary_namespace(
+    int r = librbd::api::Snapshot<>::get_mirror_namespace(
         ictx, snap_id, mirror_snap);
     return r;
   }
@@ -6985,24 +6971,27 @@ extern "C" int rbd_snap_get_trash_namespace(rbd_image_t image, uint64_t snap_id,
   return 0;
 }
 
-extern "C" int rbd_snap_get_mirror_primary_namespace(
+extern "C" int rbd_snap_get_mirror_namespace(
     rbd_image_t image, uint64_t snap_id,
-    rbd_snap_mirror_primary_namespace_t *mirror_snap,
+    rbd_snap_mirror_namespace_t *mirror_snap,
     size_t mirror_snap_size) {
   librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
 
-  if (mirror_snap_size != sizeof(rbd_snap_mirror_primary_namespace_t)) {
+  if (mirror_snap_size != sizeof(rbd_snap_mirror_namespace_t)) {
     return -ERANGE;
   }
 
-  librbd::snap_mirror_primary_namespace_t mirror_namespace;
-  int r = librbd::api::Snapshot<>::get_mirror_primary_namespace(
+  librbd::snap_mirror_namespace_t mirror_namespace;
+  int r = librbd::api::Snapshot<>::get_mirror_namespace(
       ictx, snap_id, &mirror_namespace);
   if (r < 0) {
     return r;
   }
 
-  mirror_snap->demoted = mirror_namespace.demoted;
+  mirror_snap->state = mirror_namespace.state;
+  mirror_snap->primary_mirror_uuid =
+    strdup(mirror_namespace.primary_mirror_uuid.c_str());
+  mirror_snap->primary_snap_id = mirror_namespace.primary_snap_id;
   mirror_snap->mirror_peer_uuids_count =
     mirror_namespace.mirror_peer_uuids.size();
   size_t len = 0;
@@ -7015,56 +7004,22 @@ extern "C" int rbd_snap_get_mirror_primary_namespace(
     strncpy(p, peer.c_str(), peer.size() + 1);
     p += peer.size() + 1;
   }
-
-  return 0;
-}
-
-extern "C" int rbd_snap_mirror_primary_namespace_cleanup(
-    rbd_snap_mirror_primary_namespace_t *mirror_snap,
-    size_t mirror_snap_size) {
-  if (mirror_snap_size != sizeof(rbd_snap_mirror_primary_namespace_t)) {
-    return -ERANGE;
-  }
-
-  free(mirror_snap->mirror_peer_uuids);
-  return 0;
-}
-
-extern "C" int rbd_snap_get_mirror_non_primary_namespace(
-    rbd_image_t image, uint64_t snap_id,
-    rbd_snap_mirror_non_primary_namespace_t *mirror_snap,
-    size_t mirror_snap_size) {
-  librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
-
-  if (mirror_snap_size != sizeof(rbd_snap_mirror_non_primary_namespace_t)) {
-    return -ERANGE;
-  }
-
-  librbd::snap_mirror_non_primary_namespace_t mirror_namespace;
-  int r = librbd::api::Snapshot<>::get_mirror_non_primary_namespace(
-      ictx, snap_id, &mirror_namespace);
-  if (r < 0) {
-    return r;
-  }
-
-  mirror_snap->primary_mirror_uuid =
-    strdup(mirror_namespace.primary_mirror_uuid.c_str());
-  mirror_snap->primary_snap_id = mirror_namespace.primary_snap_id;
-  mirror_snap->copied = mirror_namespace.copied;
+  mirror_snap->complete = mirror_namespace.complete;
   mirror_snap->last_copied_object_number =
     mirror_namespace.last_copied_object_number;
 
   return 0;
 }
 
-extern "C" int rbd_snap_mirror_non_primary_namespace_cleanup(
-    rbd_snap_mirror_non_primary_namespace_t *mirror_snap,
+extern "C" int rbd_snap_mirror_namespace_cleanup(
+    rbd_snap_mirror_namespace_t *mirror_snap,
     size_t mirror_snap_size) {
-  if (mirror_snap_size != sizeof(rbd_snap_mirror_non_primary_namespace_t)) {
+  if (mirror_snap_size != sizeof(rbd_snap_mirror_namespace_t)) {
     return -ERANGE;
   }
 
   free(mirror_snap->primary_mirror_uuid);
+  free(mirror_snap->mirror_peer_uuids);
   return 0;
 }
 
index 958f646045f665d3d1b2bc86deb800ea4f9f45da..34e1d92cbaa4f7df42b2b6cff1241e5ee84695c9 100644 (file)
@@ -127,15 +127,19 @@ cdef extern from "rbd/librbd.h" nogil:
         char *group_name
         char *group_snap_name
 
-    ctypedef struct rbd_snap_mirror_primary_namespace_t:
-        bint demoted
+    ctypedef enum rbd_snap_mirror_state_t:
+        _RBD_SNAP_MIRROR_STATE_PRIMARY "RBD_SNAP_MIRROR_STATE_PRIMARY"
+        _RBD_SNAP_MIRROR_STATE_PRIMARY_DEMOTED "RBD_SNAP_MIRROR_STATE_PRIMARY_DEMOTED"
+        _RBD_SNAP_MIRROR_STATE_NON_PRIMARY "RBD_SNAP_MIRROR_STATE_NON_PRIMARY"
+        _RBD_SNAP_MIRROR_STATE_NON_PRIMARY_DEMOTED "RBD_SNAP_MIRROR_STATE_NON_PRIMARY_DEMOTED"
+
+    ctypedef struct rbd_snap_mirror_namespace_t:
+        rbd_snap_mirror_state_t state
         size_t mirror_peer_uuids_count
         char *mirror_peer_uuids
-
-    ctypedef struct rbd_snap_mirror_non_primary_namespace_t:
+        bint complete
         char *primary_mirror_uuid
         uint64_t primary_snap_id
-        bint copied
         uint64_t last_copied_object_number
 
     ctypedef struct rbd_group_info_t:
@@ -158,8 +162,7 @@ cdef extern from "rbd/librbd.h" nogil:
         _RBD_SNAP_NAMESPACE_TYPE_USER "RBD_SNAP_NAMESPACE_TYPE_USER"
         _RBD_SNAP_NAMESPACE_TYPE_GROUP "RBD_SNAP_NAMESPACE_TYPE_GROUP"
         _RBD_SNAP_NAMESPACE_TYPE_TRASH "RBD_SNAP_NAMESPACE_TYPE_TRASH"
-        _RBD_SNAP_NAMESPACE_TYPE_MIRROR_PRIMARY "RBD_SNAP_NAMESPACE_TYPE_MIRROR_PRIMARY"
-        _RBD_SNAP_NAMESPACE_TYPE_MIRROR_NON_PRIMARY "RBD_SNAP_NAMESPACE_TYPE_MIRROR_NON_PRIMARY"
+        _RBD_SNAP_NAMESPACE_TYPE_MIRROR "RBD_SNAP_NAMESPACE_TYPE_MIRROR"
 
     ctypedef struct rbd_snap_spec_t:
         uint64_t id
@@ -535,20 +538,13 @@ cdef extern from "rbd/librbd.h" nogil:
                                           size_t snap_group_namespace_size)
     int rbd_snap_get_trash_namespace(rbd_image_t image, uint64_t snap_id,
                                      char *original_name, size_t max_length)
-    int rbd_snap_get_mirror_primary_namespace(
-        rbd_image_t image, uint64_t snap_id,
-        rbd_snap_mirror_primary_namespace_t *mirror_ns,
-        size_t snap_mirror_primary_namespace_size)
-    void rbd_snap_mirror_primary_namespace_cleanup(
-        rbd_snap_mirror_primary_namespace_t *mirror_ns,
-        size_t snap_mirror_primary_namespace_size)
-    int rbd_snap_get_mirror_non_primary_namespace(
+    int rbd_snap_get_mirror_namespace(
         rbd_image_t image, uint64_t snap_id,
-        rbd_snap_mirror_non_primary_namespace_t *mirror_ns,
-        size_t snap_mirror_non_primary_namespace_size)
-    void rbd_snap_mirror_non_primary_namespace_cleanup(
-        rbd_snap_mirror_non_primary_namespace_t *mirror_ns,
-        size_t snap_mirror_non_primary_namespace_size)
+        rbd_snap_mirror_namespace_t *mirror_ns,
+        size_t snap_mirror_namespace_size)
+    void rbd_snap_mirror_namespace_cleanup(
+        rbd_snap_mirror_namespace_t *mirror_ns,
+        size_t snap_mirror_namespace_size)
 
     int rbd_flatten_with_progress(rbd_image_t image, librbd_progress_fn_t cb,
                                   void *cbdata)
@@ -769,8 +765,12 @@ RBD_IMAGE_OPTION_DATA_POOL = _RBD_IMAGE_OPTION_DATA_POOL
 RBD_SNAP_NAMESPACE_TYPE_USER = _RBD_SNAP_NAMESPACE_TYPE_USER
 RBD_SNAP_NAMESPACE_TYPE_GROUP = _RBD_SNAP_NAMESPACE_TYPE_GROUP
 RBD_SNAP_NAMESPACE_TYPE_TRASH = _RBD_SNAP_NAMESPACE_TYPE_TRASH
-RBD_SNAP_NAMESPACE_TYPE_MIRROR_PRIMARY = _RBD_SNAP_NAMESPACE_TYPE_MIRROR_PRIMARY
-RBD_SNAP_NAMESPACE_TYPE_MIRROR_NON_PRIMARY = _RBD_SNAP_NAMESPACE_TYPE_MIRROR_NON_PRIMARY
+RBD_SNAP_NAMESPACE_TYPE_MIRROR = _RBD_SNAP_NAMESPACE_TYPE_MIRROR
+
+RBD_SNAP_MIRROR_STATE_PRIMARY = _RBD_SNAP_MIRROR_STATE_PRIMARY
+RBD_SNAP_MIRROR_STATE_PRIMARY_DEMOTED = _RBD_SNAP_MIRROR_STATE_PRIMARY_DEMOTED
+RBD_SNAP_MIRROR_STATE_NON_PRIMARY = _RBD_SNAP_MIRROR_STATE_NON_PRIMARY
+RBD_SNAP_MIRROR_STATE_NON_PRIMARY_DEMOTED = _RBD_SNAP_MIRROR_STATE_NON_PRIMARY_DEMOTED
 
 RBD_GROUP_IMAGE_STATE_ATTACHED = _RBD_GROUP_IMAGE_STATE_ATTACHED
 RBD_GROUP_IMAGE_STATE_INCOMPLETE = _RBD_GROUP_IMAGE_STATE_INCOMPLETE
@@ -5264,26 +5264,34 @@ written." % (self.name, ret, length))
         finally:
             free(_name)
 
-    def snap_get_mirror_primary_namespace(self, snap_id):
+    def snap_get_mirror_namespace(self, snap_id):
         """
-        get the mirror primary namespace details.
+        get the mirror namespace details.
         :param snap_id: the snapshot id of the mirror snapshot
         :type key: int
         :returns: dict - contains the following keys:
 
-            * ``demoted`` (bool) - True if snapshot is in demoted state
+            * ``state`` (int) - the snapshot state
 
             * ``mirror_peer_uuids`` (list) - mirror peer uuids
+
+            * ``complete`` (bool) - True if snapshot is complete
+
+            * ``primary_mirror_uuid`` (str) - primary mirror uuid
+
+            * ``primary_snap_id`` (int) - primary snapshot Id
+
+            *  ``last_copied_object_number`` (int) - last copied object number
         """
         cdef:
-            rbd_snap_mirror_primary_namespace_t sn
+            rbd_snap_mirror_namespace_t sn
             uint64_t _snap_id = snap_id
         with nogil:
-            ret = rbd_snap_get_mirror_primary_namespace(
+            ret = rbd_snap_get_mirror_namespace(
                 self.image, _snap_id, &sn,
-                sizeof(rbd_snap_mirror_primary_namespace_t))
+                sizeof(rbd_snap_mirror_namespace_t))
         if ret != 0:
-            raise make_ex(ret, 'error getting snapshot mirror primary '
+            raise make_ex(ret, 'error getting snapshot mirror '
                                'namespace for image: %s, snap_id: %d' %
                                (self.name, snap_id))
         uuids = []
@@ -5293,47 +5301,15 @@ written." % (self.name, ret, length))
             uuids.append(uuid)
             p += len(uuid) + 1
         info = {
-                'demoted' : sn.demoted,
+                'state' : sn.state,
                 'mirror_peer_uuids' : uuids,
-            }
-        rbd_snap_mirror_primary_namespace_cleanup(
-            &sn, sizeof(rbd_snap_mirror_primary_namespace_t))
-        return info
-
-    def snap_get_mirror_non_primary_namespace(self, snap_id):
-        """
-        get the mirror non-primary namespace details.
-        :param snap_id: the snapshot id of the mirror snapshot
-        :type key: int
-        :returns: dict - contains the following keys:
-
-            * ``primary_mirror_uuid`` (str) - primary mirror uuid
-
-            * ``primary_snap_id`` (int) - primary snapshot Id
-
-            * ``copied`` (bool) - True if snapsho is copied
-
-           *  ``last_copied_object_number`` (int) - last copied object number
-        """
-        cdef:
-            rbd_snap_mirror_non_primary_namespace_t sn
-            uint64_t _snap_id = snap_id
-        with nogil:
-            ret = rbd_snap_get_mirror_non_primary_namespace(
-                self.image, _snap_id, &sn,
-                sizeof(rbd_snap_mirror_non_primary_namespace_t))
-        if ret != 0:
-            raise make_ex(ret, 'error getting snapshot mirror non-primary '
-                               'namespace for image: %s, snap_id: %d' %
-                               (self.name, snap_id))
-        info = {
+                'complete' : sn.complete,
                 'primary_mirror_uuid' : decode_cstr(sn.primary_mirror_uuid),
                 'primary_snap_id' : sn.primary_snap_id,
-                'copied' : sn.copied,
                 'last_copied_object_number' : sn.last_copied_object_number,
             }
-        rbd_snap_mirror_non_primary_namespace_cleanup(
-            &sn, sizeof(rbd_snap_mirror_non_primary_namespace_t))
+        rbd_snap_mirror_namespace_cleanup(
+            &sn, sizeof(rbd_snap_mirror_namespace_t))
         return info
 
 
@@ -5518,9 +5494,7 @@ cdef class SnapIterator(object):
 
     * ``trash`` (dict) - optional for trash namespace snapshots
 
-    * ``mirror_primary`` (dict) - optional for mirror primary namespace snapshots
-
-    * ``mirror_non_primary`` (dict) - optional for mirror non-primary namespace snapshots
+    * ``mirror`` (dict) - optional for mirror namespace snapshots
     """
 
     cdef rbd_snap_info_t *snaps
@@ -5563,20 +5537,13 @@ cdef class SnapIterator(object):
                 except:
                     trash = None
                 s['trash'] = trash
-            elif s['namespace'] == RBD_SNAP_NAMESPACE_TYPE_MIRROR_PRIMARY:
-                try:
-                    mirror = self.image.snap_get_mirror_primary_namespace(
-                        self.snaps[i].id)
-                except:
-                    mirror = None
-                s['mirror_primary'] = mirror
-            elif s['namespace'] == RBD_SNAP_NAMESPACE_TYPE_MIRROR_NON_PRIMARY:
+            elif s['namespace'] == RBD_SNAP_NAMESPACE_TYPE_MIRROR:
                 try:
-                    mirror = self.image.snap_get_mirror_non_primary_namespace(
+                    mirror = self.image.snap_get_mirror_namespace(
                         self.snaps[i].id)
                 except:
                     mirror = None
-                    s['mirror_non_primary'] = mirror
+                s['mirror'] = mirror
             yield s
 
     def __dealloc__(self):
index c018bee35ad69a2a0a7bab097e7acbbb1092b05f..e0145c889d0d796d8ecafe308b9fed23830217f8 100644 (file)
@@ -1159,10 +1159,10 @@ TEST_F(TestMirroring, Snapshot)
 
   librbd::snap_namespace_type_t snap_ns_type;
   ASSERT_EQ(0, image.snap_get_namespace_type(snap_id, &snap_ns_type));
-  ASSERT_EQ(RBD_SNAP_NAMESPACE_TYPE_MIRROR_PRIMARY, snap_ns_type);
-  librbd::snap_mirror_primary_namespace_t mirror_snap;
-  ASSERT_EQ(0, image.snap_get_mirror_primary_namespace(snap_id, &mirror_snap,
-                                                       sizeof(mirror_snap)));
+  ASSERT_EQ(RBD_SNAP_NAMESPACE_TYPE_MIRROR, snap_ns_type);
+  librbd::snap_mirror_namespace_t mirror_snap;
+  ASSERT_EQ(0, image.snap_get_mirror_namespace(snap_id, &mirror_snap,
+                                               sizeof(mirror_snap)));
   ASSERT_EQ(1U, mirror_snap.mirror_peer_uuids.size());
   ASSERT_EQ(1, mirror_snap.mirror_peer_uuids.count(peer_uuid));
 
@@ -1242,9 +1242,9 @@ TEST_F(TestMirroring, SnapshotUnlinkPeer)
   ASSERT_EQ(0, image.mirror_image_enable2(RBD_MIRROR_IMAGE_MODE_SNAPSHOT));
   uint64_t snap_id;
   ASSERT_EQ(0, image.mirror_image_create_snapshot(&snap_id));
-  librbd::snap_mirror_primary_namespace_t mirror_snap;
-  ASSERT_EQ(0, image.snap_get_mirror_primary_namespace(snap_id, &mirror_snap,
-                                                       sizeof(mirror_snap)));
+  librbd::snap_mirror_namespace_t mirror_snap;
+  ASSERT_EQ(0, image.snap_get_mirror_namespace(snap_id, &mirror_snap,
+                                               sizeof(mirror_snap)));
   ASSERT_EQ(3U, mirror_snap.mirror_peer_uuids.size());
   ASSERT_EQ(1, mirror_snap.mirror_peer_uuids.count(peer1_uuid));
   ASSERT_EQ(1, mirror_snap.mirror_peer_uuids.count(peer2_uuid));
@@ -1264,8 +1264,8 @@ TEST_F(TestMirroring, SnapshotUnlinkPeer)
   req->send();
   ASSERT_EQ(0, cond1.wait());
 
-  ASSERT_EQ(0, image.snap_get_mirror_primary_namespace(snap_id, &mirror_snap,
-                                                       sizeof(mirror_snap)));
+  ASSERT_EQ(0, image.snap_get_mirror_namespace(snap_id, &mirror_snap,
+                                               sizeof(mirror_snap)));
   ASSERT_EQ(2U, mirror_snap.mirror_peer_uuids.size());
   ASSERT_EQ(1, mirror_snap.mirror_peer_uuids.count(peer2_uuid));
   ASSERT_EQ(1, mirror_snap.mirror_peer_uuids.count(peer3_uuid));
@@ -1283,22 +1283,22 @@ TEST_F(TestMirroring, SnapshotUnlinkPeer)
   ASSERT_EQ(0, ns_image.mirror_image_enable2(RBD_MIRROR_IMAGE_MODE_SNAPSHOT));
   uint64_t ns_snap_id;
   ASSERT_EQ(0, ns_image.mirror_image_create_snapshot(&ns_snap_id));
-  ASSERT_EQ(0, ns_image.snap_get_mirror_primary_namespace(
-              ns_snap_id, &mirror_snap, sizeof(mirror_snap)));
+  ASSERT_EQ(0, ns_image.snap_get_mirror_namespace(ns_snap_id, &mirror_snap,
+                                                  sizeof(mirror_snap)));
   ASSERT_EQ(3U, mirror_snap.mirror_peer_uuids.size());
   ASSERT_EQ(1, mirror_snap.mirror_peer_uuids.count(peer1_uuid));
   ASSERT_EQ(1, mirror_snap.mirror_peer_uuids.count(peer2_uuid));
   ASSERT_EQ(1, mirror_snap.mirror_peer_uuids.count(peer3_uuid));
-  
+
   ASSERT_EQ(0, m_rbd.mirror_peer_site_remove(m_ioctx, peer3_uuid));
 
-  ASSERT_EQ(0, image.snap_get_mirror_primary_namespace(snap_id, &mirror_snap,
-                                                       sizeof(mirror_snap)));
+  ASSERT_EQ(0, image.snap_get_mirror_namespace(snap_id, &mirror_snap,
+                                               sizeof(mirror_snap)));
   ASSERT_EQ(1U, mirror_snap.mirror_peer_uuids.size());
   ASSERT_EQ(1, mirror_snap.mirror_peer_uuids.count(peer2_uuid));
 
-  ASSERT_EQ(0, ns_image.snap_get_mirror_primary_namespace(
-              ns_snap_id, &mirror_snap, sizeof(mirror_snap)));
+  ASSERT_EQ(0, ns_image.snap_get_mirror_namespace(ns_snap_id, &mirror_snap,
+                                                  sizeof(mirror_snap)));
   ASSERT_EQ(2U, mirror_snap.mirror_peer_uuids.size());
   ASSERT_EQ(1, mirror_snap.mirror_peer_uuids.count(peer1_uuid));
   ASSERT_EQ(1, mirror_snap.mirror_peer_uuids.count(peer2_uuid));
@@ -1309,8 +1309,8 @@ TEST_F(TestMirroring, SnapshotUnlinkPeer)
   req->send();
   ASSERT_EQ(0, cond2.wait());
 
-  ASSERT_EQ(-ENOENT, image.snap_get_mirror_primary_namespace(snap_id, &mirror_snap,
-                                                             sizeof(mirror_snap)));
+  ASSERT_EQ(-ENOENT, image.snap_get_mirror_namespace(snap_id, &mirror_snap,
+                                                     sizeof(mirror_snap)));
   ictx->state->close();
   ictx = nullptr;
   ASSERT_EQ(0, image.close());
index f09b2bc07612dd2a78910053dad05419f79f3e1a..836cc7f5bac04a83f14434d7133e362514a5e972 100644 (file)
@@ -31,14 +31,14 @@ from rbd import (RBD, Group, Image, ImageNotFound, InvalidArgument, ImageExists,
                  RBD_MIRROR_IMAGE_MODE_JOURNAL, RBD_MIRROR_IMAGE_MODE_SNAPSHOT,
                  RBD_LOCK_MODE_EXCLUSIVE, RBD_OPERATION_FEATURE_GROUP,
                  RBD_SNAP_NAMESPACE_TYPE_TRASH,
-                 RBD_SNAP_NAMESPACE_TYPE_MIRROR_PRIMARY,
-                 RBD_SNAP_NAMESPACE_TYPE_MIRROR_NON_PRIMARY,
+                 RBD_SNAP_NAMESPACE_TYPE_MIRROR,
                  RBD_IMAGE_MIGRATION_STATE_PREPARED, RBD_CONFIG_SOURCE_CONFIG,
                  RBD_CONFIG_SOURCE_POOL, RBD_CONFIG_SOURCE_IMAGE,
                  RBD_MIRROR_PEER_ATTRIBUTE_NAME_MON_HOST,
                  RBD_MIRROR_PEER_ATTRIBUTE_NAME_KEY,
                  RBD_MIRROR_PEER_DIRECTION_RX, RBD_MIRROR_PEER_DIRECTION_RX_TX,
-                 RBD_SNAP_REMOVE_UNPROTECT)
+                 RBD_SNAP_REMOVE_UNPROTECT, RBD_SNAP_MIRROR_STATE_PRIMARY,
+                 RBD_SNAP_MIRROR_STATE_PRIMARY_DEMOTED)
 
 rados = None
 ioctx = None
@@ -2083,8 +2083,8 @@ class TestMirroring(object):
         snaps = list(self.image.list_snaps())
         eq(1, len(snaps))
         snap = snaps[0]
-        eq(snap['namespace'], RBD_SNAP_NAMESPACE_TYPE_MIRROR_PRIMARY)
-        eq(False, snap['mirror_primary']['demoted'])
+        eq(snap['namespace'], RBD_SNAP_NAMESPACE_TYPE_MIRROR)
+        eq(RBD_SNAP_MIRROR_STATE_PRIMARY, snap['mirror']['state'])
 
         info = self.image.mirror_image_get_info()
         eq(True, info['primary'])
@@ -2099,19 +2099,19 @@ class TestMirroring(object):
         snaps = list(self.image.list_snaps())
         eq(2, len(snaps))
         snap = snaps[0]
-        eq(snap['namespace'], RBD_SNAP_NAMESPACE_TYPE_MIRROR_PRIMARY)
-        eq(False, snap['mirror_primary']['demoted'])
+        eq(snap['namespace'], RBD_SNAP_NAMESPACE_TYPE_MIRROR)
+        eq(RBD_SNAP_MIRROR_STATE_PRIMARY, snap['mirror']['state'])
         snap = snaps[1]
         eq(snap['id'], snap_id)
-        eq(snap['namespace'], RBD_SNAP_NAMESPACE_TYPE_MIRROR_PRIMARY)
-        eq(False, snap['mirror_primary']['demoted'])
+        eq(snap['namespace'], RBD_SNAP_NAMESPACE_TYPE_MIRROR)
+        eq(RBD_SNAP_MIRROR_STATE_PRIMARY, snap['mirror']['state'])
         eq(sorted([peer1_uuid, peer2_uuid]),
-           sorted(snap['mirror_primary']['mirror_peer_uuids']))
+           sorted(snap['mirror']['mirror_peer_uuids']))
 
-        eq(RBD_SNAP_NAMESPACE_TYPE_MIRROR_PRIMARY,
+        eq(RBD_SNAP_NAMESPACE_TYPE_MIRROR,
            self.image.snap_get_namespace_type(snap_id))
-        mirror_snap = self.image.snap_get_mirror_primary_namespace(snap_id)
-        eq(mirror_snap, snap['mirror_primary'])
+        mirror_snap = self.image.snap_get_mirror_namespace(snap_id)
+        eq(mirror_snap, snap['mirror'])
 
         self.image.mirror_image_demote()
 
@@ -2120,15 +2120,15 @@ class TestMirroring(object):
         snaps = list(self.image.list_snaps())
         eq(3, len(snaps))
         snap = snaps[0]
-        eq(snap['namespace'], RBD_SNAP_NAMESPACE_TYPE_MIRROR_PRIMARY)
+        eq(snap['namespace'], RBD_SNAP_NAMESPACE_TYPE_MIRROR)
         snap = snaps[1]
         eq(snap['id'], snap_id)
-        eq(snap['namespace'], RBD_SNAP_NAMESPACE_TYPE_MIRROR_PRIMARY)
+        eq(snap['namespace'], RBD_SNAP_NAMESPACE_TYPE_MIRROR)
         snap = snaps[2]
-        eq(snap['namespace'], RBD_SNAP_NAMESPACE_TYPE_MIRROR_PRIMARY)
-        eq(True, snap['mirror_primary']['demoted'])
+        eq(snap['namespace'], RBD_SNAP_NAMESPACE_TYPE_MIRROR)
+        eq(RBD_SNAP_MIRROR_STATE_PRIMARY_DEMOTED, snap['mirror']['state'])
         eq(sorted([peer1_uuid, peer2_uuid]),
-           sorted(snap['mirror_primary']['mirror_peer_uuids']))
+           sorted(snap['mirror']['mirror_peer_uuids']))
 
         self.rbd.mirror_peer_remove(ioctx, peer1_uuid)
         self.rbd.mirror_peer_remove(ioctx, peer2_uuid)
index 833c7658e078d1c6652cbf08b1b10bdaff7fdce4..02fdbf3a7e0b72f92ee30294b6ab24657100337f 100644 (file)
@@ -316,6 +316,7 @@ int execute_status(const po::variables_map &vm,
   librados::IoCtx default_ns_io_ctx;
   default_ns_io_ctx.dup(io_ctx);
   default_ns_io_ctx.set_namespace("");
+
   std::vector<librbd::mirror_peer_site_t> mirror_peers;
   utils::get_mirror_peer_sites(default_ns_io_ctx, &mirror_peers);
 
@@ -384,7 +385,7 @@ int execute_status(const po::variables_map &vm,
                     if (r < 0) {
                       return false;
                     }
-                    return type != RBD_SNAP_NAMESPACE_TYPE_MIRROR_PRIMARY;
+                    return type != RBD_SNAP_NAMESPACE_TYPE_MIRROR;
                   }),
         snaps.end());
     }
@@ -428,16 +429,18 @@ int execute_status(const po::variables_map &vm,
     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) {
+        librbd::snap_mirror_namespace_t info;
+        r = image.snap_get_mirror_namespace(snap.id, &info, sizeof(info));
+        if (r < 0 ||
+            (info.state != RBD_SNAP_MIRROR_STATE_PRIMARY &&
+             info.state != RBD_SNAP_MIRROR_STATE_PRIMARY_DEMOTED)) {
           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->dump_bool("demoted",
+                             info.state == RBD_SNAP_MIRROR_STATE_PRIMARY_DEMOTED);
         formatter->open_array_section("mirror_peer_uuids");
         for (auto &peer : info.mirror_peer_uuids) {
           formatter->dump_string("peer_uuid", peer);
@@ -490,10 +493,11 @@ int execute_status(const po::variables_map &vm,
 
       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) {
+        librbd::snap_mirror_namespace_t info;
+        r = image.snap_get_mirror_namespace(snap.id, &info, sizeof(info));
+        if (r < 0 ||
+            (info.state != RBD_SNAP_MIRROR_STATE_PRIMARY &&
+             info.state != RBD_SNAP_MIRROR_STATE_PRIMARY_DEMOTED)) {
           continue;
         }
 
@@ -503,8 +507,9 @@ int execute_status(const po::variables_map &vm,
 
         first_site = false;
         std::cout << "    " << snap.id << " " << snap.name << " ("
-                  << (info.demoted ? "demoted " : "") << "peer_uuids:["
-                  << info.mirror_peer_uuids << "])";
+                  << (info.state == RBD_SNAP_MIRROR_STATE_PRIMARY_DEMOTED ?
+                        "demoted " : "")
+                  << "peer_uuids:[" << info.mirror_peer_uuids << "])";
       }
       std::cout << std::endl;
     }
index b2e6b665c6e8d92f6383fd0e28749ad91f7ec21a..9fe8806d8ac03a47ce4dd0ffa128eb5d7f5976d7 100644 (file)
@@ -95,11 +95,8 @@ int do_list_snaps(librbd::Image& image, Formatter *f, bool all_snaps, librados::
     case RBD_SNAP_NAMESPACE_TYPE_TRASH:
       snap_namespace_name = "trash";
       break;
-    case RBD_SNAP_NAMESPACE_TYPE_MIRROR_PRIMARY:
-      snap_namespace_name = "mirror_primary";
-      break;
-    case RBD_SNAP_NAMESPACE_TYPE_MIRROR_NON_PRIMARY:
-      snap_namespace_name = "mirror_non_primary";
+    case RBD_SNAP_NAMESPACE_TYPE_MIRROR:
+      snap_namespace_name = "mirror";
       break;
     }
 
@@ -107,22 +104,31 @@ int do_list_snaps(librbd::Image& image, Formatter *f, bool all_snaps, librados::
     std::string trash_original_name;
     int get_group_res = -ENOENT;
     librbd::snap_group_namespace_t group_snap;
-    int get_mirror_primary_res = -ENOENT;
-    librbd::snap_mirror_primary_namespace_t mirror_primary_snap;
-    int get_mirror_non_primary_res = -ENOENT;
-    librbd::snap_mirror_non_primary_namespace_t mirror_non_primary_snap;
+    int get_mirror_res = -ENOENT;
+    librbd::snap_mirror_namespace_t mirror_snap;
+    std::string mirror_snap_state = "unknown";
     if (snap_namespace == RBD_SNAP_NAMESPACE_TYPE_GROUP) {
       get_group_res = image.snap_get_group_namespace(s->id, &group_snap,
                                                      sizeof(group_snap));
     } else if (snap_namespace == RBD_SNAP_NAMESPACE_TYPE_TRASH) {
       get_trash_res = image.snap_get_trash_namespace(
         s->id, &trash_original_name);
-    } else if (snap_namespace == RBD_SNAP_NAMESPACE_TYPE_MIRROR_PRIMARY) {
-      get_mirror_primary_res = image.snap_get_mirror_primary_namespace(
-        s->id, &mirror_primary_snap, sizeof(mirror_primary_snap));
-    } else if (snap_namespace == RBD_SNAP_NAMESPACE_TYPE_MIRROR_NON_PRIMARY) {
-      get_mirror_non_primary_res = image.snap_get_mirror_non_primary_namespace(
-        s->id, &mirror_non_primary_snap, sizeof(mirror_non_primary_snap));
+    } else if (snap_namespace == RBD_SNAP_NAMESPACE_TYPE_MIRROR) {
+      get_mirror_res = image.snap_get_mirror_namespace(
+        s->id, &mirror_snap, sizeof(mirror_snap));
+
+      switch (mirror_snap.state) {
+      case RBD_SNAP_MIRROR_STATE_PRIMARY:
+        mirror_snap_state = "primary";
+        break;
+      case RBD_SNAP_MIRROR_STATE_NON_PRIMARY:
+        mirror_snap_state = "non-primary";
+        break;
+      case RBD_SNAP_MIRROR_STATE_PRIMARY_DEMOTED:
+      case RBD_SNAP_MIRROR_STATE_NON_PRIMARY_DEMOTED:
+        mirror_snap_state = "demoted";
+        break;
+      }
     }
 
     std::string protected_str = "";
@@ -152,21 +158,23 @@ int do_list_snaps(librbd::Image& image, Formatter *f, bool all_snaps, librados::
           f->dump_string("group snap", group_snap.group_snap_name);
         } else if (get_trash_res == 0) {
           f->dump_string("original_name", trash_original_name);
-        } else if (get_mirror_primary_res == 0) {
-          f->dump_bool("demoted", mirror_primary_snap.demoted);
+        } else if (get_mirror_res == 0) {
+          f->dump_string("state", mirror_snap_state);
           f->open_array_section("mirror_peer_uuids");
-          for (auto &uuid : mirror_primary_snap.mirror_peer_uuids) {
+          for (auto &uuid : mirror_snap.mirror_peer_uuids) {
             f->dump_string("peer_uuid", uuid);
           }
           f->close_section();
-        } else if (get_mirror_non_primary_res == 0) {
-          f->dump_string("primary_mirror_uuid",
-                         mirror_non_primary_snap.primary_mirror_uuid);
-          f->dump_unsigned("primary_snap_id",
-                           mirror_non_primary_snap.primary_snap_id);
-          f->dump_bool("copied", mirror_non_primary_snap.copied);
-          f->dump_unsigned("last_copied_object_number",
-                           mirror_non_primary_snap.last_copied_object_number);
+          f->dump_bool("complete", mirror_snap.complete);
+          if (mirror_snap.state == RBD_SNAP_MIRROR_STATE_NON_PRIMARY ||
+              mirror_snap.state == RBD_SNAP_MIRROR_STATE_NON_PRIMARY_DEMOTED) {
+            f->dump_string("primary_mirror_uuid",
+                           mirror_snap.primary_mirror_uuid);
+            f->dump_unsigned("primary_snap_id",
+                             mirror_snap.primary_snap_id);
+            f->dump_unsigned("last_copied_object_number",
+                             mirror_snap.last_copied_object_number);
+          }
         }
         f->close_section();
       }
@@ -186,24 +194,26 @@ int do_list_snaps(librbd::Image& image, Formatter *f, bool all_snaps, librados::
                       << group_snap.group_snap_name << ")";
         } else if (get_trash_res == 0) {
           oss << " (" << trash_original_name << ")";
-        } else if (get_mirror_primary_res == 0) {
-          oss << " (" << (mirror_primary_snap.demoted ? "demoted " : "")
-                      << "peer_uuids:[" << mirror_primary_snap.mirror_peer_uuids
-                      << "])";
-        } else if (get_mirror_non_primary_res == 0) {
-          oss << " (" << mirror_non_primary_snap.primary_mirror_uuid << ":"
-              << mirror_non_primary_snap.primary_snap_id << " ";
-          if (!mirror_non_primary_snap.copied) {
-            if (info.num_objs > 0) {
-              auto progress = std::min<uint64_t>(
-                100, 100 * mirror_non_primary_snap.last_copied_object_number /
-                           info.num_objs);
-              oss << progress << "%";
-            } else {
-              oss << "not ";
+        } else if (get_mirror_res == 0) {
+          oss << " (" << mirror_snap_state << " "
+                      << "peer_uuids:[" << mirror_snap.mirror_peer_uuids << "]";
+          if (mirror_snap.state == RBD_SNAP_MIRROR_STATE_NON_PRIMARY ||
+              mirror_snap.state == RBD_SNAP_MIRROR_STATE_NON_PRIMARY_DEMOTED) {
+            oss  << mirror_snap.primary_mirror_uuid << ":"
+                 << mirror_snap.primary_snap_id << " ";
+            if (!mirror_snap.complete) {
+              if (info.num_objs > 0) {
+                auto progress = std::min<uint64_t>(
+                  100, 100 * mirror_snap.last_copied_object_number /
+                             info.num_objs);
+                oss << progress << "% ";
+              } else {
+                oss << "not ";
+              }
             }
+            oss << "copied";
           }
-          oss << " copied)";
+          oss << ")";
         }
 
         t << oss.str();