From: Joao Eduardo Luis Date: Wed, 22 May 2013 12:51:13 +0000 (+0100) Subject: mon: Paxos: finish queued proposals instead of clearing the list X-Git-Tag: v0.63~5^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=586e8c2075f721456fbd40f738dab8ccfa657aa8;p=ceph.git mon: Paxos: finish queued proposals instead of clearing the list By finishing these Contexts, we make sure the Contexts they enclose (to be called once the proposal goes through) will behave as their were initially planned: for instance, a C_Command() may retry the command if a -EAGAIN is passed to 'finish_contexts', while a C_Trimmed() will simply set 'going_to_trim' to false. This aims at fixing at least a bug in which Paxos will stop trimming if an election is triggered while a trim is queued but not yet finished. Such happens because it is the C_Trimmed() context that is responsible for resetting 'going_to_trim' back to false. By clearing all the contexts on the proposal list instead of finishing them, we stay forever unable to trim Paxos again as 'going_to_trim' will stay True till the end of time as we know it. Fixes: #4895 Signed-off-by: Joao Eduardo Luis --- diff --git a/src/mon/Paxos.cc b/src/mon/Paxos.cc index 68e5ed1ee76f..1c2333c09494 100644 --- a/src/mon/Paxos.cc +++ b/src/mon/Paxos.cc @@ -1087,6 +1087,7 @@ void Paxos::shutdown() { finish_contexts(g_ceph_context, waiting_for_commit, -ECANCELED); finish_contexts(g_ceph_context, waiting_for_readable, -ECANCELED); finish_contexts(g_ceph_context, waiting_for_active, -ECANCELED); + finish_contexts(g_ceph_context, proposals, -ECANCELED); } void Paxos::leader_init() @@ -1094,7 +1095,7 @@ void Paxos::leader_init() cancel_events(); new_value.clear(); if (!proposals.empty()) - proposals.clear(); + finish_contexts(g_ceph_context, proposals, -EAGAIN); going_to_bootstrap = false; @@ -1121,6 +1122,7 @@ void Paxos::peon_init() // no chance to write now! finish_contexts(g_ceph_context, waiting_for_writeable, -EAGAIN); finish_contexts(g_ceph_context, waiting_for_commit, -EAGAIN); + finish_contexts(g_ceph_context, proposals, -EAGAIN); } void Paxos::restart() @@ -1128,13 +1130,13 @@ void Paxos::restart() dout(10) << "restart -- canceling timeouts" << dendl; cancel_events(); new_value.clear(); - dout(10) << __func__ << " -- clearing queued proposals" << dendl; - if (!proposals.empty()) - proposals.clear(); state = STATE_RECOVERING; going_to_bootstrap = false; + if (!proposals.empty()) + finish_contexts(g_ceph_context, proposals, -EAGAIN); + finish_contexts(g_ceph_context, waiting_for_commit, -EAGAIN); finish_contexts(g_ceph_context, waiting_for_active, -EAGAIN); }