From: Joao Eduardo Luis Date: Fri, 12 Jun 2015 18:21:10 +0000 (+0100) Subject: mon: PaxosService: call post_refresh() instead of post_paxos_update() X-Git-Tag: v9.0.3~20^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=1551ebb63238073d2fd30201e6b656a8988e958c;p=ceph.git mon: PaxosService: call post_refresh() instead of post_paxos_update() 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 --- diff --git a/src/mon/Monitor.cc b/src/mon/Monitor.cc index ab809babc707..5f6147146dc7 100644 --- a/src/mon/Monitor.cc +++ b/src/mon/Monitor.cc @@ -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(); } } diff --git a/src/mon/PaxosService.cc b/src/mon/PaxosService.cc index 8d06b0bed85a..4bdffc285f46 100644 --- a/src/mon/PaxosService.cc +++ b/src/mon/PaxosService.cc @@ -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() { diff --git a/src/mon/PaxosService.h b/src/mon/PaxosService.h index dd469288c87e..0e7ef7add689 100644 --- a/src/mon/PaxosService.h +++ b/src/mon/PaxosService.h @@ -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