Skip to content

Commit 09cdcc8

Browse files
authored
Merge pull request #2415 from arkodg/ipvlan-docker-restart-issue
Support dockerd and system restarts for ipvlan and macvlan networks
2 parents 33dffd4 + 6d382cd commit 09cdcc8

File tree

5 files changed

+85
-37
lines changed

5 files changed

+85
-37
lines changed

Diff for: controller.go

+12-5
Original file line numberDiff line numberDiff line change
@@ -706,9 +706,10 @@ const overlayDSROptionString = "dsr"
706706
// are network specific and modeled in a generic way.
707707
func (c *controller) NewNetwork(networkType, name string, id string, options ...NetworkOption) (Network, error) {
708708
var (
709-
cap *driverapi.Capability
710-
err error
711-
t *network
709+
cap *driverapi.Capability
710+
err error
711+
t *network
712+
skipCfgEpCount bool
712713
)
713714

714715
if id != "" {
@@ -803,7 +804,7 @@ func (c *controller) NewNetwork(networkType, name string, id string, options ...
803804
}
804805
network.generic[netlabel.Internal] = network.internal
805806
defer func() {
806-
if err == nil {
807+
if err == nil && !skipCfgEpCount {
807808
if err := t.getEpCnt().IncEndpointCnt(); err != nil {
808809
logrus.Warnf("Failed to update reference count for configuration network %q on creation of network %q: %v",
809810
t.Name(), network.Name(), err)
@@ -824,7 +825,13 @@ func (c *controller) NewNetwork(networkType, name string, id string, options ...
824825

825826
err = c.addNetwork(network)
826827
if err != nil {
827-
return nil, err
828+
if strings.Contains(err.Error(), "restoring existing network") {
829+
// This error can be ignored and set this boolean
830+
// value to skip a refcount increment for configOnly networks
831+
skipCfgEpCount = true
832+
} else {
833+
return nil, err
834+
}
828835
}
829836
defer func() {
830837
if err != nil {

Diff for: drivers/ipvlan/ipvlan_network.go

+27-14
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,14 @@ func (d *driver) CreateNetwork(nid string, option map[string]interface{}, nInfo
6060
// empty parent and --internal are handled the same. Set here to update k/v
6161
config.Internal = true
6262
}
63-
err = d.createNetwork(config)
63+
foundExisting, err := d.createNetwork(config)
6464
if err != nil {
6565
return err
6666
}
67+
68+
if foundExisting {
69+
return types.InternalMaskableErrorf("restoring existing network %s", config.ID)
70+
}
6771
// update persistent db, rollback on fail
6872
err = d.storeUpdate(config)
6973
if err != nil {
@@ -76,22 +80,29 @@ func (d *driver) CreateNetwork(nid string, option map[string]interface{}, nInfo
7680
}
7781

7882
// createNetwork is used by new network callbacks and persistent network cache
79-
func (d *driver) createNetwork(config *configuration) error {
83+
func (d *driver) createNetwork(config *configuration) (bool, error) {
84+
foundExisting := false
8085
networkList := d.getNetworks()
8186
for _, nw := range networkList {
8287
if config.Parent == nw.config.Parent {
83-
return fmt.Errorf("network %s is already using parent interface %s",
84-
getDummyName(stringid.TruncateID(nw.config.ID)), config.Parent)
88+
if config.ID != nw.config.ID {
89+
return false, fmt.Errorf("network %s is already using parent interface %s",
90+
getDummyName(stringid.TruncateID(nw.config.ID)), config.Parent)
91+
}
92+
logrus.Debugf("Create Network for the same ID %s\n", config.ID)
93+
foundExisting = true
94+
break
8595
}
8696
}
8797
if !parentExists(config.Parent) {
8898
// if the --internal flag is set, create a dummy link
8999
if config.Internal {
90100
err := createDummyLink(config.Parent, getDummyName(stringid.TruncateID(config.ID)))
91101
if err != nil {
92-
return err
102+
return false, err
93103
}
94104
config.CreatedSlaveLink = true
105+
95106
// notify the user in logs they have limited communications
96107
if config.Parent == getDummyName(stringid.TruncateID(config.ID)) {
97108
logrus.Debugf("Empty -o parent= and --internal flags limit communications to other containers inside of network: %s",
@@ -102,22 +113,24 @@ func (d *driver) createNetwork(config *configuration) error {
102113
// a valid example is 'eth0.10' for a parent iface 'eth0' with a vlan id '10'
103114
err := createVlanLink(config.Parent)
104115
if err != nil {
105-
return err
116+
return false, err
106117
}
107118
// if driver created the networks slave link, record it for future deletion
108119
config.CreatedSlaveLink = true
109120
}
110121
}
111-
n := &network{
112-
id: config.ID,
113-
driver: d,
114-
endpoints: endpointTable{},
115-
config: config,
122+
if !foundExisting {
123+
n := &network{
124+
id: config.ID,
125+
driver: d,
126+
endpoints: endpointTable{},
127+
config: config,
128+
}
129+
// add the network
130+
d.addNetwork(n)
116131
}
117-
// add the *network
118-
d.addNetwork(n)
119132

120-
return nil
133+
return foundExisting, nil
121134
}
122135

123136
// DeleteNetwork the network for the specified driver type

Diff for: drivers/ipvlan/ipvlan_store.go

+9-2
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,14 @@ func (d *driver) initStore(option map[string]interface{}) error {
5555
return types.InternalErrorf("ipvlan driver failed to initialize data store: %v", err)
5656
}
5757

58-
return d.populateNetworks()
58+
err = d.populateNetworks()
59+
if err != nil {
60+
return err
61+
}
62+
err = d.populateEndpoints()
63+
if err != nil {
64+
return err
65+
}
5966
}
6067

6168
return nil
@@ -73,7 +80,7 @@ func (d *driver) populateNetworks() error {
7380
}
7481
for _, kvo := range kvol {
7582
config := kvo.(*configuration)
76-
if err = d.createNetwork(config); err != nil {
83+
if _, err = d.createNetwork(config); err != nil {
7784
logrus.Warnf("could not create ipvlan network for id %s from persistent state", config.ID)
7885
}
7986
}

Diff for: drivers/macvlan/macvlan_network.go

+27-14
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,15 @@ func (d *driver) CreateNetwork(nid string, option map[string]interface{}, nInfo
6464
// empty parent and --internal are handled the same. Set here to update k/v
6565
config.Internal = true
6666
}
67-
err = d.createNetwork(config)
67+
foundExisting, err := d.createNetwork(config)
6868
if err != nil {
6969
return err
7070
}
71+
72+
if foundExisting {
73+
return types.InternalMaskableErrorf("restoring existing network %s", config.ID)
74+
}
75+
7176
// update persistent db, rollback on fail
7277
err = d.storeUpdate(config)
7378
if err != nil {
@@ -80,20 +85,26 @@ func (d *driver) CreateNetwork(nid string, option map[string]interface{}, nInfo
8085
}
8186

8287
// createNetwork is used by new network callbacks and persistent network cache
83-
func (d *driver) createNetwork(config *configuration) error {
88+
func (d *driver) createNetwork(config *configuration) (bool, error) {
89+
foundExisting := false
8490
networkList := d.getNetworks()
8591
for _, nw := range networkList {
8692
if config.Parent == nw.config.Parent {
87-
return fmt.Errorf("network %s is already using parent interface %s",
88-
getDummyName(stringid.TruncateID(nw.config.ID)), config.Parent)
93+
if config.ID != nw.config.ID {
94+
return false, fmt.Errorf("network %s is already using parent interface %s",
95+
getDummyName(stringid.TruncateID(nw.config.ID)), config.Parent)
96+
}
97+
logrus.Debugf("Create Network for the same ID %s\n", config.ID)
98+
foundExisting = true
99+
break
89100
}
90101
}
91102
if !parentExists(config.Parent) {
92103
// if the --internal flag is set, create a dummy link
93104
if config.Internal {
94105
err := createDummyLink(config.Parent, getDummyName(stringid.TruncateID(config.ID)))
95106
if err != nil {
96-
return err
107+
return false, err
97108
}
98109
config.CreatedSlaveLink = true
99110
// notify the user in logs they have limited communications
@@ -106,22 +117,24 @@ func (d *driver) createNetwork(config *configuration) error {
106117
// a valid example is 'eth0.10' for a parent iface 'eth0' with a vlan id '10'
107118
err := createVlanLink(config.Parent)
108119
if err != nil {
109-
return err
120+
return false, err
110121
}
111122
// if driver created the networks slave link, record it for future deletion
112123
config.CreatedSlaveLink = true
113124
}
114125
}
115-
n := &network{
116-
id: config.ID,
117-
driver: d,
118-
endpoints: endpointTable{},
119-
config: config,
126+
if !foundExisting {
127+
n := &network{
128+
id: config.ID,
129+
driver: d,
130+
endpoints: endpointTable{},
131+
config: config,
132+
}
133+
// add the network
134+
d.addNetwork(n)
120135
}
121-
// add the *network
122-
d.addNetwork(n)
123136

124-
return nil
137+
return foundExisting, nil
125138
}
126139

127140
// DeleteNetwork deletes the network for the specified driver type

Diff for: drivers/macvlan/macvlan_store.go

+10-2
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,15 @@ func (d *driver) initStore(option map[string]interface{}) error {
5555
return types.InternalErrorf("macvlan driver failed to initialize data store: %v", err)
5656
}
5757

58-
return d.populateNetworks()
58+
err = d.populateNetworks()
59+
if err != nil {
60+
return err
61+
}
62+
err = d.populateEndpoints()
63+
if err != nil {
64+
return err
65+
}
66+
5967
}
6068

6169
return nil
@@ -73,7 +81,7 @@ func (d *driver) populateNetworks() error {
7381
}
7482
for _, kvo := range kvol {
7583
config := kvo.(*configuration)
76-
if err = d.createNetwork(config); err != nil {
84+
if _, err = d.createNetwork(config); err != nil {
7785
logrus.Warnf("Could not create macvlan network for id %s from persistent state", config.ID)
7886
}
7987
}

0 commit comments

Comments
 (0)