]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mon: Paxos: finish queued proposals instead of clearing the list
authorJoao Eduardo Luis <joao.luis@inktank.com>
Wed, 22 May 2013 12:51:13 +0000 (13:51 +0100)
committerJoao Eduardo Luis <joao.luis@inktank.com>
Wed, 22 May 2013 16:10:42 +0000 (17:10 +0100)
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>
src/mon/Paxos.cc

index 68e5ed1ee76f211b9706e794adeca27b01a10b25..1c2333c094942a48d2e37bf0dcc2f93751f0b581 100644 (file)
@@ -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);
 }