Browse code

Fix a corner case issue when daemon panics

There is an extreme corner case where when the daemon
panics at the same time as a container is stopping
and cleaning up the sandbox and the sandbox may have been
left with an inconsistent state. This libnetwork vendoring
fixes that case.

Vendoring in libnetwork @ 5305ea570b85d61dd0fd261cd7e1680da1884678

Signed-off-by: Jana Radhakrishnan <mrjana@docker.com>

Jana Radhakrishnan authored on 2015/11/03 11:37:35
Showing 2 changed files
... ...
@@ -21,7 +21,7 @@ clone git github.com/vdemeester/shakers 3c10293ce22b900c27acad7b28656196fcc2f73b
21 21
 clone git golang.org/x/net 3cffabab72adf04f8e3b01c5baf775361837b5fe https://github.com/golang/net.git
22 22
 
23 23
 #get libnetwork packages
24
-clone git github.com/docker/libnetwork e7719596c01a83f9ef24d33e9d609a64acacd7b8
24
+clone git github.com/docker/libnetwork 5305ea570b85d61dd0fd261cd7e1680da1884678
25 25
 clone git github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec
26 26
 clone git github.com/hashicorp/go-msgpack 71c2886f5a673a35f909803f38ece5810165097b
27 27
 clone git github.com/hashicorp/memberlist 9a1e242e454d2443df330bdd51a436d5a9058fc4
... ...
@@ -177,13 +177,18 @@ func (sb *sandbox) Delete() error {
177 177
 			continue
178 178
 		}
179 179
 
180
-		if err := ep.Leave(sb); err != nil {
180
+		// Retain the sanbdox if we can't obtain the network from store.
181
+		if _, err := c.getNetworkFromStore(ep.getNetwork().ID()); err != nil {
181 182
 			retain = true
183
+			log.Warnf("Failed getting network for ep %s during sandbox %s delete: %v", ep.ID(), sb.ID(), err)
184
+			continue
185
+		}
186
+
187
+		if err := ep.Leave(sb); err != nil {
182 188
 			log.Warnf("Failed detaching sandbox %s from endpoint %s: %v\n", sb.ID(), ep.ID(), err)
183 189
 		}
184 190
 
185 191
 		if err := ep.Delete(); err != nil {
186
-			retain = true
187 192
 			log.Warnf("Failed deleting endpoint %s: %v\n", ep.ID(), err)
188 193
 		}
189 194
 	}
... ...
@@ -455,7 +460,7 @@ func (sb *sandbox) populateNetworkResources(ep *endpoint) error {
455 455
 	i := ep.iface
456 456
 	ep.Unlock()
457 457
 
458
-	if i.srcName != "" {
458
+	if i != nil && i.srcName != "" {
459 459
 		var ifaceOptions []osl.IfaceOption
460 460
 
461 461
 		ifaceOptions = append(ifaceOptions, sb.osSbox.InterfaceOptions().Address(i.addr), sb.osSbox.InterfaceOptions().Routes(i.routes))
... ...
@@ -951,6 +956,11 @@ func OptionGeneric(generic map[string]interface{}) SandboxOption {
951 951
 func (eh epHeap) Len() int { return len(eh) }
952 952
 
953 953
 func (eh epHeap) Less(i, j int) bool {
954
+	var (
955
+		cip, cjp int
956
+		ok       bool
957
+	)
958
+
954 959
 	ci, _ := eh[i].getSandbox()
955 960
 	cj, _ := eh[j].getSandbox()
956 961
 
... ...
@@ -965,14 +975,20 @@ func (eh epHeap) Less(i, j int) bool {
965 965
 		return true
966 966
 	}
967 967
 
968
-	cip, ok := ci.epPriority[eh[i].ID()]
969
-	if !ok {
970
-		cip = 0
968
+	if ci != nil {
969
+		cip, ok = ci.epPriority[eh[i].ID()]
970
+		if !ok {
971
+			cip = 0
972
+		}
971 973
 	}
972
-	cjp, ok := cj.epPriority[eh[j].ID()]
973
-	if !ok {
974
-		cjp = 0
974
+
975
+	if cj != nil {
976
+		cjp, ok = cj.epPriority[eh[j].ID()]
977
+		if !ok {
978
+			cjp = 0
979
+		}
975 980
 	}
981
+
976 982
 	if cip == cjp {
977 983
 		return eh[i].network.Name() < eh[j].network.Name()
978 984
 	}