1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Add GC loop to clean exec command refs on daemon

This adds an event loop for running a GC cleanup for exec command
references that are on the daemon.  These cannot be cleaned up
immediately because processes may need to get the exit status of the
exec command but it should not grow out of bounds.  The loop is set to a
default 5 minute interval to perform cleanup.

It should be safe to perform this cleanup because unless the clients are
remembering the exec id of the process they launched they can query for
the status and see that it has exited.  If they don't save the exec id
they will have to do an inspect on the container for all exec instances
and anything that is not live inside that container will not be returned
in the container inspect.

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
Michael Crosby 2015-07-08 11:13:47 -07:00
parent 04c9f86bdc
commit 5f017bba48
2 changed files with 33 additions and 0 deletions

View file

@ -731,6 +731,7 @@ func NewDaemon(config *Config, registryService *registry.Service) (daemon *Daemo
d.RegistryService = registryService
d.EventsService = eventsService
d.root = config.Root
go d.execCommandGC()
if err := d.restore(); err != nil {
return nil, err

View file

@ -6,6 +6,7 @@ import (
"io/ioutil"
"strings"
"sync"
"time"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/daemon/execdriver"
@ -247,3 +248,34 @@ func (d *Daemon) Exec(c *Container, execConfig *execConfig, pipes *execdriver.Pi
return exitStatus, err
}
// execCommandGC runs a ticker to clean up the daemon references
// of exec configs that are no longer part of the container.
func (d *Daemon) execCommandGC() {
for range time.Tick(5 * time.Minute) {
var (
cleaned int
liveExecCommands = d.containerExecIds()
ids = d.execCommands.List()
)
for _, id := range ids {
if _, exists := liveExecCommands[id]; !exists {
cleaned++
d.execCommands.Delete(id)
}
}
logrus.Debugf("clean %d unused exec commands", cleaned)
}
}
// containerExecIds returns a list of all the current exec ids that are in use
// and running inside a container.
func (d *Daemon) containerExecIds() map[string]struct{} {
ids := map[string]struct{}{}
for _, c := range d.containers.List() {
for _, id := range c.execCommands.List() {
ids[id] = struct{}{}
}
}
return ids
}