Преглед изворни кода

libnetwork/drivers/bridge: driver.link: don't defer in a loop

Collect a list of all the links we successfully enabled (if any), and
use a single defer to disable them.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Sebastiaan van Stijn пре 2 година
родитељ
комит
eba15fe905
1 измењених фајлова са 16 додато и 14 уклоњено
  1. 16 14
      libnetwork/drivers/bridge/bridge.go

+ 16 - 14
libnetwork/drivers/bridge/bridge.go

@@ -1351,14 +1351,24 @@ func (d *driver) RevokeExternalConnectivity(nid, eid string) error {
 
 func (d *driver) link(network *bridgeNetwork, endpoint *bridgeEndpoint, enable bool) (retErr error) {
 	cc := endpoint.containerConfig
-	if cc == nil {
-		return nil
-	}
 	ec := endpoint.extConnConfig
-	if ec == nil {
+	if cc == nil || ec == nil || (len(cc.ParentEndpoints) == 0 && len(cc.ChildEndpoints) == 0) {
+		// nothing to do
 		return nil
 	}
 
+	// Try to keep things atomic. addedLinks keeps track of links that were
+	// successfully added. If any error occurred, then roll back all.
+	var addedLinks []*link
+	defer func() {
+		if retErr == nil {
+			return
+		}
+		for _, l := range addedLinks {
+			l.Disable()
+		}
+	}()
+
 	if ec.ExposedPorts != nil {
 		for _, p := range cc.ParentEndpoints {
 			parentEndpoint, err := network.getEndpoint(p)
@@ -1374,11 +1384,7 @@ func (d *driver) link(network *bridgeNetwork, endpoint *bridgeEndpoint, enable b
 				if err := l.Enable(); err != nil {
 					return err
 				}
-				defer func() {
-					if retErr != nil {
-						l.Disable()
-					}
-				}()
+				addedLinks = append(addedLinks, l)
 			} else {
 				l.Disable()
 			}
@@ -1402,11 +1408,7 @@ func (d *driver) link(network *bridgeNetwork, endpoint *bridgeEndpoint, enable b
 			if err := l.Enable(); err != nil {
 				return err
 			}
-			defer func() {
-				if retErr != nil {
-					l.Disable()
-				}
-			}()
+			addedLinks = append(addedLinks, l)
 		} else {
 			l.Disable()
 		}