From 2f35a415dcd31683151defb0ddb1a6d5696c7051 Mon Sep 17 00:00:00 2001 From: Joao Eduardo Luis Date: Fri, 12 Jun 2015 19:21:10 +0100 Subject: [PATCH] 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 (cherry picked from commit 1551ebb63238073d2fd30201e6b656a8988e958c) --- src/mon/Monitor.cc | 2 +- src/mon/PaxosService.cc | 10 ++++++++++ src/mon/PaxosService.h | 1 + 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/mon/Monitor.cc b/src/mon/Monitor.cc index 371341c998b99..f6f08e08f360c 100644 --- a/src/mon/Monitor.cc +++ b/src/mon/Monitor.cc @@ -642,7 +642,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 1b21689863bc6..7ba8e9ca359fc 100644 --- a/src/mon/PaxosService.cc +++ b/src/mon/PaxosService.cc @@ -127,6 +127,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 5321bebcacefc..4138b20afd208 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 -- 2.39.5