]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
cls/rbd: preliminary support for mirror image status from multiple sites
authorJason Dillaman <dillaman@redhat.com>
Fri, 20 Sep 2019 00:38:59 +0000 (20:38 -0400)
committerJason Dillaman <dillaman@redhat.com>
Tue, 8 Oct 2019 15:16:46 +0000 (11:16 -0400)
The mirror_image_status_set method will now accept a MirrorImageSiteStatus
structure. When no site name is provided, it is backwards compatible
with the original MirorrImageStatus parameter, and when a site name
is provided, the setter will fail if not using a new OSD.

The mirror_image_status_get/list methods will now return an extended
MirrorImageStatus which always includes the local site status and
optionally includes the remote site status.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/cls/rbd/cls_rbd.cc
src/cls/rbd/cls_rbd_client.cc
src/cls/rbd/cls_rbd_client.h
src/cls/rbd/cls_rbd_types.cc
src/cls/rbd/cls_rbd_types.h
src/librbd/api/Mirror.cc
src/librbd/mirror/GetStatusRequest.cc
src/test/cls_rbd/test_cls_rbd.cc
src/tools/ceph-dencoder/rbd_types.h
src/tools/rbd_mirror/ImageReplayer.cc

index fc6ad0df719307ddb5041f29173a18ae38bb133f..eb29f5c7e18caa889da0ff17e36865d24a993239 100644 (file)
@@ -5037,8 +5037,8 @@ int image_remove(cls_method_context_t hctx, const string &image_id) {
 }
 
 int image_status_set(cls_method_context_t hctx, const string &global_image_id,
-                    const cls::rbd::MirrorImageStatus &status) {
-  cls::rbd::MirrorImageStatusOnDisk ondisk_status(status);
+                    const cls::rbd::MirrorImageSiteStatus &status) {
+  cls::rbd::MirrorImageSiteStatusOnDisk ondisk_status(status);
   ondisk_status.up = false;
   ondisk_status.last_update = ceph_clock_now();
 
@@ -5084,7 +5084,7 @@ int image_status_get(cls_method_context_t hctx, const string &global_image_id,
     return r;
   }
 
-  cls::rbd::MirrorImageStatusOnDisk ondisk_status;
+  cls::rbd::MirrorImageSiteStatusOnDisk ondisk_status;
   try {
     auto it = bl.cbegin();
     decode(ondisk_status, it);
@@ -5094,9 +5094,9 @@ int image_status_get(cls_method_context_t hctx, const string &global_image_id,
     return -EIO;
   }
 
-
-  *status = static_cast<cls::rbd::MirrorImageStatus>(ondisk_status);
-  status->up = (watchers.find(ondisk_status.origin) != watchers.end());
+  ondisk_status.fsid = cls::rbd::MirrorImageSiteStatus::LOCAL_FSID;
+  ondisk_status.up = (watchers.find(ondisk_status.origin) != watchers.end());
+  *status = {{ondisk_status}};
   return 0;
 }
 
@@ -5204,8 +5204,10 @@ int image_status_get_summary(
       cls::rbd::MirrorImageStatus status;
       image_status_get(hctx, mirror_image.global_image_id, watchers, &status);
 
-      cls::rbd::MirrorImageStatusState state = status.up ? status.state :
-       cls::rbd::MIRROR_IMAGE_STATUS_STATE_UNKNOWN;
+      cls::rbd::MirrorImageSiteStatus local_status;
+      r = status.get_local_mirror_image_site_status(&local_status);
+      cls::rbd::MirrorImageStatusState state = (r >= 0 && local_status.up ?
+        local_status.state : cls::rbd::MIRROR_IMAGE_STATUS_STATE_UNKNOWN);
       (*states)[state]++;
     }
 
@@ -5246,7 +5248,7 @@ int image_status_remove_down(cls_method_context_t hctx) {
        break;
       }
 
-      cls::rbd::MirrorImageStatusOnDisk status;
+      cls::rbd::MirrorImageSiteStatusOnDisk status;
       try {
        auto it = list_it.second.cbegin();
        status.decode_meta(it);
@@ -5290,7 +5292,7 @@ int image_instance_get(cls_method_context_t hctx,
     return r;
   }
 
-  cls::rbd::MirrorImageStatusOnDisk ondisk_status;
+  cls::rbd::MirrorImageSiteStatusOnDisk ondisk_status;
   try {
     auto it = bl.cbegin();
     decode(ondisk_status, it);
@@ -5991,7 +5993,7 @@ int mirror_image_remove(cls_method_context_t hctx, bufferlist *in,
 /**
  * Input:
  * @param global_image_id (std::string)
- * @param status (cls::rbd::MirrorImageStatus)
+ * @param status (cls::rbd::MirrorImageSiteStatus)
  *
  * Output:
  * @returns 0 on success, negative error code on failure
@@ -5999,7 +6001,7 @@ int mirror_image_remove(cls_method_context_t hctx, bufferlist *in,
 int mirror_image_status_set(cls_method_context_t hctx, bufferlist *in,
                            bufferlist *out) {
   string global_image_id;
-  cls::rbd::MirrorImageStatus status;
+  cls::rbd::MirrorImageSiteStatus status;
   try {
     auto it = in->cbegin();
     decode(global_image_id, it);
index a8df333e3f79f59b694204cd92ec3b6a27c4da6b..d9d6d86d12318f5d3249ecc2d8c37ca23fe3a7fc 100644 (file)
@@ -2071,7 +2071,7 @@ int mirror_image_remove(librados::IoCtx *ioctx, const std::string &image_id) {
 
 int mirror_image_status_set(librados::IoCtx *ioctx,
                             const std::string &global_image_id,
-                            const cls::rbd::MirrorImageStatus &status) {
+                            const cls::rbd::MirrorImageSiteStatus &status) {
   librados::ObjectWriteOperation op;
   mirror_image_status_set(&op, global_image_id, status);
   return ioctx->operate(RBD_MIRRORING, &op);
@@ -2079,7 +2079,7 @@ int mirror_image_status_set(librados::IoCtx *ioctx,
 
 void mirror_image_status_set(librados::ObjectWriteOperation *op,
                              const std::string &global_image_id,
-                             const cls::rbd::MirrorImageStatus &status) {
+                             const cls::rbd::MirrorImageSiteStatus &status) {
   bufferlist bl;
   encode(global_image_id, bl);
   encode(status, bl);
index 29337e7293bba0b98766ce62aae1ee722adb31f0..70d77284e380ccc1bb57a793d72722c799121b55 100644 (file)
@@ -434,10 +434,10 @@ int mirror_image_remove(librados::IoCtx *ioctx,
                         const std::string &image_id);
 int mirror_image_status_set(librados::IoCtx *ioctx,
                             const std::string &global_image_id,
-                            const cls::rbd::MirrorImageStatus &status);
+                            const cls::rbd::MirrorImageSiteStatus &status);
 void mirror_image_status_set(librados::ObjectWriteOperation *op,
                              const std::string &global_image_id,
-                             const cls::rbd::MirrorImageStatus &status);
+                             const cls::rbd::MirrorImageSiteStatus &status);
 int mirror_image_status_get(librados::IoCtx *ioctx,
                             const std::string &global_image_id,
                             cls::rbd::MirrorImageStatus *status);
index 29ddd7b3d03d686e5467cec406557240a13e7c44..32c28dd08b044ef055fe6a7f765bcc113567aa9f 100644 (file)
@@ -208,83 +208,252 @@ std::ostream& operator<<(std::ostream& os,
   return os;
 }
 
-void MirrorImageStatus::encode(bufferlist &bl) const {
-  ENCODE_START(1, 1, bl);
-  encode(state, bl);
-  encode(description, bl);
-  encode(last_update, bl);
-  encode(up, bl);
+const std::string MirrorImageSiteStatus::LOCAL_FSID(""); // empty fsid
+
+void MirrorImageSiteStatus::encode_meta(uint8_t version, bufferlist &bl) const {
+  if (version >= 2) {
+    ceph::encode(fsid, bl);
+  }
+  cls::rbd::encode(state, bl);
+  ceph::encode(description, bl);
+  ceph::encode(last_update, bl);
+  ceph::encode(up, bl);
+}
+
+void MirrorImageSiteStatus::decode_meta(uint8_t version,
+                                        bufferlist::const_iterator &it) {
+  if (version < 2) {
+    fsid = LOCAL_FSID;
+  } else {
+    ceph::decode(fsid, it);
+  }
+
+  cls::rbd::decode(state, it);
+  ceph::decode(description, it);
+  ::decode(last_update, it);
+  ceph::decode(up, it);
+}
+
+void MirrorImageSiteStatus::encode(bufferlist &bl) const {
+  // break compatibility when site-name is provided
+  uint8_t version = (fsid == LOCAL_FSID ? 1 : 2);
+  ENCODE_START(version, version, bl);
+  encode_meta(version, bl);
   ENCODE_FINISH(bl);
 }
 
-void MirrorImageStatus::decode(bufferlist::const_iterator &it) {
-  DECODE_START(1, it);
-  decode(state, it);
-  decode(description, it);
-  decode(last_update, it);
-  decode(up, it);
+void MirrorImageSiteStatus::decode(bufferlist::const_iterator &it) {
+  DECODE_START(2, it);
+  decode_meta(struct_v, it);
   DECODE_FINISH(it);
 }
 
-void MirrorImageStatus::dump(Formatter *f) const {
+void MirrorImageSiteStatus::dump(Formatter *f) const {
   f->dump_string("state", state_to_string());
   f->dump_string("description", description);
   f->dump_stream("last_update") << last_update;
 }
 
-std::string MirrorImageStatus::state_to_string() const {
+std::string MirrorImageSiteStatus::state_to_string() const {
   std::stringstream ss;
   ss << (up ? "up+" : "down+") << state;
   return ss.str();
 }
 
-void MirrorImageStatus::generate_test_instances(
-  std::list<MirrorImageStatus*> &o) {
-  o.push_back(new MirrorImageStatus());
-  o.push_back(new MirrorImageStatus(MIRROR_IMAGE_STATUS_STATE_REPLAYING));
-  o.push_back(new MirrorImageStatus(MIRROR_IMAGE_STATUS_STATE_ERROR, "error"));
+void MirrorImageSiteStatus::generate_test_instances(
+  std::list<MirrorImageSiteStatus*> &o) {
+  o.push_back(new MirrorImageSiteStatus());
+  o.push_back(new MirrorImageSiteStatus("", MIRROR_IMAGE_STATUS_STATE_REPLAYING,
+                                        ""));
+  o.push_back(new MirrorImageSiteStatus("", MIRROR_IMAGE_STATUS_STATE_ERROR,
+                                        "error"));
+  o.push_back(new MirrorImageSiteStatus("2fb68ca9-1ba0-43b3-8cdf-8c5a9db71e65",
+                                        MIRROR_IMAGE_STATUS_STATE_STOPPED, ""));
 }
 
-bool MirrorImageStatus::operator==(const MirrorImageStatus &rhs) const {
+bool MirrorImageSiteStatus::operator==(const MirrorImageSiteStatus &rhs) const {
   return state == rhs.state && description == rhs.description && up == rhs.up;
 }
 
-std::ostream& operator<<(std::ostream& os, const MirrorImageStatus& status) {
-  os << "["
+std::ostream& operator<<(std::ostream& os,
+                         const MirrorImageSiteStatus& status) {
+  os << "{"
      << "state=" << status.state_to_string() << ", "
      << "description=" << status.description << ", "
-     << "last_update=" << status.last_update << "]";
+     << "last_update=" << status.last_update << "]}";
   return os;
 }
 
-void MirrorImageStatusOnDisk::encode_meta(bufferlist &bl,
-                                          uint64_t features) const {
+void MirrorImageSiteStatusOnDisk::encode_meta(bufferlist &bl,
+                                              uint64_t features) const {
   ENCODE_START(1, 1, bl);
   encode(origin, bl, features);
   ENCODE_FINISH(bl);
 }
 
-void MirrorImageStatusOnDisk::encode(bufferlist &bl, uint64_t features) const {
+void MirrorImageSiteStatusOnDisk::encode(bufferlist &bl,
+                                         uint64_t features) const {
   encode_meta(bl, features);
-  cls::rbd::MirrorImageStatus::encode(bl);
+  cls::rbd::MirrorImageSiteStatus::encode(bl);
 }
 
-void MirrorImageStatusOnDisk::decode_meta(bufferlist::const_iterator &it) {
+void MirrorImageSiteStatusOnDisk::decode_meta(bufferlist::const_iterator &it) {
   DECODE_START(1, it);
   decode(origin, it);
   DECODE_FINISH(it);
 }
 
-void MirrorImageStatusOnDisk::decode(bufferlist::const_iterator &it) {
+void MirrorImageSiteStatusOnDisk::decode(bufferlist::const_iterator &it) {
   decode_meta(it);
-  cls::rbd::MirrorImageStatus::decode(it);
+  cls::rbd::MirrorImageSiteStatus::decode(it);
+}
+
+void MirrorImageSiteStatusOnDisk::generate_test_instances(
+    std::list<MirrorImageSiteStatusOnDisk*> &o) {
+  o.push_back(new MirrorImageSiteStatusOnDisk());
+  o.push_back(new MirrorImageSiteStatusOnDisk(
+    {"", MIRROR_IMAGE_STATUS_STATE_ERROR, "error"}));
+  o.push_back(new MirrorImageSiteStatusOnDisk(
+    {"siteA", MIRROR_IMAGE_STATUS_STATE_STOPPED, ""}));
+}
+
+int MirrorImageStatus::get_local_mirror_image_site_status(
+    MirrorImageSiteStatus* status) const {
+  auto it = std::find_if(
+    mirror_image_site_statuses.begin(),
+    mirror_image_site_statuses.end(),
+    [](const MirrorImageSiteStatus& status) {
+      return status.fsid == MirrorImageSiteStatus::LOCAL_FSID;
+    });
+  if (it == mirror_image_site_statuses.end()) {
+    return -ENOENT;
+  }
+
+  *status = *it;
+  return 0;
 }
 
-void MirrorImageStatusOnDisk::generate_test_instances(
-    std::list<MirrorImageStatusOnDisk*> &o) {
-  o.push_back(new MirrorImageStatusOnDisk());
-  o.push_back(new MirrorImageStatusOnDisk(
-    {MIRROR_IMAGE_STATUS_STATE_ERROR, "error"}));
+void MirrorImageStatus::encode(bufferlist &bl) const {
+  // don't break compatibility for extra site statuses
+  ENCODE_START(2, 1, bl);
+
+  // local site status
+  MirrorImageSiteStatus local_status;
+  int r = get_local_mirror_image_site_status(&local_status);
+  local_status.encode_meta(1, bl);
+
+  bool local_status_valid = (r >= 0);
+  encode(local_status_valid, bl);
+
+  // remote site statuses
+  __u32 n = mirror_image_site_statuses.size();
+  if (local_status_valid) {
+    --n;
+  }
+  encode(n, bl);
+
+  for (auto& status : mirror_image_site_statuses) {
+    if (status.fsid == MirrorImageSiteStatus::LOCAL_FSID) {
+      continue;
+    }
+    status.encode_meta(2, bl);
+  }
+  ENCODE_FINISH(bl);
+}
+
+void MirrorImageStatus::decode(bufferlist::const_iterator &it) {
+  DECODE_START(2, it);
+
+  // local site status
+  MirrorImageSiteStatus local_status;
+  local_status.decode_meta(1, it);
+
+  if (struct_v < 2) {
+    mirror_image_site_statuses.push_back(local_status);
+  } else {
+    bool local_status_valid;
+    decode(local_status_valid, it);
+
+    __u32 n;
+    decode(n, it);
+    if (local_status_valid) {
+      ++n;
+    }
+
+    mirror_image_site_statuses.resize(n);
+    for (auto status_it = mirror_image_site_statuses.begin();
+         status_it != mirror_image_site_statuses.end(); ++status_it) {
+      if (local_status_valid &&
+          status_it == mirror_image_site_statuses.begin()) {
+        *status_it = local_status;
+        continue;
+      }
+
+      // remote site status
+      status_it->decode_meta(struct_v, it);
+    }
+  }
+  DECODE_FINISH(it);
+}
+
+void MirrorImageStatus::dump(Formatter *f) const {
+  MirrorImageSiteStatus local_status;
+  int r = get_local_mirror_image_site_status(&local_status);
+  if (r >= 0) {
+    local_status.dump(f);
+  }
+
+  f->open_array_section("remotes");
+  for (auto& status : mirror_image_site_statuses) {
+    if (status.fsid == MirrorImageSiteStatus::LOCAL_FSID) {
+      continue;
+    }
+
+    f->open_object_section("remote");
+    status.dump(f);
+    f->close_section();
+  }
+  f->close_section();
+}
+
+bool MirrorImageStatus::operator==(const MirrorImageStatus &rhs) const {
+  return (mirror_image_site_statuses == rhs.mirror_image_site_statuses);
+}
+
+void MirrorImageStatus::generate_test_instances(
+    std::list<MirrorImageStatus*> &o) {
+  o.push_back(new MirrorImageStatus());
+  o.push_back(new MirrorImageStatus({{"", MIRROR_IMAGE_STATUS_STATE_ERROR, ""}}));
+  o.push_back(new MirrorImageStatus({{"", MIRROR_IMAGE_STATUS_STATE_STOPPED, ""},
+                                     {"siteA", MIRROR_IMAGE_STATUS_STATE_REPLAYING, ""}}));
+}
+
+std::ostream& operator<<(std::ostream& os,
+                         const MirrorImageStatus& status) {
+  os << "{";
+  MirrorImageSiteStatus local_status;
+  int r = status.get_local_mirror_image_site_status(&local_status);
+  if (r >= 0) {
+    os << "state=" << local_status.state_to_string() << ", "
+       << "description=" << local_status.description << ", "
+       << "last_update=" << local_status.last_update << ", ";
+  }
+
+  os << "remotes=[";
+  for (auto& remote_status : status.mirror_image_site_statuses) {
+    if (remote_status.fsid == MirrorImageSiteStatus::LOCAL_FSID) {
+      continue;
+    }
+
+    os << "{"
+       << "fsid=" << remote_status.fsid << ", "
+       << "state=" << remote_status.state_to_string() << ", "
+       << "description=" << remote_status.description << ", "
+       << "last_update=" << remote_status.last_update
+       << "}";
+  }
+  os << "]}";
+  return os;
 }
 
 void ParentImageSpec::encode(bufferlist& bl) const {
index cbeaaca678be4a1edcb346945eb153d1b667d852..a287f72a4539408977e3484ad5a099134306bd1d 100644 (file)
@@ -177,7 +177,8 @@ inline void encode(const MirrorImageStatusState &state, bufferlist& bl,
   encode(static_cast<uint8_t>(state), bl);
 }
 
-inline void decode(MirrorImageStatusState &state, bufferlist::const_iterator& it)
+inline void decode(MirrorImageStatusState &state,
+                   bufferlist::const_iterator& it)
 {
   uint8_t int_state;
   using ceph::decode;
@@ -187,39 +188,46 @@ inline void decode(MirrorImageStatusState &state, bufferlist::const_iterator& it
 
 std::ostream& operator<<(std::ostream& os, const MirrorImageStatusState& state);
 
-struct MirrorImageStatus {
-  MirrorImageStatus() {}
-  MirrorImageStatus(MirrorImageStatusState state,
-                   const std::string &description = "")
-    : state(state), description(description) {}
+struct MirrorImageSiteStatus {
+  static const std::string LOCAL_FSID;
+
+  MirrorImageSiteStatus() {}
+  MirrorImageSiteStatus(const std::string& fsid,
+                        MirrorImageStatusState state,
+                        const std::string &description)
+    : fsid(fsid), state(state), description(description) {
+  }
 
+  std::string fsid = LOCAL_FSID;
   MirrorImageStatusState state = MIRROR_IMAGE_STATUS_STATE_UNKNOWN;
   std::string description;
   utime_t last_update;
   bool up = false;
 
+  void encode_meta(uint8_t version, bufferlist &bl) const;
+  void decode_meta(uint8_t version, bufferlist::const_iterator &it);
+
   void encode(bufferlist &bl) const;
   void decode(bufferlist::const_iterator &it);
   void dump(Formatter *f) const;
 
   std::string state_to_string() const;
 
-  static void generate_test_instances(std::list<MirrorImageStatus*> &o);
+  bool operator==(const MirrorImageSiteStatus &rhs) const;
 
-  bool operator==(const MirrorImageStatus &rhs) const;
+  static void generate_test_instances(std::list<MirrorImageSiteStatus*> &o);
 };
+WRITE_CLASS_ENCODER(MirrorImageSiteStatus);
 
-std::ostream& operator<<(std::ostream& os, const MirrorImageStatus& status);
-
-WRITE_CLASS_ENCODER(MirrorImageStatus);
+std::ostream& operator<<(std::ostream& os, const MirrorImageSiteStatus& status);
 
-struct MirrorImageStatusOnDisk : cls::rbd::MirrorImageStatus {
+struct MirrorImageSiteStatusOnDisk : cls::rbd::MirrorImageSiteStatus {
   entity_inst_t origin;
 
-  MirrorImageStatusOnDisk() {
+  MirrorImageSiteStatusOnDisk() {
   }
-  MirrorImageStatusOnDisk(const cls::rbd::MirrorImageStatus &status) :
-    cls::rbd::MirrorImageStatus(status) {
+  MirrorImageSiteStatusOnDisk(const cls::rbd::MirrorImageSiteStatus &status) :
+    cls::rbd::MirrorImageSiteStatus(status) {
   }
 
   void encode_meta(bufferlist &bl, uint64_t features) const;
@@ -228,9 +236,34 @@ struct MirrorImageStatusOnDisk : cls::rbd::MirrorImageStatus {
   void encode(bufferlist &bl, uint64_t features) const;
   void decode(bufferlist::const_iterator &it);
 
-  static void generate_test_instances(std::list<MirrorImageStatusOnDisk*> &o);
+  static void generate_test_instances(
+      std::list<MirrorImageSiteStatusOnDisk*> &o);
 };
-WRITE_CLASS_ENCODER_FEATURES(MirrorImageStatusOnDisk)
+WRITE_CLASS_ENCODER_FEATURES(MirrorImageSiteStatusOnDisk)
+
+struct MirrorImageStatus {
+  typedef std::list<MirrorImageSiteStatus> MirrorImageSiteStatuses;
+
+  MirrorImageStatus() {}
+  MirrorImageStatus(const MirrorImageSiteStatuses& statuses)
+    : mirror_image_site_statuses(statuses) {
+  }
+
+  MirrorImageSiteStatuses mirror_image_site_statuses;
+
+  int get_local_mirror_image_site_status(MirrorImageSiteStatus* status) const;
+
+  void encode(bufferlist &bl) const;
+  void decode(bufferlist::const_iterator &it);
+  void dump(Formatter *f) const;
+
+  bool operator==(const MirrorImageStatus& rhs) const;
+
+  static void generate_test_instances(std::list<MirrorImageStatus*> &o);
+};
+WRITE_CLASS_ENCODER(MirrorImageStatus);
+
+std::ostream& operator<<(std::ostream& os, const MirrorImageStatus& status);
 
 struct ParentImageSpec {
   int64_t pool_id = -1;
index 412d6a0a5d68df58e9ce1e058499a49c1b736a49..44305701d5cb283a6b7d78169f7b7e252a635173 100644 (file)
@@ -333,12 +333,20 @@ struct C_ImageGetStatus : public C_ImageGetInfo {
     }
 
     mirror_image_status->name = image_name;
+
+    cls::rbd::MirrorImageSiteStatus local_status;
+    r = mirror_image_status_internal.get_local_mirror_image_site_status(
+      &local_status);
+    if (r < 0) {
+      on_finish->complete(r);
+      return;
+    }
+
     mirror_image_status->state = static_cast<mirror_image_status_state_t>(
-      mirror_image_status_internal.state);
-    mirror_image_status->description = mirror_image_status_internal.description;
-    mirror_image_status->last_update =
-      mirror_image_status_internal.last_update.sec();
-    mirror_image_status->up = mirror_image_status_internal.up;
+      local_status.state);
+    mirror_image_status->description = local_status.description;
+    mirror_image_status->last_update = local_status.last_update.sec();
+    mirror_image_status->up = local_status.up;
     C_ImageGetInfo::finish(0);
   }
 };
@@ -1446,7 +1454,8 @@ int Mirror<I>::image_status_list(librados::IoCtx& io_ctx,
     return r;
   }
 
-  cls::rbd::MirrorImageStatus unknown_status(
+  cls::rbd::MirrorImageSiteStatus unknown_status(
+    cls::rbd::MirrorImageSiteStatus::LOCAL_FSID,
     cls::rbd::MIRROR_IMAGE_STATUS_STATE_UNKNOWN, "status not found");
 
   for (auto it = images_.begin(); it != images_.end(); ++it) {
@@ -1462,8 +1471,13 @@ int Mirror<I>::image_status_list(librados::IoCtx& io_ctx,
                 << "using image id as name" << dendl;
       image_name = image_id;
     }
+
+    auto s = unknown_status;
     auto s_it = statuses_.find(image_id);
-    auto &s = s_it != statuses_.end() ? s_it->second : unknown_status;
+    if (s_it != statuses_.end()) {
+      s_it->second.get_local_mirror_image_site_status(&s);
+    }
+
     (*images)[image_id] = mirror_image_status_t{
       image_name,
       mirror_image_info_t{
index 570968831e3f6b569a445c15a8fbe405444c5128..e6b7f81843649f9ded3fb72b939f7dbbde9f756f 100644 (file)
@@ -25,7 +25,8 @@ using librbd::util::create_rados_callback;
 template <typename I>
 void GetStatusRequest<I>::send() {
   *m_mirror_image_status = cls::rbd::MirrorImageStatus(
-    cls::rbd::MIRROR_IMAGE_STATUS_STATE_UNKNOWN, "status not found");
+    {{cls::rbd::MirrorImageSiteStatus::LOCAL_FSID,
+      cls::rbd::MIRROR_IMAGE_STATUS_STATE_UNKNOWN, "status not found"}});
 
   get_info();
 }
index 7be6a642a6c7100e2e364ffd8c426d6337e170c5..599b96953d22621dace364210d96ab72525fe732 100644 (file)
@@ -1825,9 +1825,12 @@ TEST_F(TestClsRbd, mirror_image_status) {
   ASSERT_EQ(0, mirror_image_set(&ioctx, "image_id2", image2));
   ASSERT_EQ(0, mirror_image_set(&ioctx, "image_id3", image3));
 
-  cls::rbd::MirrorImageStatus status1(cls::rbd::MIRROR_IMAGE_STATUS_STATE_UNKNOWN);
-  cls::rbd::MirrorImageStatus status2(cls::rbd::MIRROR_IMAGE_STATUS_STATE_REPLAYING);
-  cls::rbd::MirrorImageStatus status3(cls::rbd::MIRROR_IMAGE_STATUS_STATE_ERROR);
+  cls::rbd::MirrorImageSiteStatus status1(
+    "", cls::rbd::MIRROR_IMAGE_STATUS_STATE_UNKNOWN, "");
+  cls::rbd::MirrorImageSiteStatus status2(
+    "", cls::rbd::MIRROR_IMAGE_STATUS_STATE_REPLAYING, "");
+  cls::rbd::MirrorImageSiteStatus status3(
+    "", cls::rbd::MIRROR_IMAGE_STATUS_STATE_ERROR, "");
 
   ASSERT_EQ(0, mirror_image_status_set(&ioctx, "uuid1", status1));
   images.clear();
@@ -1839,9 +1842,9 @@ TEST_F(TestClsRbd, mirror_image_status) {
   // Test status is down due to RBD_MIRRORING is not watched
 
   status1.up = false;
-  ASSERT_EQ(statuses["image_id1"], status1);
+  ASSERT_EQ(statuses["image_id1"], cls::rbd::MirrorImageStatus{{status1}});
   ASSERT_EQ(0, mirror_image_status_get(&ioctx, "uuid1", &read_status));
-  ASSERT_EQ(read_status, status1);
+  ASSERT_EQ(read_status, cls::rbd::MirrorImageStatus{{status1}});
 
   // Test status summary. All statuses are unknown due to down.
   states.clear();
@@ -1880,22 +1883,22 @@ TEST_F(TestClsRbd, mirror_image_status) {
 
   ASSERT_EQ(0, mirror_image_status_get(&ioctx, "uuid1", &read_status));
   status1.up = true;
-  ASSERT_EQ(read_status, status1);
+  ASSERT_EQ(read_status, cls::rbd::MirrorImageStatus{{status1}});
   ASSERT_EQ(0, mirror_image_status_get(&ioctx, "uuid2", &read_status));
   status2.up = true;
-  ASSERT_EQ(read_status, status2);
+  ASSERT_EQ(read_status, cls::rbd::MirrorImageStatus{{status2}});
   ASSERT_EQ(0, mirror_image_status_get(&ioctx, "uuid3", &read_status));
   status3.up = true;
-  ASSERT_EQ(read_status, status3);
+  ASSERT_EQ(read_status, cls::rbd::MirrorImageStatus{{status3}});
 
   images.clear();
   statuses.clear();
   ASSERT_EQ(0, mirror_image_status_list(&ioctx, "", 1024, &images, &statuses));
   ASSERT_EQ(3U, images.size());
   ASSERT_EQ(3U, statuses.size());
-  ASSERT_EQ(statuses["image_id1"], status1);
-  ASSERT_EQ(statuses["image_id2"], status2);
-  ASSERT_EQ(statuses["image_id3"], status3);
+  ASSERT_EQ(statuses["image_id1"], cls::rbd::MirrorImageStatus{{status1}});
+  ASSERT_EQ(statuses["image_id2"], cls::rbd::MirrorImageStatus{{status2}});
+  ASSERT_EQ(statuses["image_id3"], cls::rbd::MirrorImageStatus{{status3}});
 
   read_instance = {};
   ASSERT_EQ(0, mirror_image_instance_get(&ioctx, "uuid1", &read_instance));
@@ -1909,15 +1912,15 @@ TEST_F(TestClsRbd, mirror_image_status) {
 
   ASSERT_EQ(0, mirror_image_status_remove_down(&ioctx));
   ASSERT_EQ(0, mirror_image_status_get(&ioctx, "uuid1", &read_status));
-  ASSERT_EQ(read_status, status1);
+  ASSERT_EQ(read_status, cls::rbd::MirrorImageStatus{{status1}});
   images.clear();
   statuses.clear();
   ASSERT_EQ(0, mirror_image_status_list(&ioctx, "", 1024, &images, &statuses));
   ASSERT_EQ(3U, images.size());
   ASSERT_EQ(3U, statuses.size());
-  ASSERT_EQ(statuses["image_id1"], status1);
-  ASSERT_EQ(statuses["image_id2"], status2);
-  ASSERT_EQ(statuses["image_id3"], status3);
+  ASSERT_EQ(statuses["image_id1"], cls::rbd::MirrorImageStatus{{status1}});
+  ASSERT_EQ(statuses["image_id2"], cls::rbd::MirrorImageStatus{{status2}});
+  ASSERT_EQ(statuses["image_id3"], cls::rbd::MirrorImageStatus{{status3}});
 
   states.clear();
   ASSERT_EQ(0, mirror_image_status_get_summary(&ioctx, &states));
@@ -1932,7 +1935,7 @@ TEST_F(TestClsRbd, mirror_image_status) {
   ASSERT_EQ(0, mirror_image_status_set(&ioctx, "uuid1", status1));
   ASSERT_EQ(0, mirror_image_status_set(&ioctx, "uuid3", status3));
   ASSERT_EQ(0, mirror_image_status_get(&ioctx, "uuid3", &read_status));
-  ASSERT_EQ(read_status, status3);
+  ASSERT_EQ(read_status, cls::rbd::MirrorImageStatus{{status3}});
 
   states.clear();
   ASSERT_EQ(0, mirror_image_status_get_summary(&ioctx, &states));
@@ -1950,9 +1953,9 @@ TEST_F(TestClsRbd, mirror_image_status) {
   ASSERT_EQ(0, mirror_image_status_list(&ioctx, "", 1024, &images, &statuses));
   ASSERT_EQ(3U, images.size());
   ASSERT_EQ(3U, statuses.size());
-  ASSERT_EQ(statuses["image_id1"], status1);
-  ASSERT_EQ(statuses["image_id2"], status2);
-  ASSERT_EQ(statuses["image_id3"], status3);
+  ASSERT_EQ(statuses["image_id1"], cls::rbd::MirrorImageStatus{{status1}});
+  ASSERT_EQ(statuses["image_id2"], cls::rbd::MirrorImageStatus{{status2}});
+  ASSERT_EQ(statuses["image_id3"], cls::rbd::MirrorImageStatus{{status3}});
 
   ioctx.unwatch2(watch_handle);
 
@@ -1960,14 +1963,14 @@ TEST_F(TestClsRbd, mirror_image_status) {
   ASSERT_EQ(3U, images.size());
   ASSERT_EQ(3U, statuses.size());
   status1.up = false;
-  ASSERT_EQ(statuses["image_id1"], status1);
+  ASSERT_EQ(statuses["image_id1"], cls::rbd::MirrorImageStatus{{status1}});
   status2.up = false;
-  ASSERT_EQ(statuses["image_id2"], status2);
+  ASSERT_EQ(statuses["image_id2"], cls::rbd::MirrorImageStatus{{status2}});
   status3.up = false;
-  ASSERT_EQ(statuses["image_id3"], status3);
+  ASSERT_EQ(statuses["image_id3"], cls::rbd::MirrorImageStatus{{status3}});
 
   ASSERT_EQ(0, mirror_image_status_get(&ioctx, "uuid1", &read_status));
-  ASSERT_EQ(read_status, status1);
+  ASSERT_EQ(read_status, cls::rbd::MirrorImageStatus{{status1}});
 
   states.clear();
   ASSERT_EQ(0, mirror_image_status_get_summary(&ioctx, &states));
@@ -2020,7 +2023,8 @@ TEST_F(TestClsRbd, mirror_image_status) {
     std::string id = "id" + stringify(i);
     std::string uuid = "uuid" + stringify(i);
     cls::rbd::MirrorImage image(uuid, cls::rbd::MIRROR_IMAGE_STATE_ENABLED);
-    cls::rbd::MirrorImageStatus status(cls::rbd::MIRROR_IMAGE_STATUS_STATE_UNKNOWN);
+    cls::rbd::MirrorImageSiteStatus status(
+      "", cls::rbd::MIRROR_IMAGE_STATUS_STATE_UNKNOWN, "");
     ASSERT_EQ(0, mirror_image_set(&ioctx, id, image));
     ASSERT_EQ(0, mirror_image_status_set(&ioctx, uuid, status));
   }
index 17f564fa89233b80e12d530fd98825df0206be5e..3228318b59bbf70147962812c0fdfd7a3dccb938 100644 (file)
@@ -32,7 +32,8 @@ TYPE(cls::rbd::MirrorPeer)
 TYPE(cls::rbd::MirrorImage)
 TYPE(cls::rbd::MirrorImageMap)
 TYPE(cls::rbd::MirrorImageStatus)
-TYPE_FEATUREFUL(cls::rbd::MirrorImageStatusOnDisk)
+TYPE(cls::rbd::MirrorImageSiteStatus)
+TYPE_FEATUREFUL(cls::rbd::MirrorImageSiteStatusOnDisk)
 TYPE(cls::rbd::GroupImageSpec)
 TYPE(cls::rbd::GroupImageStatus)
 TYPE(cls::rbd::GroupSnapshot)
index b6f5de73be1edbb56abdb3563acaabd1dc2be20d..f11cf783783a22f0cac3bce88d5ce9b4f412a970 100644 (file)
@@ -1360,7 +1360,7 @@ void ImageReplayer<I>::send_mirror_status_update(const OptionalState &opt_state)
     state = *opt_state;
   }
 
-  cls::rbd::MirrorImageStatus status;
+  cls::rbd::MirrorImageSiteStatus status;
   status.up = true;
   switch (state) {
   case STATE_STARTING: