فهرست منبع

Serialize dynamic network creation

When dynamic networks are created and there is a race in creation of the
same network from two different tasks then one of them will fail while
the other will succeed. For service tasks this is not a big problem
because they will be rescheduled again. But for attachment tasks this
can be a problem since they won't get recreated and making the whole
connection fail. Fixed it by serializing network creation for the
network with the same id and trying to see if the id is present after
coming out of wait.

Signed-off-by: Jana Radhakrishnan <mrjana@docker.com>
Jana Radhakrishnan 8 سال پیش
والد
کامیت
ff59f1baab
1فایلهای تغییر یافته به همراه12 افزوده شده و 0 حذف شده
  1. 12 0
      libnetwork/controller.go

+ 12 - 0
libnetwork/controller.go

@@ -52,6 +52,7 @@ import (
 
 
 	log "github.com/Sirupsen/logrus"
 	log "github.com/Sirupsen/logrus"
 	"github.com/docker/docker/pkg/discovery"
 	"github.com/docker/docker/pkg/discovery"
+	"github.com/docker/docker/pkg/locker"
 	"github.com/docker/docker/pkg/plugins"
 	"github.com/docker/docker/pkg/plugins"
 	"github.com/docker/docker/pkg/stringid"
 	"github.com/docker/docker/pkg/stringid"
 	"github.com/docker/libnetwork/cluster"
 	"github.com/docker/libnetwork/cluster"
@@ -149,6 +150,7 @@ type controller struct {
 	ingressSandbox         *sandbox
 	ingressSandbox         *sandbox
 	sboxOnce               sync.Once
 	sboxOnce               sync.Once
 	agent                  *agent
 	agent                  *agent
+	networkLocker          *locker.Locker
 	agentInitDone          chan struct{}
 	agentInitDone          chan struct{}
 	keys                   []*types.EncryptionKey
 	keys                   []*types.EncryptionKey
 	clusterConfigAvailable bool
 	clusterConfigAvailable bool
@@ -169,6 +171,7 @@ func New(cfgOptions ...config.Option) (NetworkController, error) {
 		svcRecords:      make(map[string]svcInfo),
 		svcRecords:      make(map[string]svcInfo),
 		serviceBindings: make(map[serviceKey]*service),
 		serviceBindings: make(map[serviceKey]*service),
 		agentInitDone:   make(chan struct{}),
 		agentInitDone:   make(chan struct{}),
+		networkLocker:   locker.New(),
 	}
 	}
 
 
 	if err := c.initStores(); err != nil {
 	if err := c.initStores(); err != nil {
@@ -614,6 +617,15 @@ func (c *controller) RegisterDriver(networkType string, driver driverapi.Driver,
 // NewNetwork creates a new network of the specified network type. The options
 // NewNetwork creates a new network of the specified network type. The options
 // are network specific and modeled in a generic way.
 // are network specific and modeled in a generic way.
 func (c *controller) NewNetwork(networkType, name string, id string, options ...NetworkOption) (Network, error) {
 func (c *controller) NewNetwork(networkType, name string, id string, options ...NetworkOption) (Network, error) {
+	if id != "" {
+		c.networkLocker.Lock(id)
+		defer c.networkLocker.Unlock(id)
+
+		if _, err := c.NetworkByID(id); err == nil {
+			return nil, NetworkNameError(id)
+		}
+	}
+
 	if !config.IsValidName(name) {
 	if !config.IsValidName(name) {
 		return nil, ErrInvalidName(name)
 		return nil, ErrInvalidName(name)
 	}
 	}