From 9684be35bf2a3477de640978a5b16bfc55e1461c Mon Sep 17 00:00:00 2001 From: John Grossman Date: Thu, 13 Oct 2011 12:34:29 -0700 Subject: [PATCH] AAH: Fix a bug in the master election state machine. Client's of Masters who disappear before the client has processed even one timesync response should not enter the Ronin state. Since they have never synced to the old Master's timeline, by becoming Ronin they run the risk of defeating other new Ronin's in the master election, even though they don't have any idea what time it is on the old Master's timeline and therefore are unsuitable to serve as the new Master. Instead, they should transition to the Initial state, where other new Ronins (who do know what time it is) have the chance to step in and serve as master of the old timeline. If there are no other Ronin who can do the job, then the old timeline is dead and by transitioning to Initial, a new one will be generated. Change-Id: Iaa95313bfe68a971be2764e252ebf4b34313013d Signed-off-by: John Grossman --- services/aah_timesrv/aah_timesrv.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/services/aah_timesrv/aah_timesrv.cpp b/services/aah_timesrv/aah_timesrv.cpp index 451a7513e995b..d598b6a0fd7fa 100644 --- a/services/aah_timesrv/aah_timesrv.cpp +++ b/services/aah_timesrv/aah_timesrv.cpp @@ -1016,9 +1016,21 @@ bool AAHTimeService::becomeMaster() { } bool AAHTimeService::becomeRonin() { - mRonin_WhoIsMasterRequestTimeouts = 0; - setState(STATE_RONIN); - return sendWhoIsMasterRequest(); + // If we were the client of a given timeline, but had never received even a + // single time sync packet, then we transition back to Initial instead of + // Ronin. If we transition to Ronin and end up becoming the new Master, we + // will be unable to service requests for other clients because we never + // actually knew what time it was. By going to initial, we ensure that + // other clients who know what time it is, but would lose master arbitration + // in the Ronin case, will step up and become the proper new master of the + // old timeline. + if (mCommonClock.isValid()) { + mRonin_WhoIsMasterRequestTimeouts = 0; + setState(STATE_RONIN); + return sendWhoIsMasterRequest(); + } else { + return becomeInitial(); + } } bool AAHTimeService::becomeWaitForElection() {