]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: don't send 'image updated' notifications
authorMykola Golub <mgolub@suse.com>
Fri, 18 Dec 2020 10:15:11 +0000 (10:15 +0000)
committerPrasanna Kumar Kalever <prasanna.kalever@redhat.com>
Thu, 24 Apr 2025 15:56:22 +0000 (21:26 +0530)
when enabling/disabling group mirroring

Signed-off-by: Mykola Golub <mgolub@suse.com>
Signed-off-by: Prasanna Kumar Kalever <prasanna.kalever@redhat.com>
src/librbd/mirror/ImageRemoveRequest.cc
src/librbd/mirror/ImageRemoveRequest.h
src/librbd/mirror/ImageStateUpdateRequest.cc
src/librbd/mirror/ImageStateUpdateRequest.h

index 1aa265dae6033470719a7bf09315ec03e4980525..542d38d5697ef2ff7d759046af28a82c3a649071 100644 (file)
@@ -28,6 +28,90 @@ ImageRemoveRequest<I>::ImageRemoveRequest(
 
 template <typename I>
 void ImageRemoveRequest<I>::send() {
+  get_group();
+}
+
+template <typename I>
+void ImageRemoveRequest<I>::get_group() {
+  ldout(m_cct, 10) << dendl;
+  librados::ObjectReadOperation op;
+  cls_client::image_group_get_start(&op);
+
+  auto comp = create_rados_callback<
+    ImageRemoveRequest<I>, &ImageRemoveRequest<I>::handle_get_group>(this);
+  m_out_bl.clear();
+  int r = m_io_ctx.aio_operate(util::header_name(m_image_id), comp, &op,
+                               &m_out_bl);
+  ceph_assert(r == 0);
+  comp->release();
+}
+
+template <typename I>
+void ImageRemoveRequest<I>::handle_get_group(int r) {
+  ldout(m_cct, 10) << "r=" << r << dendl;
+
+  if (r == 0) {
+    auto iter = m_out_bl.cbegin();
+    r = cls_client::image_group_get_finish(&iter, &m_group_spec);
+  }
+
+  if (r < 0) {
+    lderr(m_cct) << "failed to retrieve image group: " << cpp_strerror(r)
+                 << dendl;
+    finish(r);
+    return;
+  }
+
+  get_mirror_group();
+}
+
+template <typename I>
+void ImageRemoveRequest<I>::get_mirror_group() {
+  if (!m_group_spec.is_valid()) {
+    m_mirror_group.state = cls::rbd::MIRROR_GROUP_STATE_DISABLED;
+    remove_mirror_image();
+    return;
+  }
+
+  ldout(m_cct, 10) << dendl;
+
+  int r = util::create_ioctx(m_io_ctx, "group", m_group_spec.pool_id, {},
+                             &m_group_io_ctx);
+  if (r < 0) {
+    finish(r);
+    return;
+  }
+
+  librados::ObjectReadOperation op;
+  cls_client::mirror_group_get_start(&op, m_group_spec.group_id);
+
+  auto comp = create_rados_callback<
+    ImageRemoveRequest<I>,
+    &ImageRemoveRequest<I>::handle_get_mirror_group>(this);
+  m_out_bl.clear();
+  r = m_group_io_ctx.aio_operate(RBD_MIRRORING, comp, &op, &m_out_bl);
+  ceph_assert(r == 0);
+  comp->release();
+}
+
+template <typename I>
+void ImageRemoveRequest<I>::handle_get_mirror_group(int r) {
+  ldout(m_cct, 10) << "r=" << r << dendl;
+
+  if (r == 0) {
+    auto iter = m_out_bl.cbegin();
+    r = cls_client::mirror_group_get_finish(&iter, &m_mirror_group);
+  }
+
+  if (r == -ENOENT) {
+    m_mirror_group.state = cls::rbd::MIRROR_GROUP_STATE_DISABLED;
+  } else if (r < 0) {
+    lderr(m_cct) << "failed to retrieve group mirroring state: "
+                 << cpp_strerror(r) << dendl;
+    finish(r);
+    return;
+  }
+
   remove_mirror_image();
 }
 
@@ -62,6 +146,12 @@ void ImageRemoveRequest<I>::handle_remove_mirror_image(int r) {
 
 template <typename I>
 void ImageRemoveRequest<I>::notify_mirroring_watcher() {
+  // skip image notification if mirroring for the image group is disabling
+  if (m_mirror_group.state == cls::rbd::MIRROR_GROUP_STATE_DISABLING) {
+    finish(0);
+    return;
+  }
+
   ldout(m_cct, 10) << dendl;
 
   auto ctx = util::create_context_callback<
index c04f9fadc2067672990700b39ef8570839d02711..0ad516622ebc88765237b346146ead11a506feda 100644 (file)
@@ -41,10 +41,16 @@ private:
    *
    * <start>
    *    |
+   * GET_GROUP
+   *    |
+   *    v
+   * GET_MIRROR_GROUP (skip if no group)
+   *    |
+   *    v
    * REMOVE_MIRROR_IMAGE
    *    |
    *    v
-   * NOTIFY_MIRRORING_WATCHER
+   * NOTIFY_MIRRORING_WATCHER (skip if not needed)
    *    |
    *    v
    * <finish>
@@ -58,6 +64,16 @@ private:
   Context* m_on_finish;
 
   CephContext* m_cct;
+  bufferlist m_out_bl;
+  librados::IoCtx m_group_io_ctx;
+  cls::rbd::GroupSpec m_group_spec;
+  cls::rbd::MirrorGroup m_mirror_group;
+
+  void get_group();
+  void handle_get_group(int r);
+
+  void get_mirror_group();
+  void handle_get_mirror_group(int r);
 
   void remove_mirror_image();
   void handle_remove_mirror_image(int r);
index fd7ec4507fa5d7588ce6d94cd128ee448b7a51ff..34a1903e2601cd19db4d3634e3ace55453295c24 100644 (file)
@@ -39,7 +39,12 @@ void ImageStateUpdateRequest<I>::send() {
 template <typename I>
 void ImageStateUpdateRequest<I>::get_mirror_image() {
   if (!m_mirror_image.global_image_id.empty()) {
-    set_mirror_image();
+    if (m_mirror_image.state == m_mirror_image_state) {
+      finish(0);
+      return;
+    }
+
+    get_group();
     return;
   }
 
@@ -75,13 +80,54 @@ void ImageStateUpdateRequest<I>::handle_get_mirror_image(int r) {
     return;
   }
 
-  set_mirror_image();
+  if (m_mirror_image.state == m_mirror_image_state) {
+    finish(0);
+    return;
+  }
+
+  get_group();
 }
 
 template <typename I>
-void ImageStateUpdateRequest<I>::set_mirror_image() {
-  if (m_mirror_image.state == m_mirror_image_state) {
-    finish(0);
+void ImageStateUpdateRequest<I>::get_group() {
+  ldout(m_cct, 10) << dendl;
+  librados::ObjectReadOperation op;
+  cls_client::image_group_get_start(&op);
+
+  auto comp = create_rados_callback<
+    ImageStateUpdateRequest<I>,
+    &ImageStateUpdateRequest<I>::handle_get_group>(this);
+  m_out_bl.clear();
+  int r = m_io_ctx.aio_operate(util::header_name(m_image_id), comp, &op,
+                               &m_out_bl);
+  ceph_assert(r == 0);
+  comp->release();
+}
+
+template <typename I>
+void ImageStateUpdateRequest<I>::handle_get_group(int r) {
+  ldout(m_cct, 10) << "r=" << r << dendl;
+
+  if (r == 0) {
+    auto iter = m_out_bl.cbegin();
+    r = cls_client::image_group_get_finish(&iter, &m_group_spec);
+  }
+
+  if (r < 0) {
+    lderr(m_cct) << "failed to retrieve image group: " << cpp_strerror(r)
+                 << dendl;
+    finish(r);
+    return;
+  }
+
+  get_mirror_group();
+}
+
+template <typename I>
+void ImageStateUpdateRequest<I>::get_mirror_group() {
+  if (!m_group_spec.is_valid()) {
+    m_mirror_group.state = cls::rbd::MIRROR_GROUP_STATE_DISABLED;
+    set_mirror_image();
     return;
   } else if (m_mirror_group.state == cls::rbd::MIRROR_GROUP_STATE_ENABLED ||
              m_mirror_group.state == cls::rbd::MIRROR_GROUP_STATE_ENABLING) {
@@ -89,6 +135,50 @@ void ImageStateUpdateRequest<I>::set_mirror_image() {
     m_mirror_image.group_spec = m_group_spec;
   }
 
+  ldout(m_cct, 10) << dendl;
+
+  int r = util::create_ioctx(m_io_ctx, "group", m_group_spec.pool_id, {},
+                             &m_group_io_ctx);
+  if (r < 0) {
+    finish(r);
+    return;
+  }
+
+  librados::ObjectReadOperation op;
+  cls_client::mirror_group_get_start(&op, m_group_spec.group_id);
+
+  auto comp = create_rados_callback<
+    ImageStateUpdateRequest<I>,
+    &ImageStateUpdateRequest<I>::handle_get_mirror_group>(this);
+  m_out_bl.clear();
+  r = m_group_io_ctx.aio_operate(RBD_MIRRORING, comp, &op, &m_out_bl);
+  ceph_assert(r == 0);
+  comp->release();
+}
+
+template <typename I>
+void ImageStateUpdateRequest<I>::handle_get_mirror_group(int r) {
+  ldout(m_cct, 10) << "r=" << r << dendl;
+
+  if (r == 0) {
+    auto iter = m_out_bl.cbegin();
+    r = cls_client::mirror_group_get_finish(&iter, &m_mirror_group);
+  }
+
+  if (r == -ENOENT) {
+    m_mirror_group.state = cls::rbd::MIRROR_GROUP_STATE_DISABLED;
+  } else if (r < 0) {
+    lderr(m_cct) << "failed to retrieve group mirroring state: "
+                 << cpp_strerror(r) << dendl;
+    finish(r);
+    return;
+  }
+
+  set_mirror_image();
+}
+
+template <typename I>
+void ImageStateUpdateRequest<I>::set_mirror_image() {
   ldout(m_cct, 10) << dendl;
   m_mirror_image.state = m_mirror_image_state;
 
@@ -108,7 +198,7 @@ void ImageStateUpdateRequest<I>::handle_set_mirror_image(int r) {
   ldout(m_cct, 10) << "r=" << r << dendl;
 
   if (r < 0) {
-    lderr(m_cct) << "failed to disable mirroring image: " << cpp_strerror(r)
+    lderr(m_cct) << "failed to set mirror image: " << cpp_strerror(r)
                  << dendl;
     finish(r);
     return;
@@ -119,6 +209,12 @@ void ImageStateUpdateRequest<I>::handle_set_mirror_image(int r) {
 
 template <typename I>
 void ImageStateUpdateRequest<I>::notify_mirroring_watcher() {
+  // skip image notification if mirroring for the image group is disabled
+  if (m_mirror_group.state != cls::rbd::MIRROR_GROUP_STATE_DISABLED) {
+    finish(0);
+    return;
+  }
+
   ldout(m_cct, 10) << dendl;
 
   auto ctx = util::create_context_callback<
index 9e0affe6a99a193f5b7a1362ae23c6502d1b21cf..1db953d2da57e2ee3cc13f891bdd488b94fd0992 100644 (file)
@@ -51,10 +51,16 @@ private:
    * GET_MIRROR_IMAGE
    *    |
    *    v
+   * GET_GROUP
+   *    |
+   *    v
+   * GET_MIRROR_GROUP (skip if no group)
+   *    |
+   *    v
    * SET_MIRROR_IMAGE
    *    |
    *    v
-   * NOTIFY_MIRRORING_WATCHER
+   * NOTIFY_MIRRORING_WATCHER (skip if not needed)
    *    |
    *    v
    * <finish>
@@ -70,10 +76,19 @@ private:
 
   CephContext* m_cct;
   bufferlist m_out_bl;
+  librados::IoCtx m_group_io_ctx;
+  cls::rbd::GroupSpec m_group_spec;
+  cls::rbd::MirrorGroup m_mirror_group;
 
   void get_mirror_image();
   void handle_get_mirror_image(int r);
 
+  void get_group();
+  void handle_get_group(int r);
+
+  void get_mirror_group();
+  void handle_get_mirror_group(int r);
+
   void set_mirror_image();
   void handle_set_mirror_image(int r);