From: Jason Dillaman Date: Thu, 4 May 2017 21:56:22 +0000 (-0400) Subject: librbd: add no-op event when promoting an image X-Git-Tag: v10.2.10~90^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=618a82e11e53cf2f1d5d306a2eb330cdf5e459ca;p=ceph.git librbd: add no-op event when promoting an image 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 (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 --- diff --git a/qa/workunits/rbd/rbd_mirror.sh b/qa/workunits/rbd/rbd_mirror.sh index 830ef5604b0a..10507a217772 100755 --- a/qa/workunits/rbd/rbd_mirror.sh +++ b/qa/workunits/rbd/rbd_mirror.sh @@ -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} diff --git a/src/librbd/Journal.cc b/src/librbd/Journal.cc index 5686e17ea3b4..d5df1a2837e2 100644 --- a/src/librbd/Journal.cc +++ b/src/librbd/Journal.cc @@ -797,6 +797,40 @@ int Journal::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::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); diff --git a/src/librbd/journal/Replay.cc b/src/librbd/journal/Replay.cc index e8592f516740..387de370905c 100644 --- a/src/librbd/journal/Replay.cc +++ b/src/librbd/journal/Replay.cc @@ -624,10 +624,10 @@ void Replay::handle_event(const journal::FlattenEvent &event, } template -void Replay::handle_event(const journal::DemoteEvent &event, +void Replay::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); } diff --git a/src/librbd/journal/Replay.h b/src/librbd/journal/Replay.h index 30642db1f365..af74cc8240e3 100644 --- a/src/librbd/journal/Replay.h +++ b/src/librbd/journal/Replay.h @@ -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); diff --git a/src/librbd/journal/Types.cc b/src/librbd/journal/Types.cc index f402edf12fe0..f1d87e6546d0 100644 --- a/src/librbd/journal/Types.cc +++ b/src/librbd/journal/Types.cc @@ -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 &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(type) << ")"; diff --git a/src/librbd/journal/Types.h b/src/librbd/journal/Types.h index c8c13a9beeae..f282da7b689d 100644 --- a/src/librbd/journal/Types.h +++ b/src/librbd/journal/Types.h @@ -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(EVENT_TYPE_DEMOTE); +struct DemotePromoteEvent { + static const EventType TYPE = static_cast( + EVENT_TYPE_DEMOTE_PROMOTE); void encode(bufferlist& bl) const; void decode(__u8 version, bufferlist::iterator& it); @@ -293,7 +294,7 @@ typedef boost::variant Event; struct EventEntry {