From 9d4b69df7326763d210e77cc108afb26f5d7a532 Mon Sep 17 00:00:00 2001 From: Jana Radhakrishnan Date: Tue, 19 May 2015 16:12:47 +0000 Subject: [PATCH] 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 --- libnetwork/controller.go | 4 +-- libnetwork/libnetwork_test.go | 57 ++++++++++++++++++++++++++++++++--- 2 files changed, 54 insertions(+), 7 deletions(-) diff --git a/libnetwork/controller.go b/libnetwork/controller.go index 8b4d48e861..a64d6e526b 100644 --- a/libnetwork/controller.go +++ b/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 } diff --git a/libnetwork/libnetwork_test.go b/libnetwork/libnetwork_test.go index 6b904a176c..b628190657 100644 --- a/libnetwork/libnetwork_test.go +++ b/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) }