瀏覽代碼

daemon: execdriver: lxc: fix cgroup paths

When running LXC dind (outer docker is started with native driver)
cgroup paths point to `/docker/CID` inside `/proc/self/mountinfo` but
these paths aren't mounted (root is wrong). This fix just discard the
cgroup dir from mountinfo and set it to root `/`.
This patch fixes/skip OOM LXC tests that were failing.
Fix #16520

Signed-off-by: Antonio Murdaca <runcom@linux.com>
Signed-off-by: Antonio Murdaca <amurdaca@redhat.com>
Antonio Murdaca 9 年之前
父節點
當前提交
cfcddefacd
共有 3 個文件被更改,包括 27 次插入12 次删除
  1. 25 11
      daemon/execdriver/lxc/driver.go
  2. 0 1
      daemon/execdriver/native/driver.go
  3. 2 0
      integration-cli/docker_cli_events_unix_test.go

+ 25 - 11
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
 	}

+ 0 - 1
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)

+ 2 - 0
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)