1
0
mirror of https://github.com/docker/cli.git synced 2026-01-22 03:22:01 +03:00

libnetwork: Add garbage collection trigger

When the daemon is going down trigger immediate
garbage collection of libnetwork resources deleted
like namespace path since there will be no way to
remove them when the daemon restarts.

Signed-off-by: Jana Radhakrishnan <mrjana@docker.com>
Upstream-commit: c68e7f96f9636a9b2ab0c2c0dbf753161fa73fc2
Component: engine
This commit is contained in:
Jana Radhakrishnan
2015-06-05 15:02:56 -07:00
parent 68316f4f57
commit 2ee4e129d1
15 changed files with 132 additions and 14 deletions

View File

@@ -79,7 +79,7 @@
},
{
"ImportPath": "github.com/vishvananda/netns",
"Rev": "008d17ae001344769b031375bdb38a86219154c6"
"Rev": "5478c060110032f972e86a1f844fdb9a2f008f2c"
}
]
}

View File

@@ -76,6 +76,9 @@ type NetworkController interface {
// NetworkByID returns the Network which has the passed id. If not found, the error ErrNoSuchNetwork is returned.
NetworkByID(id string) (Network, error)
// GC triggers immediate garbage collection of resources which are garbage collected.
GC()
}
// NetworkWalker is a client provided function which will be used to walk the Networks.
@@ -299,3 +302,7 @@ func (c *controller) loadDriver(networkType string) (driverapi.Driver, error) {
}
return d, nil
}
func (c *controller) GC() {
sandbox.GC()
}

View File

@@ -24,6 +24,7 @@ var (
gpmLock sync.Mutex
gpmWg sync.WaitGroup
gpmCleanupPeriod = 60 * time.Second
gpmChan = make(chan chan struct{})
)
// The networkNamespace type is the linux implementation of the Sandbox
@@ -55,7 +56,18 @@ func removeUnusedPaths() {
period := gpmCleanupPeriod
gpmLock.Unlock()
for range time.Tick(period) {
ticker := time.NewTicker(period)
for {
var (
gc chan struct{}
gcOk bool
)
select {
case <-ticker.C:
case gc, gcOk = <-gpmChan:
}
gpmLock.Lock()
pathList := make([]string, 0, len(garbagePathMap))
for path := range garbagePathMap {
@@ -70,6 +82,9 @@ func removeUnusedPaths() {
}
gpmWg.Done()
if gcOk {
close(gc)
}
}
}
@@ -85,6 +100,18 @@ func removeFromGarbagePaths(path string) {
gpmLock.Unlock()
}
// GC triggers garbage collection of namespace path right away
// and waits for it.
func GC() {
waitGC := make(chan struct{})
// Trigger GC now
gpmChan <- waitGC
// wait for gc to complete
<-waitGC
}
// GenerateKey generates a sandbox key based on the passed
// container id.
func GenerateKey(containerID string) string {

View File

@@ -144,9 +144,16 @@ func verifySandbox(t *testing.T, s Sandbox) {
}
}
func verifyCleanup(t *testing.T, s Sandbox) {
time.Sleep(time.Duration(gpmCleanupPeriod * 2))
func verifyCleanup(t *testing.T, s Sandbox, wait bool) {
if wait {
time.Sleep(time.Duration(gpmCleanupPeriod * 2))
}
if _, err := os.Stat(s.Key()); err == nil {
t.Fatalf("The sandbox path %s is not getting cleanup event after twice the cleanup period", s.Key())
if wait {
t.Fatalf("The sandbox path %s is not getting cleaned up even after twice the cleanup period", s.Key())
} else {
t.Fatalf("The sandbox path %s is not cleaned up after running gc", s.Key())
}
}
}

View File

@@ -54,7 +54,7 @@ func TestSandboxCreate(t *testing.T) {
verifySandbox(t, s)
s.Destroy()
verifyCleanup(t, s)
verifyCleanup(t, s, true)
}
func TestSandboxCreateTwice(t *testing.T) {
@@ -77,6 +77,23 @@ func TestSandboxCreateTwice(t *testing.T) {
s.Destroy()
}
func TestSandboxGC(t *testing.T) {
key, err := newKey(t)
if err != nil {
t.Fatalf("Failed to obtain a key: %v", err)
}
s, err := NewSandbox(key, true)
if err != nil {
t.Fatalf("Failed to create a new sandbox: %v", err)
}
s.Destroy()
GC()
verifyCleanup(t, s, false)
}
func TestInterfaceEqual(t *testing.T) {
list := getInterfaceList()

View File

@@ -12,6 +12,7 @@ import (
"fmt"
"syscall"
)
// NsHandle is a handle to a network namespace. It can be cast directly
// to an int and used as a file descriptor.
type NsHandle int

View File

@@ -1,3 +1,5 @@
// +build linux
package netns
import (

View File

@@ -1,3 +1,5 @@
// +build linux,386
package netns
const (

View File

@@ -1,3 +1,5 @@
// +build linux,arm
package netns
const (

View File

@@ -0,0 +1,7 @@
// +build linux,ppc64le
package netns
const (
SYS_SETNS = 350
)

View File

@@ -10,26 +10,26 @@ var (
ErrNotImplemented = errors.New("not implemented")
)
func Set(ns Namespace) (err error) {
func Set(ns NsHandle) (err error) {
return ErrNotImplemented
}
func New() (ns Namespace, err error) {
func New() (ns NsHandle, err error) {
return -1, ErrNotImplemented
}
func Get() (Namespace, error) {
func Get() (NsHandle, error) {
return -1, ErrNotImplemented
}
func GetFromName(name string) (Namespace, error) {
func GetFromName(name string) (NsHandle, error) {
return -1, ErrNotImplemented
}
func GetFromPid(pid int) (Namespace, error) {
func GetFromPid(pid int) (NsHandle, error) {
return -1, ErrNotImplemented
}
func GetFromDocker(id string) (Namespace, error) {
func GetFromDocker(id string) (NsHandle, error) {
return -1, ErrNotImplemented
}