Don't chown/chmod volumes if not needed.

Doing a chown/chmod automatically can cause `EPERM` in some cases (e.g.
with an NFS mount). Currently Docker will always call chown+chmod on a
volume path unless `:nocopy` is passed in, but we don't need to make
these calls if the perms and ownership already match and potentially
avoid an uneccessary `EPERM`.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
Upstream-commit: f05a023760493dbd41fbfc1bb76ad334b579e94e
Component: engine
This commit is contained in:
Brian Goff
2017-06-18 16:44:52 -07:00
parent f816b75526
commit 0db82d1f6c
+17 -2
View File
@@ -441,11 +441,26 @@ func copyOwnership(source, destination string) error {
return err
}
if err := os.Chown(destination, int(stat.UID()), int(stat.GID())); err != nil {
destStat, err := system.Stat(destination)
if err != nil {
return err
}
return os.Chmod(destination, os.FileMode(stat.Mode()))
// In some cases, even though UID/GID match and it would effectively be a no-op,
// this can return a permission denied error... for example if this is an NFS
// mount.
// Since it's not really an error that we can't chown to the same UID/GID, don't
// even bother trying in such cases.
if stat.UID() != destStat.UID() || stat.GID() != destStat.GID() {
if err := os.Chown(destination, int(stat.UID()), int(stat.GID())); err != nil {
return err
}
}
if stat.Mode() != destStat.Mode() {
return os.Chmod(destination, os.FileMode(stat.Mode()))
}
return nil
}
// TmpfsMounts returns the list of tmpfs mounts