Follow up #29365, fix fail to remove container after restart
| ... | ... |
@@ -147,15 +147,6 @@ func (daemon *Daemon) restore() error {
|
| 147 | 147 |
continue |
| 148 | 148 |
} |
| 149 | 149 |
container.RWLayer = rwlayer |
| 150 |
- if err := daemon.Mount(container); err != nil {
|
|
| 151 |
- // The mount is unlikely to fail. However, in case mount fails |
|
| 152 |
- // the container should be allowed to restore here. Some functionalities |
|
| 153 |
- // (like docker exec -u user) might be missing but container is able to be |
|
| 154 |
- // stopped/restarted/removed. |
|
| 155 |
- // See #29365 for related information. |
|
| 156 |
- // The error is only logged here. |
|
| 157 |
- logrus.Warnf("Failed to mount container %v: %v", id, err)
|
|
| 158 |
- } |
|
| 159 | 150 |
logrus.Debugf("Loaded container %v", container.ID)
|
| 160 | 151 |
|
| 161 | 152 |
containers[container.ID] = container |
| ... | ... |
@@ -213,6 +204,23 @@ func (daemon *Daemon) restore() error {
|
| 213 | 213 |
logrus.Errorf("Failed to restore %s with containerd: %s", c.ID, err)
|
| 214 | 214 |
return |
| 215 | 215 |
} |
| 216 |
+ |
|
| 217 |
+ // we call Mount and then Unmount to get BaseFs of the container |
|
| 218 |
+ if err := daemon.Mount(c); err != nil {
|
|
| 219 |
+ // The mount is unlikely to fail. However, in case mount fails |
|
| 220 |
+ // the container should be allowed to restore here. Some functionalities |
|
| 221 |
+ // (like docker exec -u user) might be missing but container is able to be |
|
| 222 |
+ // stopped/restarted/removed. |
|
| 223 |
+ // See #29365 for related information. |
|
| 224 |
+ // The error is only logged here. |
|
| 225 |
+ logrus.Warnf("Failed to mount container on getting BaseFs path %v: %v", c.ID, err)
|
|
| 226 |
+ } else {
|
|
| 227 |
+ // if mount success, then unmount it |
|
| 228 |
+ if err := daemon.Unmount(c); err != nil {
|
|
| 229 |
+ logrus.Warnf("Failed to umount container on getting BaseFs path %v: %v", c.ID, err)
|
|
| 230 |
+ } |
|
| 231 |
+ } |
|
| 232 |
+ |
|
| 216 | 233 |
c.ResetRestartManager(false) |
| 217 | 234 |
if !c.HostConfig.NetworkMode.IsContainer() && c.IsRunning() {
|
| 218 | 235 |
options, err := daemon.buildSandboxOptions(c) |
| ... | ... |
@@ -654,6 +654,11 @@ func (d *Daemon) ReadLogFile() ([]byte, error) {
|
| 654 | 654 |
return ioutil.ReadFile(d.logFile.Name()) |
| 655 | 655 |
} |
| 656 | 656 |
|
| 657 |
+// InspectField returns the field filter by 'filter' |
|
| 658 |
+func (d *Daemon) InspectField(name, filter string) (string, error) {
|
|
| 659 |
+ return d.inspectFilter(name, filter) |
|
| 660 |
+} |
|
| 661 |
+ |
|
| 657 | 662 |
func (d *Daemon) inspectFilter(name, filter string) (string, error) {
|
| 658 | 663 |
format := fmt.Sprintf("{{%s}}", filter)
|
| 659 | 664 |
out, err := d.Cmd("inspect", "-f", format, name)
|
| ... | ... |
@@ -3,6 +3,7 @@ |
| 3 | 3 |
package main |
| 4 | 4 |
|
| 5 | 5 |
import ( |
| 6 |
+ "bufio" |
|
| 6 | 7 |
"bytes" |
| 7 | 8 |
"encoding/json" |
| 8 | 9 |
"fmt" |
| ... | ... |
@@ -2822,7 +2823,7 @@ func (s *DockerDaemonSuite) TestExecWithUserAfterLiveRestore(c *check.C) {
|
| 2822 | 2822 |
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")
|
| 2823 | 2823 |
c.Assert(err, check.IsNil, check.Commentf("Output: %s", out))
|
| 2824 | 2824 |
|
| 2825 |
- waitRun("top")
|
|
| 2825 |
+ s.d.WaitRun("top")
|
|
| 2826 | 2826 |
|
| 2827 | 2827 |
out1, err := s.d.Cmd("exec", "-u", "test", "top", "id")
|
| 2828 | 2828 |
// uid=100(test) gid=101(test) groups=101(test) |
| ... | ... |
@@ -2838,3 +2839,36 @@ func (s *DockerDaemonSuite) TestExecWithUserAfterLiveRestore(c *check.C) {
|
| 2838 | 2838 |
out, err = s.d.Cmd("stop", "top")
|
| 2839 | 2839 |
c.Assert(err, check.IsNil, check.Commentf("Output: %s", out))
|
| 2840 | 2840 |
} |
| 2841 |
+ |
|
| 2842 |
+func (s *DockerDaemonSuite) TestRemoveContainerAfterLiveRestore(c *check.C) {
|
|
| 2843 |
+ testRequires(c, DaemonIsLinux, overlayFSSupported, SameHostDaemon) |
|
| 2844 |
+ s.d.StartWithBusybox(c, "--live-restore", "--storage-driver", "overlay") |
|
| 2845 |
+ out, err := s.d.Cmd("run", "-d", "--name=top", "busybox", "top")
|
|
| 2846 |
+ c.Assert(err, check.IsNil, check.Commentf("Output: %s", out))
|
|
| 2847 |
+ |
|
| 2848 |
+ s.d.WaitRun("top")
|
|
| 2849 |
+ |
|
| 2850 |
+ // restart daemon. |
|
| 2851 |
+ s.d.Restart(c, "--live-restore", "--storage-driver", "overlay") |
|
| 2852 |
+ |
|
| 2853 |
+ out, err = s.d.Cmd("stop", "top")
|
|
| 2854 |
+ c.Assert(err, check.IsNil, check.Commentf("Output: %s", out))
|
|
| 2855 |
+ |
|
| 2856 |
+ // test if the rootfs mountpoint still exist |
|
| 2857 |
+ mountpoint, err := s.d.InspectField("top", ".GraphDriver.Data.MergedDir")
|
|
| 2858 |
+ c.Assert(err, check.IsNil) |
|
| 2859 |
+ f, err := os.Open("/proc/self/mountinfo")
|
|
| 2860 |
+ c.Assert(err, check.IsNil) |
|
| 2861 |
+ defer f.Close() |
|
| 2862 |
+ sc := bufio.NewScanner(f) |
|
| 2863 |
+ for sc.Scan() {
|
|
| 2864 |
+ line := sc.Text() |
|
| 2865 |
+ if strings.Contains(line, mountpoint) {
|
|
| 2866 |
+ c.Fatalf("mountinfo should not include the mountpoint of stop container")
|
|
| 2867 |
+ } |
|
| 2868 |
+ } |
|
| 2869 |
+ |
|
| 2870 |
+ out, err = s.d.Cmd("rm", "top")
|
|
| 2871 |
+ c.Assert(err, check.IsNil, check.Commentf("Output: %s", out))
|
|
| 2872 |
+ |
|
| 2873 |
+} |