]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/librbd/mirror/DemoteRequest.cc
import 15.2.0 Octopus source
[ceph.git] / ceph / src / librbd / mirror / DemoteRequest.cc
index c5d38752ea9200b4c1f73a0f7d96210eb7e69c38..350a76d83421d4bffaf9c4fcfa1482e39122a801 100644 (file)
@@ -11,6 +11,7 @@
 #include "librbd/Journal.h"
 #include "librbd/Utils.h"
 #include "librbd/mirror/GetInfoRequest.h"
+#include "librbd/mirror/snapshot/DemoteRequest.h"
 
 #define dout_subsys ceph_subsys_rbd
 #undef dout_prefix
@@ -35,7 +36,8 @@ void DemoteRequest<I>::get_info() {
   auto ctx = create_context_callback<
     DemoteRequest<I>, &DemoteRequest<I>::handle_get_info>(this);
   auto req = GetInfoRequest<I>::create(m_image_ctx, &m_mirror_image,
-                                       &m_promotion_state, ctx);
+                                       &m_promotion_state,
+                                       &m_primary_mirror_uuid, ctx);
   req->send();
 }
 
@@ -44,7 +46,7 @@ void DemoteRequest<I>::handle_get_info(int r) {
   CephContext *cct = m_image_ctx.cct;
   ldout(cct, 20) << "r=" << r << dendl;
 
-  if (r < 0) {
+  if (r < 0 && r != -ENOENT) {
     lderr(cct) << "failed to retrieve mirroring state: " << cpp_strerror(r)
                << dendl;
     finish(r);
@@ -66,11 +68,15 @@ template <typename I>
 void DemoteRequest<I>::acquire_lock() {
   CephContext *cct = m_image_ctx.cct;
 
-  m_image_ctx.owner_lock.get_read();
+  m_image_ctx.owner_lock.lock_shared();
   if (m_image_ctx.exclusive_lock == nullptr) {
-    m_image_ctx.owner_lock.put_read();
-    lderr(cct) << "exclusive lock is not active" << dendl;
-    finish(-EINVAL);
+    m_image_ctx.owner_lock.unlock_shared();
+    if (m_mirror_image.mode == cls::rbd::MIRROR_IMAGE_MODE_JOURNAL) {
+      lderr(cct) << "exclusive lock is not active" << dendl;
+      finish(-EINVAL);
+    } else {
+      demote();
+    }
     return;
   }
 
@@ -80,7 +86,7 @@ void DemoteRequest<I>::acquire_lock() {
   m_blocked_requests = true;
 
   if (m_image_ctx.exclusive_lock->is_lock_owner()) {
-    m_image_ctx.owner_lock.put_read();
+    m_image_ctx.owner_lock.unlock_shared();
     demote();
     return;
   }
@@ -88,9 +94,10 @@ void DemoteRequest<I>::acquire_lock() {
   ldout(cct, 20) << dendl;
 
   auto ctx = create_context_callback<
-    DemoteRequest<I>, &DemoteRequest<I>::handle_acquire_lock>(this);
+    DemoteRequest<I>,
+    &DemoteRequest<I>::handle_acquire_lock>(this, m_image_ctx.exclusive_lock);
   m_image_ctx.exclusive_lock->acquire_lock(ctx);
-  m_image_ctx.owner_lock.put_read();
+  m_image_ctx.owner_lock.unlock_shared();
 }
 
 template <typename I>
@@ -104,16 +111,16 @@ void DemoteRequest<I>::handle_acquire_lock(int r) {
     return;
   }
 
-  m_image_ctx.owner_lock.get_read();
+  m_image_ctx.owner_lock.lock_shared();
   if (m_image_ctx.exclusive_lock != nullptr &&
       !m_image_ctx.exclusive_lock->is_lock_owner()) {
     r = m_image_ctx.exclusive_lock->get_unlocked_op_error();
-    m_image_ctx.owner_lock.put_read();
+    m_image_ctx.owner_lock.unlock_shared();
     lderr(cct) << "failed to acquire exclusive lock" << dendl;
     finish(r);
     return;
   }
-  m_image_ctx.owner_lock.put_read();
+  m_image_ctx.owner_lock.unlock_shared();
 
   demote();
 }
@@ -125,7 +132,17 @@ void DemoteRequest<I>::demote() {
 
   auto ctx = create_context_callback<
     DemoteRequest<I>, &DemoteRequest<I>::handle_demote>(this);
-  Journal<I>::demote(&m_image_ctx, ctx);
+  if (m_mirror_image.mode == cls::rbd::MIRROR_IMAGE_MODE_JOURNAL) {
+    Journal<I>::demote(&m_image_ctx, ctx);
+  } else if (m_mirror_image.mode == cls::rbd::MIRROR_IMAGE_MODE_SNAPSHOT) {
+    auto req = mirror::snapshot::DemoteRequest<I>::create(
+      &m_image_ctx, m_mirror_image.global_image_id, ctx);
+    req->send();
+  } else {
+    lderr(cct) << "unknown image mirror mode: " << m_mirror_image.mode << dendl;
+    m_ret_val = -EOPNOTSUPP;
+    release_lock();
+  }
 }
 
 template <typename I>
@@ -146,17 +163,18 @@ void DemoteRequest<I>::release_lock() {
   CephContext *cct = m_image_ctx.cct;
   ldout(cct, 20) << dendl;
 
-  m_image_ctx.owner_lock.get_read();
+  m_image_ctx.owner_lock.lock_shared();
   if (m_image_ctx.exclusive_lock == nullptr) {
-    m_image_ctx.owner_lock.put_read();
+    m_image_ctx.owner_lock.unlock_shared();
     finish(0);
     return;
   }
 
   auto ctx = create_context_callback<
-    DemoteRequest<I>, &DemoteRequest<I>::handle_release_lock>(this);
+    DemoteRequest<I>,
+    &DemoteRequest<I>::handle_release_lock>(this, m_image_ctx.exclusive_lock);
   m_image_ctx.exclusive_lock->release_lock(ctx);
-  m_image_ctx.owner_lock.put_read();
+  m_image_ctx.owner_lock.unlock_shared();
 }
 
 template <typename I>
@@ -179,7 +197,7 @@ void DemoteRequest<I>::finish(int r) {
   }
 
   {
-    RWLock::RLocker owner_locker(m_image_ctx.owner_lock);
+    std::shared_lock owner_locker{m_image_ctx.owner_lock};
     if (m_blocked_requests && m_image_ctx.exclusive_lock != nullptr) {
       m_image_ctx.exclusive_lock->unblock_requests();
     }