]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: add no-op event when promoting an image 14977/head
authorJason Dillaman <dillaman@redhat.com>
Thu, 4 May 2017 21:56:22 +0000 (17:56 -0400)
committerJason Dillaman <dillaman@redhat.com>
Fri, 5 May 2017 14:46:44 +0000 (10:46 -0400)
The rbd-mirror process needs an event in the journal
to properly detect the transition between primary and
non-primary state between peers.

Fixes: http://tracker.ceph.com/issues/19858
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
(cherry picked from commit 4031555dda7597d24e9eb04b9ff29173909586f7)

Conflicts:
src/librbd/journal/DemoteRequest.cc: logic exists in Journal.cc

(cherry picked from commit 7970ec586bebd26b1ca4955136ad8f48bb833af6)

Conflicts:
src/librbd/journal/PromoteRequest.[h|cc]: logic exists in Journal.cc
src/librbd/journal/Types.[h|cc]: trivial resolution
src/test/librbd/journal/test_mock_PromoteRequest.cc: does not exist

qa/workunits/rbd/rbd_mirror.sh
src/librbd/Journal.cc
src/librbd/journal/Replay.cc
src/librbd/journal/Replay.h
src/librbd/journal/Types.cc
src/librbd/journal/Types.h

index 830ef5604b0a1755f8f684309198a8ba0a3087c1..10507a21777221b63f52ed144e2dddd0a8d77fb8 100755 (executable)
@@ -120,6 +120,25 @@ wait_for_status_in_pool_dir ${CLUSTER2} ${POOL} ${image} 'up+stopped'
 wait_for_status_in_pool_dir ${CLUSTER1} ${POOL} ${image} 'up+replaying' 'master_position'
 compare_images ${POOL} ${image}
 
+# failover (unmodified)
+demote_image ${CLUSTER2} ${POOL} ${image}
+wait_for_image_replay_stopped ${CLUSTER1} ${POOL} ${image}
+wait_for_status_in_pool_dir ${CLUSTER1} ${POOL} ${image} 'up+stopped'
+wait_for_status_in_pool_dir ${CLUSTER2} ${POOL} ${image} 'up+stopped'
+promote_image ${CLUSTER1} ${POOL} ${image}
+wait_for_image_replay_started ${CLUSTER2} ${POOL} ${image}
+
+# failback (unmodified)
+demote_image ${CLUSTER1} ${POOL} ${image}
+wait_for_image_replay_stopped ${CLUSTER2} ${POOL} ${image}
+wait_for_status_in_pool_dir ${CLUSTER2} ${POOL} ${image} 'up+stopped'
+promote_image ${CLUSTER2} ${POOL} ${image}
+wait_for_image_replay_started ${CLUSTER1} ${POOL} ${image}
+wait_for_replay_complete ${CLUSTER1} ${CLUSTER2} ${POOL} ${image}
+wait_for_status_in_pool_dir ${CLUSTER1} ${POOL} ${image} 'up+replaying' 'master_position'
+wait_for_status_in_pool_dir ${CLUSTER2} ${POOL} ${image} 'up+stopped'
+compare_images ${POOL} ${image}
+
 # failover
 demote_image ${CLUSTER2} ${POOL} ${image}
 wait_for_image_replay_stopped ${CLUSTER1} ${POOL} ${image}
index 5686e17ea3b42d0c067e87bf9de56903d2cd4a67..d5df1a2837e29a834671e173d4cb70d0cf0c363e 100644 (file)
@@ -797,6 +797,40 @@ int Journal<I>::promote(I *image_ctx) {
     return r;
   }
 
+  journaler.start_append(0, 0, 0);
+  BOOST_SCOPE_EXIT_ALL(&journaler) {
+    C_SaferCond stop_append_ctx;
+    journaler.stop_append(&stop_append_ctx);
+    stop_append_ctx.wait();
+  };
+
+  journal::EventEntry event_entry{journal::DemotePromoteEvent{}};
+  bufferlist event_entry_bl;
+  ::encode(event_entry, event_entry_bl);
+  Future future = journaler.append(new_tag.tid, event_entry_bl);
+
+  C_SaferCond flush_ctx;
+  future.flush(&flush_ctx);
+  r = flush_ctx.wait();
+  if (r < 0) {
+    lderr(cct) << __func__ << ": "
+               << "failed to append promotion journal event: " << cpp_strerror(r)
+               << dendl;
+    return r;
+  }
+
+  journaler.committed(future);
+
+  C_SaferCond flush_commit_ctx;
+  journaler.flush_commit_position(&flush_commit_ctx);
+  r = flush_commit_ctx.wait();
+  if (r < 0) {
+    lderr(cct) << __func__ << ": "
+               << "failed to flush promotion commit position: "
+               << cpp_strerror(r) << dendl;
+    return r;
+  }
+
   return 0;
 }
 
@@ -962,7 +996,7 @@ int Journal<I>::demote() {
       return r;
     }
 
-    journal::EventEntry event_entry{journal::DemoteEvent{}};
+    journal::EventEntry event_entry{journal::DemotePromoteEvent{}};
     bufferlist event_entry_bl;
     ::encode(event_entry, event_entry_bl);
 
index e8592f51674016bd3decbecadbf16f5c035458d0..387de370905cefedb771a0c543f7775ffafd108d 100644 (file)
@@ -624,10 +624,10 @@ void Replay<I>::handle_event(const journal::FlattenEvent &event,
 }
 
 template <typename I>
-void Replay<I>::handle_event(const journal::DemoteEvent &event,
+void Replay<I>::handle_event(const journal::DemotePromoteEvent &event,
                             Context *on_ready, Context *on_safe) {
   CephContext *cct = m_image_ctx.cct;
-  ldout(cct, 20) << ": Demote event" << dendl;
+  ldout(cct, 20) << ": Demote/Promote event" << dendl;
   on_ready->complete(0);
   on_safe->complete(0);
 }
index 30642db1f365281d2c793527a764d67a489cd54c..af74cc8240e395aecbcf036c5ee204f5af31a555 100644 (file)
@@ -155,7 +155,7 @@ private:
                     Context *on_safe);
   void handle_event(const FlattenEvent &event, Context *on_ready,
                     Context *on_safe);
-  void handle_event(const DemoteEvent &event, Context *on_ready,
+  void handle_event(const DemotePromoteEvent &event, Context *on_ready,
                     Context *on_safe);
   void handle_event(const UnknownEvent &event, Context *on_ready,
                     Context *on_safe);
index f402edf12fe0edefc0b421cb09047778ca50782f..f1d87e6546d07ae4e72d72d3aed054df3d97e1cb 100644 (file)
@@ -205,13 +205,13 @@ void ResizeEvent::dump(Formatter *f) const {
   f->dump_unsigned("size", size);
 }
 
-void DemoteEvent::encode(bufferlist& bl) const {
+void DemotePromoteEvent::encode(bufferlist& bl) const {
 }
 
-void DemoteEvent::decode(__u8 version, bufferlist::iterator& it) {
+void DemotePromoteEvent::decode(__u8 version, bufferlist::iterator& it) {
 }
 
-void DemoteEvent::dump(Formatter *f) const {
+void DemotePromoteEvent::dump(Formatter *f) const {
 }
 
 void UnknownEvent::encode(bufferlist& bl) const {
@@ -281,8 +281,8 @@ void EventEntry::decode(bufferlist::iterator& it) {
   case EVENT_TYPE_FLATTEN:
     event = FlattenEvent();
     break;
-  case EVENT_TYPE_DEMOTE:
-    event = DemoteEvent();
+  case EVENT_TYPE_DEMOTE_PROMOTE:
+    event = DemotePromoteEvent();
     break;
   default:
     event = UnknownEvent();
@@ -336,7 +336,7 @@ void EventEntry::generate_test_instances(std::list<EventEntry *> &o) {
 
   o.push_back(new EventEntry(FlattenEvent(123)));
 
-  o.push_back(new EventEntry(DemoteEvent()));
+  o.push_back(new EventEntry(DemotePromoteEvent()));
 }
 
 // Journal Client
@@ -585,8 +585,8 @@ std::ostream &operator<<(std::ostream &out, const EventType &type) {
   case EVENT_TYPE_FLATTEN:
     out << "Flatten";
     break;
-  case EVENT_TYPE_DEMOTE:
-    out << "Demote";
+  case EVENT_TYPE_DEMOTE_PROMOTE:
+    out << "Demote/Promote";
     break;
   default:
     out << "Unknown (" << static_cast<uint32_t>(type) << ")";
index c8c13a9beeaed959dac1d43e2f75a6f092b3376b..f282da7b689d31f580bcd1909595ac07d641bd36 100644 (file)
@@ -35,7 +35,7 @@ enum EventType {
   EVENT_TYPE_RENAME         = 10,
   EVENT_TYPE_RESIZE         = 11,
   EVENT_TYPE_FLATTEN        = 12,
-  EVENT_TYPE_DEMOTE         = 13
+  EVENT_TYPE_DEMOTE_PROMOTE = 13
 };
 
 struct AioDiscardEvent {
@@ -264,8 +264,9 @@ struct FlattenEvent : public OpEventBase {
   using OpEventBase::dump;
 };
 
-struct DemoteEvent {
-  static const EventType TYPE = static_cast<EventType>(EVENT_TYPE_DEMOTE);
+struct DemotePromoteEvent {
+  static const EventType TYPE = static_cast<EventType>(
+    EVENT_TYPE_DEMOTE_PROMOTE);
 
   void encode(bufferlist& bl) const;
   void decode(__u8 version, bufferlist::iterator& it);
@@ -293,7 +294,7 @@ typedef boost::variant<AioDiscardEvent,
                        RenameEvent,
                        ResizeEvent,
                        FlattenEvent,
-                       DemoteEvent,
+                       DemotePromoteEvent,
                        UnknownEvent> Event;
 
 struct EventEntry {