99
1010 mounttypes "github.com/docker/docker/api/types/mount"
1111 "github.com/docker/docker/pkg/idtools"
12+ "github.com/docker/docker/pkg/symlink"
1213 "github.com/docker/docker/pkg/stringid"
1314 "github.com/opencontainers/runc/libcontainer/label"
1415 "github.com/pkg/errors"
@@ -124,23 +125,28 @@ type MountPoint struct {
124125
125126// Setup sets up a mount point by either mounting the volume if it is
126127// configured, or creating the source directory if supplied.
127- func (m * MountPoint ) Setup (mountLabel string , rootUID , rootGID int ) (path string , err error ) {
128+ func (m * MountPoint ) Setup (prefix , mountLabel string , rootUID , rootGID int ) (path string , err error ) {
129+ symlinkRoot := prefix
130+ if symlinkRoot == "" {
131+ symlinkRoot = "/"
132+ }
133+ sourcePath , err := symlink .FollowSymlinkInScope (filepath .Join (prefix , m .Source ), symlinkRoot )
134+ if err != nil {
135+ path = ""
136+ err = errors .Wrapf (err , "error evaluating symlink from mount source '%s'" , m .Source )
137+ return
138+ }
139+
128140 defer func () {
129141 if err == nil {
130142 if label .RelabelNeeded (m .Mode ) {
131- sourcePath , err := filepath .EvalSymlinks (m .Source )
132- if err != nil {
133- path = ""
134- err = errors .Wrapf (err , "error evaluating symlink from mount source '%s'" , m .Source )
135- return
136- }
137143 err = label .Relabel (sourcePath , mountLabel , label .IsShared (m .Mode ))
138144 if err == syscall .ENOTSUP {
139145 err = nil
140146 }
141147 if err != nil {
142148 path = ""
143- err = errors .Wrapf (err , "error setting label on mount source '%s'" , m . Source )
149+ err = errors .Wrapf (err , "error setting label on mount source '%s'" , sourcePath )
144150 return
145151 }
146152 }
@@ -162,19 +168,19 @@ func (m *MountPoint) Setup(mountLabel string, rootUID, rootGID int) (path string
162168 if len (m .Source ) == 0 {
163169 return "" , fmt .Errorf ("Unable to setup mount point, neither source nor volume defined" )
164170 }
165- // system.MkdirAll() produces an error if m.Source exists and is a file (not a directory),
171+ // system.MkdirAll() produces an error if source exists and is a file (not a directory),
166172 if m .Type == mounttypes .TypeBind {
167- // idtools.MkdirAllNewAs() produces an error if m.Source exists and is a file (not a directory)
173+ // idtools.MkdirAllNewAs() produces an error if source exists and is a file (not a directory)
168174 // also, makes sure that if the directory is created, the correct remapped rootUID/rootGID will own it
169- if err := idtools .MkdirAllNewAs (m . Source , 0755 , rootUID , rootGID ); err != nil {
175+ if err := idtools .MkdirAllNewAs (sourcePath , 0755 , rootUID , rootGID ); err != nil {
170176 if perr , ok := err .(* os.PathError ); ok {
171177 if perr .Err != syscall .ENOTDIR {
172- return "" , errors .Wrapf (err , "error while creating mount source path '%s'" , m . Source )
178+ return "" , errors .Wrapf (err , "error while creating mount source path '%s'" , sourcePath )
173179 }
174180 }
175181 }
176182 }
177- return m . Source , nil
183+ return sourcePath , nil
178184}
179185
180186// Path returns the path of a volume in a mount point.
0 commit comments