UnmountVolumes used to also unmount 'specialMounts' but it no longer does after
a recent refactor of volumes. This patch corrects this behavior to include
unmounting of `networkMounts` which replaces `specialMounts` (now dead code).
Docker-DCO-1.1-Signed-off-by: Josh Hawn <josh.hawn@docker.com> (github: jlhawn)
| ... | ... |
@@ -956,21 +956,37 @@ func (container *Container) DisableLink(name string) {
|
| 956 | 956 |
} |
| 957 | 957 |
|
| 958 | 958 |
func (container *Container) UnmountVolumes(forceSyscall bool) error {
|
| 959 |
- for _, m := range container.MountPoints {
|
|
| 960 |
- dest, err := container.GetResourcePath(m.Destination) |
|
| 959 |
+ var volumeMounts []mountPoint |
|
| 960 |
+ |
|
| 961 |
+ for _, mntPoint := range container.MountPoints {
|
|
| 962 |
+ dest, err := container.GetResourcePath(mntPoint.Destination) |
|
| 963 |
+ if err != nil {
|
|
| 964 |
+ return err |
|
| 965 |
+ } |
|
| 966 |
+ |
|
| 967 |
+ volumeMounts = append(volumeMounts, mountPoint{Destination: dest, Volume: mntPoint.Volume})
|
|
| 968 |
+ } |
|
| 969 |
+ |
|
| 970 |
+ for _, mnt := range container.networkMounts() {
|
|
| 971 |
+ dest, err := container.GetResourcePath(mnt.Destination) |
|
| 961 | 972 |
if err != nil {
|
| 962 | 973 |
return err |
| 963 | 974 |
} |
| 964 | 975 |
|
| 976 |
+ volumeMounts = append(volumeMounts, mountPoint{Destination: dest})
|
|
| 977 |
+ } |
|
| 978 |
+ |
|
| 979 |
+ for _, volumeMount := range volumeMounts {
|
|
| 965 | 980 |
if forceSyscall {
|
| 966 |
- syscall.Unmount(dest, 0) |
|
| 981 |
+ syscall.Unmount(volumeMount.Destination, 0) |
|
| 967 | 982 |
} |
| 968 | 983 |
|
| 969 |
- if m.Volume != nil {
|
|
| 970 |
- if err := m.Volume.Unmount(); err != nil {
|
|
| 984 |
+ if volumeMount.Volume != nil {
|
|
| 985 |
+ if err := volumeMount.Volume.Unmount(); err != nil {
|
|
| 971 | 986 |
return err |
| 972 | 987 |
} |
| 973 | 988 |
} |
| 974 | 989 |
} |
| 990 |
+ |
|
| 975 | 991 |
return nil |
| 976 | 992 |
} |
| ... | ... |
@@ -8,7 +8,6 @@ import ( |
| 8 | 8 |
"path/filepath" |
| 9 | 9 |
"strings" |
| 10 | 10 |
|
| 11 |
- "github.com/docker/docker/daemon/execdriver" |
|
| 12 | 11 |
"github.com/docker/docker/pkg/chrootarchive" |
| 13 | 12 |
"github.com/docker/docker/runconfig" |
| 14 | 13 |
"github.com/docker/docker/volume" |
| ... | ... |
@@ -115,20 +114,6 @@ func validMountMode(mode string) bool {
|
| 115 | 115 |
return validModes[mode] |
| 116 | 116 |
} |
| 117 | 117 |
|
| 118 |
-func (container *Container) specialMounts() []execdriver.Mount {
|
|
| 119 |
- var mounts []execdriver.Mount |
|
| 120 |
- if container.ResolvConfPath != "" {
|
|
| 121 |
- mounts = append(mounts, execdriver.Mount{Source: container.ResolvConfPath, Destination: "/etc/resolv.conf", Writable: !container.hostConfig.ReadonlyRootfs, Private: true})
|
|
| 122 |
- } |
|
| 123 |
- if container.HostnamePath != "" {
|
|
| 124 |
- mounts = append(mounts, execdriver.Mount{Source: container.HostnamePath, Destination: "/etc/hostname", Writable: !container.hostConfig.ReadonlyRootfs, Private: true})
|
|
| 125 |
- } |
|
| 126 |
- if container.HostsPath != "" {
|
|
| 127 |
- mounts = append(mounts, execdriver.Mount{Source: container.HostsPath, Destination: "/etc/hosts", Writable: !container.hostConfig.ReadonlyRootfs, Private: true})
|
|
| 128 |
- } |
|
| 129 |
- return mounts |
|
| 130 |
-} |
|
| 131 |
- |
|
| 132 | 118 |
func copyExistingContents(source, destination string) error {
|
| 133 | 119 |
volList, err := ioutil.ReadDir(source) |
| 134 | 120 |
if err != nil {
|
| ... | ... |
@@ -596,3 +596,40 @@ func (s *DockerSuite) TestCpNameHasColon(c *check.C) {
|
| 596 | 596 |
c.Fatalf("Wrong content in copied file %q, should be %q", content, "lololol\n")
|
| 597 | 597 |
} |
| 598 | 598 |
} |
| 599 |
+ |
|
| 600 |
+func (s *DockerSuite) TestCopyAndRestart(c *check.C) {
|
|
| 601 |
+ expectedMsg := "hello" |
|
| 602 |
+ out, err := exec.Command(dockerBinary, "run", "-d", "busybox", "echo", expectedMsg).CombinedOutput() |
|
| 603 |
+ if err != nil {
|
|
| 604 |
+ c.Fatal(string(out), err) |
|
| 605 |
+ } |
|
| 606 |
+ id := strings.TrimSpace(string(out)) |
|
| 607 |
+ |
|
| 608 |
+ if out, err = exec.Command(dockerBinary, "wait", id).CombinedOutput(); err != nil {
|
|
| 609 |
+ c.Fatalf("unable to wait for container: %s", err)
|
|
| 610 |
+ } |
|
| 611 |
+ |
|
| 612 |
+ status := strings.TrimSpace(string(out)) |
|
| 613 |
+ if status != "0" {
|
|
| 614 |
+ c.Fatalf("container exited with status %s", status)
|
|
| 615 |
+ } |
|
| 616 |
+ |
|
| 617 |
+ tmpDir, err := ioutil.TempDir("", "test-docker-restart-after-copy-")
|
|
| 618 |
+ if err != nil {
|
|
| 619 |
+ c.Fatalf("unable to make temporary directory: %s", err)
|
|
| 620 |
+ } |
|
| 621 |
+ defer os.RemoveAll(tmpDir) |
|
| 622 |
+ |
|
| 623 |
+ if _, err = exec.Command(dockerBinary, "cp", fmt.Sprintf("%s:/etc/issue", id), tmpDir).CombinedOutput(); err != nil {
|
|
| 624 |
+ c.Fatalf("unable to copy from busybox container: %s", err)
|
|
| 625 |
+ } |
|
| 626 |
+ |
|
| 627 |
+ if out, err = exec.Command(dockerBinary, "start", "-a", id).CombinedOutput(); err != nil {
|
|
| 628 |
+ c.Fatalf("unable to start busybox container after copy: %s - %s", err, out)
|
|
| 629 |
+ } |
|
| 630 |
+ |
|
| 631 |
+ msg := strings.TrimSpace(string(out)) |
|
| 632 |
+ if msg != expectedMsg {
|
|
| 633 |
+ c.Fatalf("expected %q but got %q", expectedMsg, msg)
|
|
| 634 |
+ } |
|
| 635 |
+} |