From 9052c886f029c9bb4ebcc5c404c9e240aa72674b Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Fri, 11 Dec 2015 11:56:01 -0800 Subject: [PATCH] Fix leak in logging and proc pipes Signed-off-by: Michael Crosby --- delete.go | 6 ++++-- linux/linux.go | 17 +++++++++++++++-- runtime/container.go | 1 + 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/delete.go b/delete.go index 075b5d4..722da8a 100644 --- a/delete.go +++ b/delete.go @@ -14,8 +14,10 @@ func (h *DeleteEvent) Handle(e *Event) error { if err := h.deleteContainer(i.container); err != nil { logrus.WithField("error", err).Error("containerd: deleting container") } - if err := i.logger.Close(); err != nil { - logrus.WithField("error", err).Error("containerd: close container logger") + if i.logger != nil { + if err := i.logger.Close(); err != nil { + logrus.WithField("error", err).Error("containerd: close container logger") + } } h.s.notifySubscribers(&Event{ Type: ExitEventType, diff --git a/linux/linux.go b/linux/linux.go index 5809f43..d5f5c4e 100644 --- a/linux/linux.go +++ b/linux/linux.go @@ -5,6 +5,7 @@ package linux import ( "encoding/json" "fmt" + "io" "io/ioutil" "os" "path/filepath" @@ -184,6 +185,15 @@ func (p *libcontainerProcess) Signal(s os.Signal) error { return p.process.Signal(s) } +func (p *libcontainerProcess) Close() error { + // in close we always need to call wait to close/flush any pipes + _, err := p.process.Wait() + p.process.Stdin.(io.Closer).Close() + p.process.Stdout.(io.Closer).Close() + p.process.Stderr.(io.Closer).Close() + return err +} + type libcontainerContainer struct { c libcontainer.Container initProcess *libcontainerProcess @@ -305,6 +315,7 @@ func (c *libcontainerContainer) SetExited(status int) { c.exitStatus = status // meh c.exited = true + c.initProcess.Close() } func (c *libcontainerContainer) Stats() (*runtime.Stat, error) { @@ -334,11 +345,13 @@ func (c *libcontainerContainer) Processes() ([]runtime.Process, error) { } func (c *libcontainerContainer) RemoveProcess(pid int) error { - if _, ok := c.additionalProcesses[pid]; !ok { + proc, ok := c.additionalProcesses[pid] + if !ok { return runtime.ErrNotChildProcess } + err := proc.Close() delete(c.additionalProcesses, pid) - return nil + return err } func NewRuntime(stateDir string) (runtime.Runtime, error) { diff --git a/runtime/container.go b/runtime/container.go index 863ffe4..7069f9d 100644 --- a/runtime/container.go +++ b/runtime/container.go @@ -9,6 +9,7 @@ import ( ) type Process interface { + io.Closer Pid() (int, error) Spec() specs.Process Signal(os.Signal) error