Skip to content
This repository has been archived by the owner on Oct 13, 2023. It is now read-only.

[19.03 backport] Fix overlay2 busy error on mount #332

Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 29 additions & 6 deletions daemon/graphdriver/overlay2/overlay.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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))
Expand All @@ -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
Expand Down