Browse code

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 authored on 2015/09/24 19:13:19
Showing 3 changed files
... ...
@@ -324,24 +324,20 @@ func (d *Driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, hooks execd
324 324
 
325 325
 	c.ContainerPid = pid
326 326
 
327
-	oomKill := false
328
-	oomKillNotification, err := notifyOnOOM(cgroupPaths)
329
-
330 327
 	if hooks.Start != nil {
331 328
 		logrus.Debugf("Invoking startCallback")
332
-		hooks.Start(&c.ProcessConfig, pid, oomKillNotification)
333
-
329
+		chOOM := make(chan struct{})
330
+		close(chOOM)
331
+		hooks.Start(&c.ProcessConfig, pid, chOOM)
334 332
 	}
335 333
 
334
+	oomKillNotification := notifyChannelOOM(cgroupPaths)
335
+
336 336
 	<-waitLock
337 337
 	exitCode := getExitCode(c)
338 338
 
339
-	if err == nil {
340
-		_, oomKill = <-oomKillNotification
341
-		logrus.Debugf("oomKill error: %v, waitErr: %v", oomKill, waitErr)
342
-	} else {
343
-		logrus.Warnf("Your kernel does not support OOM notifications: %s", err)
344
-	}
339
+	_, oomKill := <-oomKillNotification
340
+	logrus.Debugf("oomKill error: %v, waitErr: %v", oomKill, waitErr)
345 341
 
346 342
 	// check oom error
347 343
 	if oomKill {
... ...
@@ -351,6 +347,17 @@ func (d *Driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, hooks execd
351 351
 	return execdriver.ExitStatus{ExitCode: exitCode, OOMKilled: oomKill}, waitErr
352 352
 }
353 353
 
354
+func notifyChannelOOM(paths map[string]string) <-chan struct{} {
355
+	oom, err := notifyOnOOM(paths)
356
+	if err != nil {
357
+		logrus.Warnf("Your kernel does not support OOM notifications: %s", err)
358
+		c := make(chan struct{})
359
+		close(c)
360
+		return c
361
+	}
362
+	return oom
363
+}
364
+
354 365
 // copy from libcontainer
355 366
 func notifyOnOOM(paths map[string]string) (<-chan struct{}, error) {
356 367
 	dir := paths["memory"]
... ...
@@ -386,11 +393,13 @@ func notifyOnOOM(paths map[string]string) (<-chan struct{}, error) {
386 386
 		buf := make([]byte, 8)
387 387
 		for {
388 388
 			if _, err := eventfd.Read(buf); err != nil {
389
+				logrus.Warn(err)
389 390
 				return
390 391
 			}
391 392
 			// When a cgroup is destroyed, an event is sent to eventfd.
392 393
 			// So if the control path is gone, return instead of notifying.
393 394
 			if _, err := os.Lstat(eventControlPath); os.IsNotExist(err) {
395
+				logrus.Warn(err)
394 396
 				return
395 397
 			}
396 398
 			ch <- struct{}{}
... ...
@@ -424,6 +433,11 @@ func cgroupPaths(containerID string) (map[string]string, error) {
424 424
 			//unsupported subystem
425 425
 			continue
426 426
 		}
427
+		// if we are running dind
428
+		dockerPathIdx := strings.LastIndex(cgroupDir, "docker")
429
+		if dockerPathIdx != -1 {
430
+			cgroupDir = cgroupDir[:dockerPathIdx-1]
431
+		}
427 432
 		path := filepath.Join(cgroupRoot, cgroupDir, "lxc", containerID)
428 433
 		paths[subsystem] = path
429 434
 	}
... ...
@@ -167,7 +167,6 @@ func (d *Driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, hooks execd
167 167
 
168 168
 	oom := notifyOnOOM(cont)
169 169
 	if hooks.Start != nil {
170
-
171 170
 		pid, err := p.Pid()
172 171
 		if err != nil {
173 172
 			p.Signal(os.Kill)
... ...
@@ -56,6 +56,7 @@ func (s *DockerSuite) TestEventsRedirectStdout(c *check.C) {
56 56
 
57 57
 func (s *DockerSuite) TestEventsOOMDisableFalse(c *check.C) {
58 58
 	testRequires(c, DaemonIsLinux)
59
+	testRequires(c, NativeExecDriver)
59 60
 	testRequires(c, oomControl)
60 61
 
61 62
 	errChan := make(chan error)
... ...
@@ -103,6 +104,7 @@ func (s *DockerSuite) TestEventsOOMDisableFalse(c *check.C) {
103 103
 
104 104
 func (s *DockerSuite) TestEventsOOMDisableTrue(c *check.C) {
105 105
 	testRequires(c, DaemonIsLinux)
106
+	testRequires(c, NativeExecDriver)
106 107
 	testRequires(c, oomControl)
107 108
 
108 109
 	errChan := make(chan error)