|
@@ -102,18 +102,6 @@ func (container *Container) BuildHostnameFile() error {
|
|
|
return ioutil.WriteFile(container.HostnamePath, []byte(container.Config.Hostname+"\n"), 0644)
|
|
|
}
|
|
|
|
|
|
-// appendNetworkMounts appends any network mounts to the array of mount points passed in
|
|
|
-func appendNetworkMounts(container *Container, volumeMounts []volume.MountPoint) ([]volume.MountPoint, error) {
|
|
|
- for _, mnt := range container.NetworkMounts() {
|
|
|
- dest, err := container.GetResourcePath(mnt.Destination)
|
|
|
- if err != nil {
|
|
|
- return nil, err
|
|
|
- }
|
|
|
- volumeMounts = append(volumeMounts, volume.MountPoint{Destination: dest})
|
|
|
- }
|
|
|
- return volumeMounts, nil
|
|
|
-}
|
|
|
-
|
|
|
// NetworkMounts returns the list of network mounts.
|
|
|
func (container *Container) NetworkMounts() []Mount {
|
|
|
var mounts []Mount
|
|
@@ -353,49 +341,37 @@ func (container *Container) UpdateContainer(hostConfig *containertypes.HostConfi
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-// UnmountVolumes unmounts all volumes
|
|
|
-func (container *Container) UnmountVolumes(forceSyscall bool, volumeEventLog func(name, action string, attributes map[string]string)) error {
|
|
|
- var (
|
|
|
- volumeMounts []volume.MountPoint
|
|
|
- err error
|
|
|
- )
|
|
|
+// DetachAndUnmount uses a detached mount on all mount destinations, then
|
|
|
+// unmounts each volume normally.
|
|
|
+// This is used from daemon/archive for `docker cp`
|
|
|
+func (container *Container) DetachAndUnmount(volumeEventLog func(name, action string, attributes map[string]string)) error {
|
|
|
+ networkMounts := container.NetworkMounts()
|
|
|
+ mountPaths := make([]string, 0, len(container.MountPoints)+len(networkMounts))
|
|
|
|
|
|
for _, mntPoint := range container.MountPoints {
|
|
|
dest, err := container.GetResourcePath(mntPoint.Destination)
|
|
|
if err != nil {
|
|
|
- return err
|
|
|
+ logrus.Warnf("Failed to get volume destination path for container '%s' at '%s' while lazily unmounting: %v", container.ID, mntPoint.Destination, err)
|
|
|
+ continue
|
|
|
}
|
|
|
-
|
|
|
- volumeMounts = append(volumeMounts, volume.MountPoint{Destination: dest, Volume: mntPoint.Volume, ID: mntPoint.ID})
|
|
|
- }
|
|
|
-
|
|
|
- // Append any network mounts to the list (this is a no-op on Windows)
|
|
|
- if volumeMounts, err = appendNetworkMounts(container, volumeMounts); err != nil {
|
|
|
- return err
|
|
|
+ mountPaths = append(mountPaths, dest)
|
|
|
}
|
|
|
|
|
|
- for _, volumeMount := range volumeMounts {
|
|
|
- if forceSyscall {
|
|
|
- if err := detachMounted(volumeMount.Destination); err != nil {
|
|
|
- logrus.Warnf("%s unmountVolumes: Failed to do lazy umount %v", container.ID, err)
|
|
|
- }
|
|
|
+ for _, m := range networkMounts {
|
|
|
+ dest, err := container.GetResourcePath(m.Destination)
|
|
|
+ if err != nil {
|
|
|
+ logrus.Warnf("Failed to get volume destination path for container '%s' at '%s' while lazily unmounting: %v", container.ID, m.Destination, err)
|
|
|
+ continue
|
|
|
}
|
|
|
+ mountPaths = append(mountPaths, dest)
|
|
|
+ }
|
|
|
|
|
|
- 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)
|
|
|
+ for _, mountPath := range mountPaths {
|
|
|
+ if err := detachMounted(mountPath); err != nil {
|
|
|
+ logrus.Warnf("%s unmountVolumes: Failed to do lazy umount fo volume '%s': %v", container.ID, mountPath, err)
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- return nil
|
|
|
+ return container.UnmountVolumes(volumeEventLog)
|
|
|
}
|
|
|
|
|
|
// copyExistingContents copies from the source to the destination and
|