瀏覽代碼

Merge pull request #12007 from crosbymichael/fix-oom-hang

Return closed channel if oom notification fails
Arnaud Porterie 10 年之前
父節點
當前提交
3f77f627d0
共有 1 個文件被更改,包括 16 次插入8 次删除
  1. 16 8
      daemon/execdriver/native/driver.go

+ 16 - 8
daemon/execdriver/native/driver.go

@@ -156,11 +156,7 @@ func (d *driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, startCallba
 		startCallback(&c.ProcessConfig, pid)
 	}
 
-	oomKillNotification, err := cont.NotifyOOM()
-	if err != nil {
-		oomKillNotification = nil
-		logrus.Warnf("Your kernel does not support OOM notifications: %s", err)
-	}
+	oom := notifyOnOOM(cont)
 	waitF := p.Wait
 	if nss := cont.Config().Namespaces; !nss.Contains(configs.NEWPID) {
 		// we need such hack for tracking processes with inerited fds,
@@ -176,12 +172,24 @@ func (d *driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, startCallba
 		ps = execErr.ProcessState
 	}
 	cont.Destroy()
-
-	_, oomKill := <-oomKillNotification
-
+	_, oomKill := <-oom
 	return execdriver.ExitStatus{ExitCode: utils.ExitStatus(ps.Sys().(syscall.WaitStatus)), OOMKilled: oomKill}, nil
 }
 
+// notifyOnOOM returns a channel that signals if the container received an OOM notification
+// for any process.  If it is unable to subscribe to OOM notifications then a closed
+// channel is returned as it will be non-blocking and return the correct result when read.
+func notifyOnOOM(container libcontainer.Container) <-chan struct{} {
+	oom, err := container.NotifyOOM()
+	if err != nil {
+		logrus.Warnf("Your kernel does not support OOM notifications: %s", err)
+		c := make(chan struct{})
+		close(c)
+		return c
+	}
+	return oom
+}
+
 func waitInPIDHost(p *libcontainer.Process, c libcontainer.Container) func() (*os.ProcessState, error) {
 	return func() (*os.ProcessState, error) {
 		pid, err := p.Pid()