From c3e54b79fdc15aa70f87532340099ca174d3f262 Mon Sep 17 00:00:00 2001 From: Sean Chittenden Date: Mon, 20 Jun 2016 14:59:54 -0700 Subject: [PATCH] Fix deadlock in Consul RTT. - consul/rtt.go:388: s.getDatacentersByDistance(). Acquires RLock() - consul/rtt.go:341: sortDatacentersByDistance() RLock still held. - consul/rtt.go:282: getDatacenterDistance() RLock still held. - consul/rtt.go:268: getNodesForDatacenter(). Attempts to reacquire RLock(), hangs indefinitely. --- consul/rtt.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/consul/rtt.go b/consul/rtt.go index 1d9533ab89dd..3aa198dda00d 100644 --- a/consul/rtt.go +++ b/consul/rtt.go @@ -386,12 +386,11 @@ func getDatacenterMaps(s serfer, dcs []string) []structs.DatacenterMap { // other things being equal (or if coordinates are disabled). func (s *Server) getDatacentersByDistance() ([]string, error) { s.remoteLock.RLock() - defer s.remoteLock.RUnlock() - - var dcs []string + dcs := make([]string, 0, len(s.remoteConsuls)) for dc := range s.remoteConsuls { dcs = append(dcs, dc) } + s.remoteLock.RUnlock() // Sort by name first, since the coordinate sort is stable. sort.Strings(dcs)