Переглянути джерело

Merge pull request #29721 from coolljt0725/follow_29365

Follow up #29365, fix fail to remove container after restart
Sebastiaan van Stijn 8 роки тому
батько
коміт
36ed7d58bb

+ 17 - 9
daemon/daemon.go

@@ -147,15 +147,6 @@ func (daemon *Daemon) restore() error {
 				continue
 			}
 			container.RWLayer = rwlayer
-			if err := daemon.Mount(container); err != nil {
-				// The mount is unlikely to fail. However, in case mount fails
-				// the container should be allowed to restore here. Some functionalities
-				// (like docker exec -u user) might be missing but container is able to be
-				// stopped/restarted/removed.
-				// See #29365 for related information.
-				// The error is only logged here.
-				logrus.Warnf("Failed to mount container %v: %v", id, err)
-			}
 			logrus.Debugf("Loaded container %v", container.ID)
 
 			containers[container.ID] = container
@@ -213,6 +204,23 @@ func (daemon *Daemon) restore() error {
 					logrus.Errorf("Failed to restore %s with containerd: %s", c.ID, err)
 					return
 				}
+
+				// we call Mount and then Unmount to get BaseFs of the container
+				if err := daemon.Mount(c); err != nil {
+					// The mount is unlikely to fail. However, in case mount fails
+					// the container should be allowed to restore here. Some functionalities
+					// (like docker exec -u user) might be missing but container is able to be
+					// stopped/restarted/removed.
+					// See #29365 for related information.
+					// The error is only logged here.
+					logrus.Warnf("Failed to mount container on getting BaseFs path %v: %v", c.ID, err)
+				} else {
+					// if mount success, then unmount it
+					if err := daemon.Unmount(c); err != nil {
+						logrus.Warnf("Failed to umount container on getting BaseFs path %v: %v", c.ID, err)
+					}
+				}
+
 				c.ResetRestartManager(false)
 				if !c.HostConfig.NetworkMode.IsContainer() && c.IsRunning() {
 					options, err := daemon.buildSandboxOptions(c)

+ 5 - 0
integration-cli/daemon/daemon.go

@@ -654,6 +654,11 @@ func (d *Daemon) ReadLogFile() ([]byte, error) {
 	return ioutil.ReadFile(d.logFile.Name())
 }
 
+// InspectField returns the field filter by 'filter'
+func (d *Daemon) InspectField(name, filter string) (string, error) {
+	return d.inspectFilter(name, filter)
+}
+
 func (d *Daemon) inspectFilter(name, filter string) (string, error) {
 	format := fmt.Sprintf("{{%s}}", filter)
 	out, err := d.Cmd("inspect", "-f", format, name)

+ 35 - 1
integration-cli/docker_cli_daemon_test.go

@@ -3,6 +3,7 @@
 package main
 
 import (
+	"bufio"
 	"bytes"
 	"encoding/json"
 	"fmt"
@@ -2822,7 +2823,7 @@ func (s *DockerDaemonSuite) TestExecWithUserAfterLiveRestore(c *check.C) {
 	out, err := s.d.Cmd("run", "-d", "--name=top", "busybox", "sh", "-c", "addgroup -S test && adduser -S -G test test -D -s /bin/sh && top")
 	c.Assert(err, check.IsNil, check.Commentf("Output: %s", out))
 
-	waitRun("top")
+	s.d.WaitRun("top")
 
 	out1, err := s.d.Cmd("exec", "-u", "test", "top", "id")
 	// uid=100(test) gid=101(test) groups=101(test)
@@ -2838,3 +2839,36 @@ func (s *DockerDaemonSuite) TestExecWithUserAfterLiveRestore(c *check.C) {
 	out, err = s.d.Cmd("stop", "top")
 	c.Assert(err, check.IsNil, check.Commentf("Output: %s", out))
 }
+
+func (s *DockerDaemonSuite) TestRemoveContainerAfterLiveRestore(c *check.C) {
+	testRequires(c, DaemonIsLinux, overlayFSSupported, SameHostDaemon)
+	s.d.StartWithBusybox(c, "--live-restore", "--storage-driver", "overlay")
+	out, err := s.d.Cmd("run", "-d", "--name=top", "busybox", "top")
+	c.Assert(err, check.IsNil, check.Commentf("Output: %s", out))
+
+	s.d.WaitRun("top")
+
+	// restart daemon.
+	s.d.Restart(c, "--live-restore", "--storage-driver", "overlay")
+
+	out, err = s.d.Cmd("stop", "top")
+	c.Assert(err, check.IsNil, check.Commentf("Output: %s", out))
+
+	// test if the rootfs mountpoint still exist
+	mountpoint, err := s.d.InspectField("top", ".GraphDriver.Data.MergedDir")
+	c.Assert(err, check.IsNil)
+	f, err := os.Open("/proc/self/mountinfo")
+	c.Assert(err, check.IsNil)
+	defer f.Close()
+	sc := bufio.NewScanner(f)
+	for sc.Scan() {
+		line := sc.Text()
+		if strings.Contains(line, mountpoint) {
+			c.Fatalf("mountinfo should not include the mountpoint of stop container")
+		}
+	}
+
+	out, err = s.d.Cmd("rm", "top")
+	c.Assert(err, check.IsNil, check.Commentf("Output: %s", out))
+
+}