daemon/volumes_unix.go
ba1725a9
 // +build !windows
 
 package daemon
 
 import (
 	"os"
81fa9feb
 	"sort"
9d12d093
 	"strconv"
ba1725a9
 
6bb0d181
 	"github.com/docker/docker/container"
bd9814f0
 	"github.com/docker/docker/volume"
ba1725a9
 )
 
72c04ab8
 // setupMounts iterates through each of the mount points for a container and
 // calls Setup() on each. It also looks to see if is a network mount such as
 // /etc/resolv.conf, and if it is not, appends it to the array of mounts.
9c4570a9
 func (daemon *Daemon) setupMounts(c *container.Container) ([]container.Mount, error) {
 	var mounts []container.Mount
034d555d
 	// TODO: tmpfs mounts should be part of Mountpoints
 	tmpfsMounts := make(map[string]bool)
 	for _, m := range c.TmpfsMounts() {
 		tmpfsMounts[m.Destination] = true
 	}
9c4570a9
 	for _, m := range c.MountPoints {
034d555d
 		if tmpfsMounts[m.Destination] {
 			continue
 		}
9c4570a9
 		if err := daemon.lazyInitializeVolume(c.ID, m); err != nil {
aab35963
 			return nil, err
2aa673ae
 		}
322cc99c
 		path, err := m.Setup(c.MountLabel)
81fa9feb
 		if err != nil {
 			return nil, err
 		}
9c4570a9
 		if !c.TrySetNetworkMount(m.Destination, path) {
 			mnt := container.Mount{
6bd389b9
 				Source:      path,
 				Destination: m.Destination,
 				Writable:    m.RW,
a2dc4f79
 				Propagation: m.Propagation,
 			}
9d12d093
 			if m.Volume != nil {
 				attributes := map[string]string{
 					"driver":      m.Volume.DriverName(),
9c4570a9
 					"container":   c.ID,
9d12d093
 					"destination": m.Destination,
 					"read/write":  strconv.FormatBool(m.RW),
 					"propagation": m.Propagation,
 				}
 				daemon.LogVolumeEvent(m.Volume.Name(), "mount", attributes)
 			}
a2dc4f79
 			mounts = append(mounts, mnt)
6bd389b9
 		}
b9e4b957
 	}
81fa9feb
 
 	mounts = sortMounts(mounts)
9c4570a9
 	netMounts := c.NetworkMounts()
442b4562
 	// if we are going to mount any of the network files from container
 	// metadata, the ownership must be set properly for potential container
 	// remapped root (user namespaces)
63efc120
 	rootUID, rootGID := daemon.GetRemappedUIDGID()
442b4562
 	for _, mount := range netMounts {
 		if err := os.Chown(mount.Source, rootUID, rootGID); err != nil {
 			return nil, err
 		}
 	}
 	return append(mounts, netMounts...), nil
b9e4b957
 }
 
72c04ab8
 // sortMounts sorts an array of mounts in lexicographic order. This ensure that
 // when mounting, the mounts don't shadow other mounts. For example, if mounting
 // /etc and /etc/resolv.conf, /etc/resolv.conf must not be mounted first.
9c4570a9
 func sortMounts(m []container.Mount) []container.Mount {
81fa9feb
 	sort.Sort(mounts(m))
 	return m
 }
b9e4b957
 
a7e686a7
 // setBindModeIfNull is platform specific processing to ensure the
 // shared mode is set to 'z' if it is null. This is called in the case
 // of processing a named volume and not a typical bind.
 func setBindModeIfNull(bind *volume.MountPoint) *volume.MountPoint {
 	if bind.Mode == "" {
 		bind.Mode = "z"
47c56e43
 	}
a7e686a7
 	return bind
47c56e43
 }