diff --git a/src/mon/Paxos.cc b/src/mon/Paxos.cc index 5d07457fdbdec..3a691931c9f2a 100644 --- a/src/mon/Paxos.cc +++ b/src/mon/Paxos.cc @@ -1343,8 +1343,7 @@ void Paxos::leader_init() // discard pending transaction pending_proposal.reset(); - finish_contexts(g_ceph_context, pending_finishers, -EAGAIN); - finish_contexts(g_ceph_context, committing_finishers, -EAGAIN); + reset_pending_committing_finishers(); logger->inc(l_paxos_start_leader); @@ -1375,9 +1374,8 @@ void Paxos::peon_init() pending_proposal.reset(); // no chance to write now! + reset_pending_committing_finishers(); finish_contexts(g_ceph_context, waiting_for_writeable, -EAGAIN); - finish_contexts(g_ceph_context, pending_finishers, -EAGAIN); - finish_contexts(g_ceph_context, committing_finishers, -EAGAIN); logger->inc(l_paxos_start_peon); } @@ -1400,13 +1398,17 @@ void Paxos::restart() // discard pending transaction pending_proposal.reset(); - finish_contexts(g_ceph_context, committing_finishers, -EAGAIN); - finish_contexts(g_ceph_context, pending_finishers, -EAGAIN); + reset_pending_committing_finishers(); finish_contexts(g_ceph_context, waiting_for_active, -EAGAIN); logger->inc(l_paxos_restart); } +void Paxos::reset_pending_committing_finishers() +{ + committing_finishers.splice(committing_finishers.end(), pending_finishers); + finish_contexts(g_ceph_context, committing_finishers, -EAGAIN); +} void Paxos::dispatch(MonOpRequestRef op) { diff --git a/src/mon/Paxos.h b/src/mon/Paxos.h index 2b2e71d94a131..590279ed9cef0 100644 --- a/src/mon/Paxos.h +++ b/src/mon/Paxos.h @@ -597,6 +597,15 @@ class Paxos { * this list. When it commits, these finishers are notified. */ list committing_finishers; + /** + * This function re-triggers pending_ and committing_finishers + * safely, so as to maintain existing system invariants. In particular + * we maintain ordering by triggering committing before pending, and + * we clear out pending_finishers prior to any triggers so that + * we don't trigger asserts on them being empty. You should + * use it instead of sending -EAGAIN to them with finish_contexts. + */ + void reset_pending_committing_finishers(); /** * @defgroup Paxos_h_sync_warns Synchronization warnings