summaryrefslogtreecommitdiff
path: root/container/container_windows.go
diff options
context:
space:
mode:
authorBrian Goff <cpuguy83@gmail.com>2016-10-03 13:53:06 -0400
committerBrian Goff <cpuguy83@gmail.com>2016-11-10 14:04:08 -0500
commit9a2d0bc3adc0c21c82cd1974be45ea0449f9f224 (patch)
tree6caf5b94092f9f20518099692a169601a1f7a068 /container/container_windows.go
parentc13bf5ba51c4f6a1ba5e5c0da0d4f85d2d5b9116 (diff)
downloaddocker-9a2d0bc3adc0c21c82cd1974be45ea0449f9f224.tar.gz
Fix uneccessary calls to `volume.Unmount()`
Fixes #22564 When an error occurs on mount, there should not be any call later to unmount. This can throw off refcounting in the underlying driver unexpectedly. Consider these two cases: ``` $ docker run -v foo:/bar busybox true ``` ``` $ docker run -v foo:/bar -w /foo busybox true ``` In the first case, if mounting `foo` fails, the volume driver will not get a call to unmount (this is the incorrect behavior). In the second case, the volume driver will not get a call to unmount (correct behavior). This occurs because in the first case, `/bar` does not exist in the container, and as such there is no call to `volume.Mount()` during the `create` phase. It will error out during the `start` phase. In the second case `/bar` is created before dealing with the volume because of the `-w`. Because of this, when the volume is being setup docker will try to copy the image path contents in the volume, in which case it will attempt to mount the volume and fail. This happens during the `create` phase. This makes it so the container will not be created (or at least fully created) and the user gets the error on `create` instead of `start`. The error handling is different in these two phases. Changed to only send `unmount` if the volume is mounted. While investigating the cause of the reported issue I found some odd behavior in unmount calls so I've cleaned those up a bit here as well. Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Diffstat (limited to 'container/container_windows.go')
-rw-r--r--container/container_windows.go48
1 files changed, 5 insertions, 43 deletions
diff --git a/container/container_windows.go b/container/container_windows.go
index 4dbd02b4a7..b24aa3d845 100644
--- a/container/container_windows.go
+++ b/container/container_windows.go
@@ -9,7 +9,6 @@ import (
containertypes "github.com/docker/docker/api/types/container"
"github.com/docker/docker/utils"
- "github.com/docker/docker/volume"
)
// Container holds fields specific to the Windows implementation. See
@@ -54,41 +53,11 @@ func (container *Container) UnmountSecrets() error {
return nil
}
-// UnmountVolumes explicitly unmounts volumes from the container.
-func (container *Container) UnmountVolumes(forceSyscall bool, volumeEventLog func(name, action string, attributes map[string]string)) error {
- var (
- volumeMounts []volume.MountPoint
- err error
- )
-
- for _, mntPoint := range container.MountPoints {
- // Do not attempt to get the mountpoint destination on the host as it
- // is not accessible on Windows in the case that a container is running.
- // (It's a special reparse point which doesn't have any contextual meaning).
- volumeMounts = append(volumeMounts, volume.MountPoint{Volume: mntPoint.Volume, ID: mntPoint.ID})
- }
-
- // atm, this is a no-op.
- if volumeMounts, err = appendNetworkMounts(container, volumeMounts); err != nil {
- return err
- }
-
- for _, volumeMount := range volumeMounts {
- if volumeMount.Volume != nil {
- if err := volumeMount.Volume.Unmount(volumeMount.ID); err != nil {
- return err
- }
- volumeMount.ID = ""
-
- attributes := map[string]string{
- "driver": volumeMount.Volume.DriverName(),
- "container": container.ID,
- }
- volumeEventLog(volumeMount.Volume.Name(), "unmount", attributes)
- }
- }
-
- return nil
+// DetachAndUnmount unmounts all volumes.
+// On Windows it only delegates to `UnmountVolumes` since there is nothing to
+// force unmount.
+func (container *Container) DetachAndUnmount(volumeEventLog func(name, action string, attributes map[string]string)) error {
+ return container.UnmountVolumes(volumeEventLog)
}
// TmpfsMounts returns the list of tmpfs mounts
@@ -119,13 +88,6 @@ func (container *Container) UpdateContainer(hostConfig *containertypes.HostConfi
return nil
}
-// appendNetworkMounts appends any network mounts to the array of mount points passed in.
-// Windows does not support network mounts (not to be confused with SMB network mounts), so
-// this is a no-op.
-func appendNetworkMounts(container *Container, volumeMounts []volume.MountPoint) ([]volume.MountPoint, error) {
- return volumeMounts, nil
-}
-
// cleanResourcePath cleans a resource path by removing C:\ syntax, and prepares
// to combine with a volume path
func cleanResourcePath(path string) string {