Prechádzať zdrojové kódy

Handle concurrent creation of default GW network

- Code is not protected against concurrent joins of overlay network

Signed-off-by: Alessandro Boch <aboch@docker.com>
Alessandro Boch 9 rokov pred
rodič
commit
7086da757a
1 zmenil súbory, kde vykonal 20 pridanie a 5 odobranie
  1. 20 5
      libnetwork/default_gateway.go

+ 20 - 5
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
+}