summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoao Eduardo Luis <joao.luis@inktank.com>2013-05-22 13:51:13 +0100
committerSage Weil <sage@inktank.com>2013-05-27 12:44:21 -0700
commitf29206bdd950d1e916a1422b4826caaf4a8cef3a (patch)
tree14e4aa4e91a1b84a2860c8dabd48c6e3ef88ec43
parentb73d7c6b7e83fe8ce29e7150f25a4cca7647cccd (diff)
downloadceph-f29206bdd950d1e916a1422b4826caaf4a8cef3a.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> (cherry picked from commit 586e8c2075f721456fbd40f738dab8ccfa657aa8)
-rw-r--r--src/mon/Paxos.cc10
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);
}