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
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}
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;
}
return r;
}
- journal::EventEntry event_entry{journal::DemoteEvent{}};
+ journal::EventEntry event_entry{journal::DemotePromoteEvent{}};
bufferlist event_entry_bl;
::encode(event_entry, event_entry_bl);
}
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);
}
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);
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 {
case EVENT_TYPE_FLATTEN:
event = FlattenEvent();
break;
- case EVENT_TYPE_DEMOTE:
- event = DemoteEvent();
+ case EVENT_TYPE_DEMOTE_PROMOTE:
+ event = DemotePromoteEvent();
break;
default:
event = UnknownEvent();
o.push_back(new EventEntry(FlattenEvent(123)));
- o.push_back(new EventEntry(DemoteEvent()));
+ o.push_back(new EventEntry(DemotePromoteEvent()));
}
// Journal Client
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) << ")";
EVENT_TYPE_RENAME = 10,
EVENT_TYPE_RESIZE = 11,
EVENT_TYPE_FLATTEN = 12,
- EVENT_TYPE_DEMOTE = 13
+ EVENT_TYPE_DEMOTE_PROMOTE = 13
};
struct AioDiscardEvent {
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);
RenameEvent,
ResizeEvent,
FlattenEvent,
- DemoteEvent,
+ DemotePromoteEvent,
UnknownEvent> Event;
struct EventEntry {