Skip to content

Instantly share code, notes, and snippets.

@rnataraja
Last active March 15, 2019 19:10
Show Gist options
  • Save rnataraja/d987b61d8acc8ac738641f55ebe5af0d to your computer and use it in GitHub Desktop.
Save rnataraja/d987b61d8acc8ac738641f55ebe5af0d to your computer and use it in GitHub Desktop.
diff --git a/components/engine/vendor/github.com/docker/libnetwork/drivers/macvlan/macvlan_network.go b/components/engine/vendor/github.com/docker/libnetwork/drivers/macvlan/macvlan_network.go
index 914c6cdf64..8e73809cff 100644
--- a/components/engine/vendor/github.com/docker/libnetwork/drivers/macvlan/macvlan_network.go
+++ b/components/engine/vendor/github.com/docker/libnetwork/drivers/macvlan/macvlan_network.go
@@ -64,10 +64,16 @@ func (d *driver) CreateNetwork(nid string, option map[string]interface{}, nInfo
// empty parent and --internal are handled the same. Set here to update k/v
config.Internal = true
}
- err = d.createNetwork(config)
+
+ logrus.Warnf("Creating Mac Vlan Network %s\n", nid)
+ foundExisting,err := d.createNetwork(config)
if err != nil {
return err
}
+
+ if foundExisting {
+ return nil
+ }
// update persistent db, rollback on fail
err = d.storeUpdate(config)
if err != nil {
@@ -80,21 +86,34 @@ func (d *driver) CreateNetwork(nid string, option map[string]interface{}, nInfo
}
// createNetwork is used by new network callbacks and persistent network cache
-func (d *driver) createNetwork(config *configuration) error {
+func (d *driver) createNetwork(config *configuration) (bool, error) {
+ foundExisting := false
networkList := d.getNetworks()
for _, nw := range networkList {
if config.Parent == nw.config.Parent {
- return fmt.Errorf("network %s is already using parent interface %s",
- getDummyName(stringid.TruncateID(nw.config.ID)), config.Parent)
+ if config.ID != nw.config.ID {
+ return false, fmt.Errorf("network %s is already using parent interface %s",
+ getDummyName(stringid.TruncateID(nw.config.ID)), config.Parent)
+ } else {
+ logrus.Warnf("Create Network for the same ID %s\n", config.ID)
+ foundExisting = true
+ break
+ }
}
}
if !parentExists(config.Parent) {
// if the --internal flag is set, create a dummy link
if config.Internal {
- err := createDummyLink(config.Parent, getDummyName(stringid.TruncateID(config.ID)))
- if err != nil {
- return err
+
+ if !dummyLinkExists(getDummyName(stringid.TruncateID(config.ID))) {
+ err := createDummyLink(config.Parent, getDummyName(stringid.TruncateID(config.ID)))
+ if err != nil {
+ return false, err
+ }
+ } else {
+ logrus.Debugf("Dummy Link %s for Mac Vlan already exists", getDummyName(stringid.TruncateID(config.ID)))
}
+
config.CreatedSlaveLink = true
// notify the user in logs they have limited comunicatins
if config.Parent == getDummyName(stringid.TruncateID(config.ID)) {
@@ -102,26 +121,34 @@ func (d *driver) createNetwork(config *configuration) error {
config.Parent)
}
} else {
- // if the subinterface parent_iface.vlan_id checks do not pass, return err.
- // a valid example is 'eth0.10' for a parent iface 'eth0' with a vlan id '10'
- err := createVlanLink(config.Parent)
- if err != nil {
- return err
+ if !vlanLinkExists(config.Parent) {
+ // if the subinterface parent_iface.vlan_id checks do not pass, return err.
+ // a valid example is 'eth0.10' for a parent iface 'eth0' with a vlan id '10'
+ err := createVlanLink(config.Parent)
+ if err != nil {
+ return false, err
+ }
+ } else {
+ logrus.Debugf("Parent Sub Interface %s already Exists NetID %s", config.Parent, config.ID)
}
// if driver created the networks slave link, record it for future deletion
config.CreatedSlaveLink = true
}
}
- n := &network{
- id: config.ID,
- driver: d,
- endpoints: endpointTable{},
- config: config,
+
+ /* Should we delete endpoints if foundExisting == true */
+ if !foundExisting {
+ n := &network{
+ id: config.ID,
+ driver: d,
+ endpoints: endpointTable{},
+ config: config,
+ }
+ // add the *network
+ d.addNetwork(n)
}
- // add the *network
- d.addNetwork(n)
- return nil
+ return foundExisting, nil
}
// DeleteNetwork deletes the network for the specified driver type
diff --git a/components/engine/vendor/github.com/docker/libnetwork/drivers/macvlan/macvlan_setup.go b/components/engine/vendor/github.com/docker/libnetwork/drivers/macvlan/macvlan_setup.go
index 98d4bd3832..9dc4767172 100644
--- a/components/engine/vendor/github.com/docker/libnetwork/drivers/macvlan/macvlan_setup.go
+++ b/components/engine/vendor/github.com/docker/libnetwork/drivers/macvlan/macvlan_setup.go
@@ -74,6 +74,14 @@ func parentExists(ifaceStr string) bool {
return true
}
+func vlanLinkExists(linkStr string) bool {
+ _, err := ns.NlHandle().LinkByName(linkStr)
+ if err != nil {
+ return false
+ }
+ return true
+}
+
// createVlanLink parses sub-interfaces and vlan id for creation
func createVlanLink(parentName string) error {
if strings.Contains(parentName, ".") {
@@ -97,6 +105,7 @@ func createVlanLink(parentName string) error {
},
VlanId: vidInt,
}
+
// create the subinterface
if err := ns.NlHandle().LinkAdd(vlanLink); err != nil {
return fmt.Errorf("failed to create %s vlan link: %v", vlanLink.Name, err)
@@ -160,6 +169,14 @@ func parseVlan(linkName string) (string, int, error) {
return parent, vidInt, nil
}
+func dummyLinkExists(dummyName string) bool {
+ _, err := ns.NlHandle().LinkByName(dummyName)
+ if err != nil {
+ return false
+ }
+ return true
+}
+
// createDummyLink creates a dummy0 parent link
func createDummyLink(dummyName, truncNetID string) error {
// create a parent interface since one was not specified
diff --git a/components/engine/vendor/github.com/docker/libnetwork/drivers/macvlan/macvlan_store.go b/components/engine/vendor/github.com/docker/libnetwork/drivers/macvlan/macvlan_store.go
index 655a49c08b..2f4a7a5181 100644
--- a/components/engine/vendor/github.com/docker/libnetwork/drivers/macvlan/macvlan_store.go
+++ b/components/engine/vendor/github.com/docker/libnetwork/drivers/macvlan/macvlan_store.go
@@ -55,7 +55,14 @@ func (d *driver) initStore(option map[string]interface{}) error {
return types.InternalErrorf("macvlan driver failed to initialize data store: %v", err)
}
- return d.populateNetworks()
+ err = d.populateNetworks()
+ if err != nil {
+ return err
+ }
+ err = d.populateEndpoints()
+ if err != nil {
+ return err
+ }
}
return nil
@@ -73,7 +80,7 @@ func (d *driver) populateNetworks() error {
}
for _, kvo := range kvol {
config := kvo.(*configuration)
- if err = d.createNetwork(config); err != nil {
+ if _, err = d.createNetwork(config); err != nil {
logrus.Warnf("Could not create macvlan network for id %s from persistent state", config.ID)
}
}
diff --git a/components/engine/vendor/github.com/docker/libnetwork/endpoint_cnt.go b/components/engine/vendor/github.com/docker/libnetwork/endpoint_cnt.go
index c63d06abe0..49f3469088 100644
--- a/components/engine/vendor/github.com/docker/libnetwork/endpoint_cnt.go
+++ b/components/engine/vendor/github.com/docker/libnetwork/endpoint_cnt.go
@@ -137,6 +137,8 @@ func (ec *endpointCnt) setCnt(cnt uint64) error {
return ec.updateStore()
}
+
+
func (ec *endpointCnt) atomicIncDecEpCnt(inc bool) error {
retry:
ec.Lock()
@@ -176,3 +178,7 @@ func (ec *endpointCnt) IncEndpointCnt() error {
func (ec *endpointCnt) DecEndpointCnt() error {
return ec.atomicIncDecEpCnt(false)
}
+
+func (ec *endpointCnt) SetEndpointCnt(cnt uint64) error {
+ return ec.setCnt(cnt)
+}
diff --git a/components/engine/vendor/github.com/docker/libnetwork/network.go b/components/engine/vendor/github.com/docker/libnetwork/network.go
index 1ad4706ff8..639a31188c 100644
--- a/components/engine/vendor/github.com/docker/libnetwork/network.go
+++ b/components/engine/vendor/github.com/docker/libnetwork/network.go
@@ -926,6 +926,7 @@ func (n *network) driver(load bool) (driverapi.Driver, error) {
}
func (n *network) Delete() error {
+ logrus.Debugf("Request to Delete Network %s\n", n.id)
return n.delete(false)
}
@@ -957,12 +958,20 @@ func (n *network) delete(force bool) error {
return fmt.Errorf("error marking network %s (%s) for deletion: %v", n.Name(), n.ID(), err)
}
+ logrus.Debugf("Deleting Network %s with Config From %s\n", n.id, n.ConfigFrom())
if n.ConfigFrom() != "" {
if t, err := c.getConfigNetwork(n.ConfigFrom()); err == nil {
- if err := t.getEpCnt().DecEndpointCnt(); err != nil {
+ // ConfigOnly and ConfigFrom Networks have 1 to 1 correspondence? In that case
+ // there is no need to decrement the ref count, simply set it to zero.
+ // In the case of a powercycle, the count on the configfrom network increments more than
+ // once and this can cause the configfrom network to linger forever and not even deleteable.
+ // This happens due to the additional increment after the power on, hence count can never
+ // become zero.
+ if err := t.getEpCnt().SetEndpointCnt(0); err != nil {
logrus.Warnf("Failed to update reference count for configuration network %q on removal of network %q: %v",
t.Name(), n.Name(), err)
}
+ logrus.Debugf("Config Only Networks new endpoint count is %d\n", t.getEpCnt().EndpointCnt())
} else {
logrus.Warnf("Could not find configuration network %q during removal of network %q", n.configOnly, n.Name())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment