diff options
author | Joao Eduardo Luis <joao.luis@inktank.com> | 2013-05-22 13:51:13 +0100 |
---|---|---|
committer | Joao Eduardo Luis <joao.luis@inktank.com> | 2013-05-22 17:10:42 +0100 |
commit | 586e8c2075f721456fbd40f738dab8ccfa657aa8 (patch) | |
tree | 86d6a367d210b677f2da8a681fbbb98345e3e568 /src | |
parent | 2ff23fe784245f3b86bc98e0434b21a5318e0a7b (diff) | |
download | ceph-586e8c2075f721456fbd40f738dab8ccfa657aa8.tar.gz |
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 <joao.luis@inktank.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/mon/Paxos.cc | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/src/mon/Paxos.cc b/src/mon/Paxos.cc index 68e5ed1ee76..1c2333c0949 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); } |