Browse code

Fix `docker exec -u` issue after docker daemon restart

This fix tries to address the issue raised in 29342 where
`docker exec -u` after docker daemon restart returns an error:
```
unable to find user test: no matching entries in passwd file
```

The reason was that `container.BaseFS` is not present after restart.

This fix adds the `daemon.Mount` during the restore to bring up the
`container.BaseFS`.

An integration test has been added to cover the changes.

This fix fixes 29342.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>

Yong Tang authored on 2016/12/14 01:06:42
Showing 2 changed files
... ...
@@ -149,6 +149,10 @@ func (daemon *Daemon) restore() error {
149 149
 				continue
150 150
 			}
151 151
 			container.RWLayer = rwlayer
152
+			if err := daemon.Mount(container); err != nil {
153
+				logrus.Errorf("Failed to mount container %v: %v", id, err)
154
+				continue
155
+			}
152 156
 			logrus.Debugf("Loaded container %v", container.ID)
153 157
 
154 158
 			containers[container.ID] = container
... ...
@@ -2823,3 +2823,28 @@ func (s *DockerDaemonSuite) TestDaemonShutdownTimeoutWithConfigFile(c *check.C)
2823 2823
 	c.Assert(err, checker.IsNil)
2824 2824
 	c.Assert(string(content), checker.Contains, expectedMessage)
2825 2825
 }
2826
+
2827
+// Test case for 29342
2828
+func (s *DockerDaemonSuite) TestExecWithUserAfterLiveRestore(c *check.C) {
2829
+	testRequires(c, DaemonIsLinux)
2830
+	s.d.StartWithBusybox(c, "--live-restore")
2831
+
2832
+	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")
2833
+	c.Assert(err, check.IsNil, check.Commentf("Output: %s", out))
2834
+
2835
+	waitRun("top")
2836
+
2837
+	out1, err := s.d.Cmd("exec", "-u", "test", "top", "id")
2838
+	// uid=100(test) gid=101(test) groups=101(test)
2839
+	c.Assert(err, check.IsNil, check.Commentf("Output: %s", out1))
2840
+
2841
+	// restart daemon.
2842
+	s.d.Restart(c, "--live-restore")
2843
+
2844
+	out2, err := s.d.Cmd("exec", "-u", "test", "top", "id")
2845
+	c.Assert(err, check.IsNil, check.Commentf("Output: %s", out2))
2846
+	c.Assert(out1, check.Equals, out2, check.Commentf("Output: before restart '%s', after restart '%s'", out1, out2))
2847
+
2848
+	out, err = s.d.Cmd("stop", "top")
2849
+	c.Assert(err, check.IsNil, check.Commentf("Output: %s", out))
2850
+}