Просмотр исходного кода

Fix panic on leave of host driver endpont leave

There is a panic when two containers joining a host
network leave one after another. The problem was that
in controller.go the sandboxData was not stored as a
pointer reference. So when we got the data from the map
it was the copy of the data and refcnt increment was done
on that. Changed it to hold a reference.  Also added a test
case to test it.

Signed-off-by: Jana Radhakrishnan <mrjana@docker.com>
Jana Radhakrishnan 10 лет назад
Родитель
Сommit
9d4b69df73
2 измененных файлов с 54 добавлено и 7 удалено
  1. 2 2
      libnetwork/controller.go
  2. 52 5
      libnetwork/libnetwork_test.go

+ 2 - 2
libnetwork/controller.go

@@ -89,7 +89,7 @@ type sandboxData struct {
 
 type networkTable map[types.UUID]*network
 type endpointTable map[types.UUID]*endpoint
-type sandboxTable map[string]sandboxData
+type sandboxTable map[string]*sandboxData
 
 type controller struct {
 	networks  networkTable
@@ -247,7 +247,7 @@ func (c *controller) sandboxAdd(key string, create bool) (sandbox.Sandbox, error
 			return nil, err
 		}
 
-		sData = sandboxData{sandbox: sb, refCnt: 1}
+		sData = &sandboxData{sandbox: sb, refCnt: 1}
 		c.sandboxes[key] = sData
 		return sData.sandbox, nil
 	}

+ 52 - 5
libnetwork/libnetwork_test.go

@@ -113,13 +113,13 @@ func TestHost(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	ep, err := network.CreateEndpoint("testep")
+	ep1, err := network.CreateEndpoint("testep1")
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	_, err = ep.Join("host_container",
-		libnetwork.JoinOptionHostname("test"),
+	_, err = ep1.Join("host_container1",
+		libnetwork.JoinOptionHostname("test1"),
 		libnetwork.JoinOptionDomainname("docker.io"),
 		libnetwork.JoinOptionExtraHost("web", "192.168.0.1"),
 		libnetwork.JoinOptionUseDefaultSandbox())
@@ -127,12 +127,59 @@ func TestHost(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	err = ep.Leave("host_container")
+	ep2, err := network.CreateEndpoint("testep2")
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	if err := ep.Delete(); err != nil {
+	_, err = ep2.Join("host_container2",
+		libnetwork.JoinOptionHostname("test2"),
+		libnetwork.JoinOptionDomainname("docker.io"),
+		libnetwork.JoinOptionExtraHost("web", "192.168.0.1"),
+		libnetwork.JoinOptionUseDefaultSandbox())
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	err = ep1.Leave("host_container1")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	err = ep2.Leave("host_container2")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if err := ep1.Delete(); err != nil {
+		t.Fatal(err)
+	}
+
+	if err := ep2.Delete(); err != nil {
+		t.Fatal(err)
+	}
+
+	// Try to create another host endpoint and join/leave that.
+	ep3, err := network.CreateEndpoint("testep3")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	_, err = ep3.Join("host_container3",
+		libnetwork.JoinOptionHostname("test3"),
+		libnetwork.JoinOptionDomainname("docker.io"),
+		libnetwork.JoinOptionExtraHost("web", "192.168.0.1"),
+		libnetwork.JoinOptionUseDefaultSandbox())
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	err = ep3.Leave("host_container3")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if err := ep3.Delete(); err != nil {
 		t.Fatal(err)
 	}