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>
This commit is contained in:
parent
cc0095b03e
commit
ff59f1baab
1 changed files with 12 additions and 0 deletions
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue