From feab0cca9f9bb852df3372c7458b0d6d7b64d515 Mon Sep 17 00:00:00 2001 From: Martin Dojcak Date: Sun, 12 Sep 2021 18:05:34 +0200 Subject: [PATCH] libnetwork/overlay:fix join sandbox deadlock Operations performed on overlay network sandboxes are handled by dispatching operations send through a channel. This allows for asynchronous operations to be performed which, since they are not called from within another function, are able to operate in an idempotent manner with a known/measurable starting state from which an identical series of iterative actions can be performed. However, it was possible in some cases for an operation dispatched from this channel to write a message back to the channel in the case of joining a network when a sufficient volume of sandboxes were operated on. A goroutine which is simultaneously reading and writing to an unbuffered channel can deadlock if it sends a message to a channel then waits for it to be consumed and completed, since the only available goroutine is more or less "talking to itself". In order to break this deadlock, in the observed race, a goroutine is now created to send the message to the channel. Signed-off-by: Martin Dojcak Signed-off-by: Ryan Barry --- libnetwork/drivers/overlay/ov_network.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libnetwork/drivers/overlay/ov_network.go b/libnetwork/drivers/overlay/ov_network.go index 529f5297d6..03726d9574 100644 --- a/libnetwork/drivers/overlay/ov_network.go +++ b/libnetwork/drivers/overlay/ov_network.go @@ -319,7 +319,7 @@ func (n *network) joinSandbox(s *subnet, restore bool, incJoinCount bool) error defer func() { n.Unlock() if doInitPeerDB { - n.driver.initSandboxPeerDB(n.id) + go n.driver.initSandboxPeerDB(n.id) } }()