diff --git a/daemon/graphdriver/overlay2/overlay.go b/daemon/graphdriver/overlay2/overlay.go index c986b45606..eedf5b73ae 100644 --- a/daemon/graphdriver/overlay2/overlay.go +++ b/daemon/graphdriver/overlay2/overlay.go @@ -446,6 +446,10 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts) (retErr return err } + if err := ioutil.WriteFile(path.Join(d.dir(parent), "committed"), []byte{}, 0600); err != nil { + return err + } + lower, err := d.getLower(parent) if err != nil { return err @@ -592,7 +596,20 @@ func (d *Driver) Get(id, mountLabel string) (_ containerfs.ContainerFS, retErr e for i, s := range splitLowers { absLowers[i] = path.Join(d.home, s) } - opts := indexOff + "lowerdir=" + strings.Join(absLowers, ":") + ",upperdir=" + diffDir + ",workdir=" + workDir + var readonly bool + if _, err := os.Stat(path.Join(dir, "committed")); err == nil { + readonly = true + } else if !os.IsNotExist(err) { + return nil, err + } + + var opts string + if readonly { + opts = indexOff + "lowerdir=" + diffDir + ":" + strings.Join(absLowers, ":") + } else { + opts = indexOff + "lowerdir=" + strings.Join(absLowers, ":") + ",upperdir=" + diffDir + ",workdir=" + workDir + } + mountData := label.FormatMountLabel(opts, mountLabel) mount := unix.Mount mountTarget := mergedDir @@ -612,7 +629,11 @@ func (d *Driver) Get(id, mountLabel string) (_ containerfs.ContainerFS, retErr e // fit within a page and relative links make the mount data much // smaller at the expense of requiring a fork exec to chroot. if len(mountData) > pageSize { - opts = indexOff + "lowerdir=" + string(lowers) + ",upperdir=" + path.Join(id, diffDirName) + ",workdir=" + path.Join(id, workDirName) + if readonly { + opts = indexOff + "lowerdir=" + path.Join(id, diffDirName) + ":" + string(lowers) + } else { + opts = indexOff + "lowerdir=" + string(lowers) + ",upperdir=" + path.Join(id, diffDirName) + ",workdir=" + path.Join(id, workDirName) + } mountData = label.FormatMountLabel(opts, mountLabel) if len(mountData) > pageSize { return nil, fmt.Errorf("cannot mount layer, mount label too large %d", len(mountData)) @@ -628,10 +649,12 @@ func (d *Driver) Get(id, mountLabel string) (_ containerfs.ContainerFS, retErr e return nil, fmt.Errorf("error creating overlay mount to %s: %v", mergedDir, err) } - // chown "workdir/work" to the remapped root UID/GID. Overlay fs inside a - // user namespace requires this to move a directory from lower to upper. - if err := os.Chown(path.Join(workDir, workDirName), rootUID, rootGID); err != nil { - return nil, err + if !readonly { + // chown "workdir/work" to the remapped root UID/GID. Overlay fs inside a + // user namespace requires this to move a directory from lower to upper. + if err := os.Chown(path.Join(workDir, workDirName), rootUID, rootGID); err != nil { + return nil, err + } } return containerfs.NewLocalContainerFS(mergedDir), nil