]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
librbd: allow force promotions to create necessary orphan snapshot
authorJason Dillaman <dillaman@redhat.com>
Thu, 27 Feb 2020 15:44:21 +0000 (10:44 -0500)
committerJason Dillaman <dillaman@redhat.com>
Mon, 2 Mar 2020 15:53:43 +0000 (10:53 -0500)
The rbd-mirror daemon needs to accept the RPC request to create an
orphan snapshot so that it knows to shut-down the replayer.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/cls/rbd/cls_rbd_types.h
src/librbd/ImageWatcher.cc
src/librbd/exclusive_lock/Policy.h
src/librbd/mirror/snapshot/CreateNonPrimaryRequest.cc
src/librbd/mirror/snapshot/PromoteRequest.cc
src/tools/rbd_mirror/image_replayer/OpenLocalImageRequest.cc

index 1e4a537b04d730d7f9b503b0b26e4c5f7559ca1b..081540d8e7998c0578866ca311483698b06efd6d 100644 (file)
@@ -584,6 +584,12 @@ struct MirrorSnapshotNamespace {
             state == MIRROR_SNAPSHOT_STATE_NON_PRIMARY_DEMOTED);
   }
 
+  inline bool is_orphan() const {
+    return (is_non_primary() &&
+            primary_mirror_uuid.empty() &&
+            primary_snap_id == CEPH_NOSNAP);
+  }
+
   void encode(bufferlist& bl) const;
   void decode(bufferlist::const_iterator& it);
 
index 18440c0452fb79edcdf206f771e5f69caea9b5b9..073123094d265c3f49af7ec02480f1da66ca60a8 100644 (file)
@@ -777,8 +777,16 @@ bool ImageWatcher<I>::handle_payload(const SnapCreatePayload &payload,
   std::shared_lock l{m_image_ctx.owner_lock};
   if (m_image_ctx.exclusive_lock != nullptr) {
     int r;
-    if (m_image_ctx.exclusive_lock->accept_request(
-          exclusive_lock::OPERATION_REQUEST_TYPE_GENERAL, &r)) {
+    auto request_type = exclusive_lock::OPERATION_REQUEST_TYPE_GENERAL;
+
+    // rbd-mirror needs to accept forced promotion orphan snap create requests
+    auto mirror_ns = boost::get<cls::rbd::MirrorSnapshotNamespace>(
+      &payload.snap_namespace);
+    if (mirror_ns != nullptr && mirror_ns->is_orphan()) {
+      request_type = exclusive_lock::OPERATION_REQUEST_TYPE_FORCE_PROMOTION;
+    }
+
+    if (m_image_ctx.exclusive_lock->accept_request(request_type, &r)) {
       ldout(m_image_ctx.cct, 10) << this << " remote snap_create request: "
                                 << payload.snap_name << dendl;
 
index 8dcbf444441068e2e9d4dc19377f5bcbb0deaa78..7064a6515ba1c7268f484c95cc4f34626a87bd02 100644 (file)
@@ -10,6 +10,7 @@ namespace exclusive_lock {
 enum OperationRequestType {
   OPERATION_REQUEST_TYPE_GENERAL           = 0,
   OPERATION_REQUEST_TYPE_TRASH_SNAP_REMOVE = 1,
+  OPERATION_REQUEST_TYPE_FORCE_PROMOTION   = 2,
 };
 
 struct Policy {
index 8922ee240767090857e0e1e4ab92373c9542f276..7dffb92e97ec26272cdf6656ac635af6963a35de 100644 (file)
@@ -122,6 +122,7 @@ void CreateNonPrimaryRequest<I>::create_snapshot() {
                  cls::rbd::MIRROR_SNAPSHOT_STATE_NON_PRIMARY), {},
     m_primary_mirror_uuid, m_primary_snap_id};
   ns.snap_seqs = m_snap_seqs;
+  ns.complete = is_orphan();
   ldout(cct, 20) << "ns=" << ns << dendl;
 
   auto ctx = create_context_callback<
@@ -160,6 +161,7 @@ void CreateNonPrimaryRequest<I>::write_image_state() {
 
   if (is_orphan()) {
     finish(0);
+    return;
   }
 
   CephContext *cct = m_image_ctx->cct;
index 91d4a25b1161a0537bb5039696d6eb44bd76b090..d02959077931ccec630e9672850aaeb6f3c32740 100644 (file)
@@ -43,6 +43,8 @@ void PromoteRequest<I>::send() {
     return;
   }
 
+  ldout(cct, 20) << "requires_orphan=" << requires_orphan << ", "
+                 << "rollback_snap_id=" << m_rollback_snap_id << dendl;
   create_orphan_snapshot();
 }
 
@@ -233,6 +235,7 @@ void PromoteRequest<I>::handle_acquire_exclusive_lock(int r) {
       r = m_image_ctx->exclusive_lock->get_unlocked_op_error();
       locker.unlock();
       finish(r);
+      return;
     }
   }
 
index 6606a5009e159df0f3c0390158abc35384887e3e..70e935fd72d2213a18c57269342fa3122aaa8db4 100644 (file)
@@ -62,11 +62,13 @@ struct MirrorExclusiveLockPolicy : public librbd::exclusive_lock::Policy {
 
   bool accept_blocked_request(
       librbd::exclusive_lock::OperationRequestType request_type) override {
-    if (request_type ==
-        librbd::exclusive_lock::OPERATION_REQUEST_TYPE_TRASH_SNAP_REMOVE) {
+    switch (request_type) {
+    case librbd::exclusive_lock::OPERATION_REQUEST_TYPE_TRASH_SNAP_REMOVE:
+    case librbd::exclusive_lock::OPERATION_REQUEST_TYPE_FORCE_PROMOTION:
       return true;
+    default:
+      return false;
     }
-    return false;
   }
 };