]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mon: PaxosService: call post_refresh() instead of post_paxos_update() 5359/head
authorJoao Eduardo Luis <joao@suse.de>
Fri, 12 Jun 2015 18:21:10 +0000 (19:21 +0100)
committerJoao Eduardo Luis <jecluis@gmail.com>
Mon, 27 Jul 2015 20:56:42 +0000 (21:56 +0100)
Whenever the monitor finishes committing a proposal, we call
Monitor::refresh_from_paxos() to nudge the services to refresh.  Once
all services have refreshed, we would then call each services
post_paxos_update().

However, due to an unfortunate, non-critical bug, some services (mainly
the LogMonitor) could have messages pending in their
'waiting_for_finished_proposal' callback queue [1], and we need to nudge
those callbacks.

This patch adds a new step during the refresh phase: instead of calling
directly the service's post_paxos_update(), we introduce a
PaxosService::post_refresh() which will call the services
post_paxos_update() function first and then nudge those callbacks when
appropriate.

[1] - Given the monitor will send MLog messages to itself, and given the
service is not readable before its initial state is proposed and
committed, some of the initial MLog's would be stuck waiting for the
proposal to finish.  However, by design, we only nudge those message's
callbacks when an election finishes or, if the leader, when the proposal
finishes.  On peons, however, we would only nudge those callbacks if an
election happened to be triggered, hence the need for an alternate path
to retry any message waiting for the initial proposal to finish.

Fixes: #11470
Signed-off-by: Joao Eduardo Luis <joao@suse.de>
(cherry picked from commit 1551ebb63238073d2fd30201e6b656a8988e958c)

src/mon/Monitor.cc
src/mon/PaxosService.cc
src/mon/PaxosService.h

index 83098f00b10523a52410902f925529762cac9202..ba2aecfe2dd7d44c93eeecc74f5eff25480fe612 100644 (file)
@@ -788,7 +788,7 @@ void Monitor::refresh_from_paxos(bool *need_bootstrap)
     paxos_service[i]->refresh(need_bootstrap);
   }
   for (int i = 0; i < PAXOS_NUM; ++i) {
-    paxos_service[i]->post_paxos_update();
+    paxos_service[i]->post_refresh();
   }
 }
 
index 8d06b0bed85acbd061e252d084f6419cc47e69df..4bdffc285f4631f4a350c47e33ed028a5127cf8e 100644 (file)
@@ -128,6 +128,16 @@ void PaxosService::refresh(bool *need_bootstrap)
   update_from_paxos(need_bootstrap);
 }
 
+void PaxosService::post_refresh()
+{
+  dout(10) << __func__ << dendl;
+
+  post_paxos_update();
+
+  if (mon->is_peon() && !waiting_for_finished_proposal.empty()) {
+    finish_contexts(g_ceph_context, waiting_for_finished_proposal, -EAGAIN);
+  }
+}
 
 void PaxosService::remove_legacy_versions()
 {
index 7c2259218e37d0e9e9cf2a8e89828a53a493c724..b5f92f11cf896767ec057fd11e0166dfc7e23a49 100644 (file)
@@ -322,6 +322,7 @@ public:
   bool dispatch(PaxosServiceMessage *m);
 
   void refresh(bool *need_bootstrap);
+  void post_refresh();
 
   /**
    * @defgroup PaxosService_h_override_funcs Functions that should be