diff --git a/daemon/execdriver/lxc/driver.go b/daemon/execdriver/lxc/driver.go index 30b36e775d..12793bd01f 100644 --- a/daemon/execdriver/lxc/driver.go +++ b/daemon/execdriver/lxc/driver.go @@ -324,24 +324,20 @@ func (d *Driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, hooks execd c.ContainerPid = pid - oomKill := false - oomKillNotification, err := notifyOnOOM(cgroupPaths) - if hooks.Start != nil { logrus.Debugf("Invoking startCallback") - hooks.Start(&c.ProcessConfig, pid, oomKillNotification) - + chOOM := make(chan struct{}) + close(chOOM) + hooks.Start(&c.ProcessConfig, pid, chOOM) } + oomKillNotification := notifyChannelOOM(cgroupPaths) + <-waitLock exitCode := getExitCode(c) - if err == nil { - _, oomKill = <-oomKillNotification - logrus.Debugf("oomKill error: %v, waitErr: %v", oomKill, waitErr) - } else { - logrus.Warnf("Your kernel does not support OOM notifications: %s", err) - } + _, oomKill := <-oomKillNotification + logrus.Debugf("oomKill error: %v, waitErr: %v", oomKill, waitErr) // check oom error if oomKill { @@ -351,6 +347,17 @@ func (d *Driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, hooks execd return execdriver.ExitStatus{ExitCode: exitCode, OOMKilled: oomKill}, waitErr } +func notifyChannelOOM(paths map[string]string) <-chan struct{} { + oom, err := notifyOnOOM(paths) + if err != nil { + logrus.Warnf("Your kernel does not support OOM notifications: %s", err) + c := make(chan struct{}) + close(c) + return c + } + return oom +} + // copy from libcontainer func notifyOnOOM(paths map[string]string) (<-chan struct{}, error) { dir := paths["memory"] @@ -386,11 +393,13 @@ func notifyOnOOM(paths map[string]string) (<-chan struct{}, error) { buf := make([]byte, 8) for { if _, err := eventfd.Read(buf); err != nil { + logrus.Warn(err) return } // When a cgroup is destroyed, an event is sent to eventfd. // So if the control path is gone, return instead of notifying. if _, err := os.Lstat(eventControlPath); os.IsNotExist(err) { + logrus.Warn(err) return } ch <- struct{}{} @@ -424,6 +433,11 @@ func cgroupPaths(containerID string) (map[string]string, error) { //unsupported subystem continue } + // if we are running dind + dockerPathIdx := strings.LastIndex(cgroupDir, "docker") + if dockerPathIdx != -1 { + cgroupDir = cgroupDir[:dockerPathIdx-1] + } path := filepath.Join(cgroupRoot, cgroupDir, "lxc", containerID) paths[subsystem] = path } diff --git a/daemon/execdriver/native/driver.go b/daemon/execdriver/native/driver.go index 09f84a37bb..94f200a311 100644 --- a/daemon/execdriver/native/driver.go +++ b/daemon/execdriver/native/driver.go @@ -167,7 +167,6 @@ func (d *Driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, hooks execd oom := notifyOnOOM(cont) if hooks.Start != nil { - pid, err := p.Pid() if err != nil { p.Signal(os.Kill) diff --git a/integration-cli/docker_cli_events_unix_test.go b/integration-cli/docker_cli_events_unix_test.go index ca7c092214..9115809b87 100644 --- a/integration-cli/docker_cli_events_unix_test.go +++ b/integration-cli/docker_cli_events_unix_test.go @@ -56,6 +56,7 @@ func (s *DockerSuite) TestEventsRedirectStdout(c *check.C) { func (s *DockerSuite) TestEventsOOMDisableFalse(c *check.C) { testRequires(c, DaemonIsLinux) + testRequires(c, NativeExecDriver) testRequires(c, oomControl) errChan := make(chan error) @@ -103,6 +104,7 @@ func (s *DockerSuite) TestEventsOOMDisableFalse(c *check.C) { func (s *DockerSuite) TestEventsOOMDisableTrue(c *check.C) { testRequires(c, DaemonIsLinux) + testRequires(c, NativeExecDriver) testRequires(c, oomControl) errChan := make(chan error)