From 7086da757a37b4ed730b4af8f868eadff9080fb8 Mon Sep 17 00:00:00 2001 From: Alessandro Boch Date: Mon, 25 Jan 2016 16:58:46 -0800 Subject: [PATCH] Handle concurrent creation of default GW network - Code is not protected against concurrent joins of overlay network Signed-off-by: Alessandro Boch --- libnetwork/default_gateway.go | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/libnetwork/default_gateway.go b/libnetwork/default_gateway.go index 9a3ca0d6bd..2df047a348 100644 --- a/libnetwork/default_gateway.go +++ b/libnetwork/default_gateway.go @@ -12,6 +12,8 @@ const ( gwEPlen = 12 ) +var procGwNetwork = make(chan (bool), 1) + /* libnetwork creates a bridge network "docker_gw_bridge" for provding default gateway for the containers if none of the container's endpoints @@ -35,13 +37,11 @@ func (sb *sandbox) setupDefaultGW(srcEp *endpoint) error { return nil } + // Look for default gw network. In case of error (includes not found), + // retry and create it if needed in a serialized execution. n, err := c.NetworkByName(libnGWNetwork) if err != nil { - if _, ok := err.(types.NotFoundError); !ok { - return err - } - n, err = c.createGWNetwork() - if err != nil { + if n, err = c.defaultGwNetwork(); err != nil { return err } } @@ -150,3 +150,18 @@ func (sb *sandbox) getEPwithoutGateway() *endpoint { } return nil } + +// Looks for the default gw network and creates it if not there. +// Parallel executions are serialized. +func (c *controller) defaultGwNetwork() (Network, error) { + procGwNetwork <- true + defer func() { <-procGwNetwork }() + + n, err := c.NetworkByName(libnGWNetwork) + if err != nil { + if _, ok := err.(types.NotFoundError); ok { + n, err = c.createGWNetwork() + } + } + return n, err +}