Browse code

Fix liverestore/restartmanager panic in v1.12

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>

Tonis Tiigi authored on 2016/12/22 04:29:39
Showing 2 changed files
... ...
@@ -2717,3 +2717,35 @@ func (s *DockerDaemonSuite) TestRunWithRuntimeFromCommandLine(c *check.C) {
2717 2717
 	out, err = s.d.Cmd("run", "--rm", "--runtime=runc", "busybox", "ls")
2718 2718
 	c.Assert(err, check.IsNil, check.Commentf(out))
2719 2719
 }
2720
+
2721
+// #29598
2722
+func (s *DockerDaemonSuite) TestRestartPolicyWithLiveRestore(c *check.C) {
2723
+	testRequires(c, SameHostDaemon, DaemonIsLinux)
2724
+	c.Assert(s.d.StartWithBusybox("--live-restore"), check.IsNil)
2725
+
2726
+	out, err := s.d.Cmd("run", "-d", "--restart", "always", "busybox", "top")
2727
+	c.Assert(err, check.IsNil, check.Commentf("Output: %s", out))
2728
+	id := strings.TrimSpace(out)
2729
+
2730
+	c.Assert(s.d.Restart("--live-restore"), check.IsNil)
2731
+
2732
+	c.Assert(s.d.waitRun(id), check.IsNil)
2733
+
2734
+	pid, err := s.d.Cmd("inspect", "-f", "{{.State.Pid}}", id)
2735
+	c.Assert(err, check.IsNil)
2736
+	pidint, err := strconv.Atoi(strings.TrimSpace(pid))
2737
+	c.Assert(err, check.IsNil)
2738
+	c.Assert(syscall.Kill(pidint, syscall.SIGKILL), check.IsNil)
2739
+
2740
+	// This test is only for v1.12 and only checks that killing of a process
2741
+	// doesn't cause a panic. Actual issue is fixed in v1.13 with a proper test.
2742
+	calls := 0
2743
+	for range time.NewTicker(500 * time.Millisecond).C {
2744
+		out, err := s.d.inspectFilter(id, "json .Id")
2745
+		c.Assert(err, checker.IsNil, check.Commentf(out))
2746
+		calls++
2747
+		if calls >= 10 {
2748
+			break
2749
+		}
2750
+	}
2751
+}
... ...
@@ -424,6 +424,7 @@ func (clnt *client) restore(cont *containerd.Container, lastEvent *containerd.Ev
424 424
 
425 425
 	container := clnt.newContainer(cont.BundlePath, options...)
426 426
 	container.systemPid = systemPid(cont)
427
+	container.attachStdio = attachStdio
427 428
 
428 429
 	var terminal bool
429 430
 	for _, p := range cont.Processes {
... ...
@@ -596,6 +597,7 @@ func (clnt *client) Restore(containerID string, attachStdio StdioCallback, optio
596 596
 	w := clnt.getOrCreateExitNotifier(containerID)
597 597
 	clnt.lock(cont.Id)
598 598
 	container := clnt.newContainer(cont.BundlePath)
599
+	container.attachStdio = attachStdio
599 600
 	container.systemPid = systemPid(cont)
600 601
 	clnt.appendContainer(container)
601 602
 	clnt.unlock(cont.Id)