소스 검색

Return closed channel if oom notification fails

When working with Go channels you must not set it to nil or else the
channel will block forever.  It will not panic reading from a nil chan
but it blocks.  The correct way to do this is to create the channel then
close it as the correct results to the caller will be returned.

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
(cherry picked from commit 7061a993c5b620d6e68450f1b90f3458bfa1add0)

Docker-DCO-1.1-Signed-off-by: Jessie Frazelle <princess@docker.com> (github: jfrazelle)

Docker-DCO-1.1-Signed-off-by: Jessie Frazelle <jess@docker.com> (github: jfrazelle)
Michael Crosby 10 년 전
부모
커밋
e1381ae328
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)
 		startCallback(&c.ProcessConfig, pid)
 	}
 	}
 
 
-	oomKillNotification, err := cont.NotifyOOM()
-	if err != nil {
-		oomKillNotification = nil
-		log.Warnf("Your kernel does not support OOM notifications: %s", err)
-	}
+	oom := notifyOnOOM(cont)
 	waitF := p.Wait
 	waitF := p.Wait
 	if nss := cont.Config().Namespaces; !nss.Contains(configs.NEWPID) {
 	if nss := cont.Config().Namespaces; !nss.Contains(configs.NEWPID) {
 		// we need such hack for tracking processes with inerited fds,
 		// 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
 		ps = execErr.ProcessState
 	}
 	}
 	cont.Destroy()
 	cont.Destroy()
-
-	_, oomKill := <-oomKillNotification
-
+	_, oomKill := <-oom
 	return execdriver.ExitStatus{ExitCode: utils.ExitStatus(ps.Sys().(syscall.WaitStatus)), OOMKilled: oomKill}, nil
 	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 {
+		log.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) {
 func waitInPIDHost(p *libcontainer.Process, c libcontainer.Container) func() (*os.ProcessState, error) {
 	return func() (*os.ProcessState, error) {
 	return func() (*os.ProcessState, error) {
 		pid, err := p.Pid()
 		pid, err := p.Pid()