Merge pull request #13017 from cpuguy83/12859_fix_lxc_wait_exitcodes

Fix LXC stop signals
This commit is contained in:
Alexander Morozov 2015-05-06 11:21:44 -07:00
Родитель a242ceaa09 d2c4ee37c6
Коммит 71c1a7ea7f
2 изменённых файлов: 32 добавлений и 11 удалений

Просмотреть файл

@ -127,6 +127,7 @@ func (d *driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, startCallba
"lxc-start",
"-n", c.ID,
"-f", configPath,
"-q",
}
// From lxc>=1.1 the default behavior is to daemonize containers after start
@ -278,19 +279,20 @@ func (d *driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, startCallba
oomKillNotification, err := notifyOnOOM(cgroupPaths)
<-waitLock
exitCode := getExitCode(c)
if err == nil {
_, oomKill = <-oomKillNotification
logrus.Debugf("oomKill error %s waitErr %s", oomKill, waitErr)
logrus.Debugf("oomKill error: %v, waitErr: %v", oomKill, waitErr)
} else {
logrus.Warnf("Your kernel does not support OOM notifications: %s", err)
}
// check oom error
exitCode := getExitCode(c)
if oomKill {
exitCode = 137
}
return execdriver.ExitStatus{ExitCode: exitCode, OOMKilled: oomKill}, waitErr
}
@ -468,7 +470,11 @@ func getExitCode(c *execdriver.Command) int {
}
func (d *driver) Kill(c *execdriver.Command, sig int) error {
return KillLxc(c.ID, sig)
if sig == 9 || c.ProcessConfig.Process == nil {
return KillLxc(c.ID, sig)
}
return c.ProcessConfig.Process.Signal(syscall.Signal(sig))
}
func (d *driver) Pause(c *execdriver.Command) error {
@ -528,7 +534,8 @@ func KillLxc(id string, sig int) error {
if err == nil {
output, err = exec.Command("lxc-kill", "-n", id, strconv.Itoa(sig)).CombinedOutput()
} else {
output, err = exec.Command("lxc-stop", "-k", "-n", id, strconv.Itoa(sig)).CombinedOutput()
// lxc-stop does not take arbitrary signals like lxc-kill does
output, err = exec.Command("lxc-stop", "-k", "-n", id).CombinedOutput()
}
if err != nil {
return fmt.Errorf("Err: %s Output: %s", err, output)

Просмотреть файл

@ -1,6 +1,7 @@
package main
import (
"bytes"
"os/exec"
"strings"
"time"
@ -44,7 +45,7 @@ func (s *DockerSuite) TestWaitNonBlockedExitZero(c *check.C) {
// blocking wait with 0 exit code
func (s *DockerSuite) TestWaitBlockedExitZero(c *check.C) {
out, _ := dockerCmd(c, "run", "-d", "busybox", "/bin/sh", "-c", "trap 'exit 0' SIGTERM; while true; do sleep 0.01; done")
out, _ := dockerCmd(c, "run", "-d", "busybox", "/bin/sh", "-c", "trap 'exit 0' TERM; while true; do sleep 0.01; done")
containerID := strings.TrimSpace(out)
if err := waitRun(containerID); err != nil {
@ -107,7 +108,7 @@ func (s *DockerSuite) TestWaitNonBlockedExitRandom(c *check.C) {
// blocking wait with random exit code
func (s *DockerSuite) TestWaitBlockedExitRandom(c *check.C) {
out, _ := dockerCmd(c, "run", "-d", "busybox", "sh", "-c", "trap 'exit 99' SIGTERM; while true; do sleep 0.01; done")
out, _ := dockerCmd(c, "run", "-d", "busybox", "/bin/sh", "-c", "trap 'exit 99' TERM; while true; do sleep 0.01; done")
containerID := strings.TrimSpace(out)
if err := waitRun(containerID); err != nil {
c.Fatal(err)
@ -116,21 +117,34 @@ func (s *DockerSuite) TestWaitBlockedExitRandom(c *check.C) {
c.Fatal(err)
}
chWait := make(chan string)
chWait := make(chan error)
waitCmd := exec.Command(dockerBinary, "wait", containerID)
waitCmdOut := bytes.NewBuffer(nil)
waitCmd.Stdout = waitCmdOut
if err := waitCmd.Start(); err != nil {
c.Fatal(err)
}
go func() {
out, _, _ := runCommandWithOutput(exec.Command(dockerBinary, "wait", containerID))
chWait <- out
chWait <- waitCmd.Wait()
}()
time.Sleep(100 * time.Millisecond)
dockerCmd(c, "stop", containerID)
select {
case status := <-chWait:
case err := <-chWait:
if err != nil {
c.Fatal(err)
}
status, err := waitCmdOut.ReadString('\n')
if err != nil {
c.Fatal(err)
}
if strings.TrimSpace(status) != "99" {
c.Fatalf("expected exit 99, got %s", status)
}
case <-time.After(2 * time.Second):
waitCmd.Process.Kill()
c.Fatal("timeout waiting for `docker wait` to exit")
}
}