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

Commit

Permalink
Merge pull request #84 from thaJeztah/18.09_backport_ovr2_index
Browse files Browse the repository at this point in the history
[18.09 backport] overlay2: use index=off if possible (fix EBUSY on mount)
  • Loading branch information
seemethere authored Nov 21, 2018
2 parents 4980e48 + 690e097 commit 27b0fee
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 21 deletions.
9 changes: 4 additions & 5 deletions daemon/graphdriver/overlay2/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (

"github.com/docker/docker/pkg/system"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
)

Expand All @@ -27,7 +26,7 @@ func doesSupportNativeDiff(d string) error {
}
defer func() {
if err := os.RemoveAll(td); err != nil {
logrus.WithField("storage-driver", "overlay2").Warnf("Failed to remove check directory %v: %v", td, err)
logger.Warnf("Failed to remove check directory %v: %v", td, err)
}
}()

Expand Down Expand Up @@ -62,7 +61,7 @@ func doesSupportNativeDiff(d string) error {
}
defer func() {
if err := unix.Unmount(filepath.Join(td, "merged"), 0); err != nil {
logrus.WithField("storage-driver", "overlay2").Warnf("Failed to unmount check directory %v: %v", filepath.Join(td, "merged"), err)
logger.Warnf("Failed to unmount check directory %v: %v", filepath.Join(td, "merged"), err)
}
}()

Expand Down Expand Up @@ -113,7 +112,7 @@ func supportsMultipleLowerDir(d string) error {
}
defer func() {
if err := os.RemoveAll(td); err != nil {
logrus.WithField("storage-driver", "overlay2").Warnf("Failed to remove check directory %v: %v", td, err)
logger.Warnf("Failed to remove check directory %v: %v", td, err)
}
}()

Expand All @@ -128,7 +127,7 @@ func supportsMultipleLowerDir(d string) error {
return errors.Wrap(err, "failed to mount overlay")
}
if err := unix.Unmount(filepath.Join(td, "merged"), 0); err != nil {
logrus.WithField("storage-driver", "overlay2").Warnf("Failed to unmount check directory %v: %v", filepath.Join(td, "merged"), err)
logger.Warnf("Failed to unmount check directory %v: %v", filepath.Join(td, "merged"), err)
}
return nil
}
39 changes: 25 additions & 14 deletions daemon/graphdriver/overlay2/overlay.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,14 @@ type Driver struct {
}

var (
logger = logrus.WithField("storage-driver", "overlay2")
backingFs = "<unknown>"
projectQuotaSupported = false

useNaiveDiffLock sync.Once
useNaiveDiffOnly bool

indexOff string
)

func init() {
Expand Down Expand Up @@ -155,8 +158,6 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
backingFs = fsName
}

logger := logrus.WithField("storage-driver", "overlay2")

switch fsMagic {
case graphdriver.FsMagicAufs, graphdriver.FsMagicEcryptfs, graphdriver.FsMagicNfsFs, graphdriver.FsMagicOverlay, graphdriver.FsMagicZfs:
logger.Errorf("'overlay2' is not supported over %s", backingFs)
Expand Down Expand Up @@ -228,7 +229,18 @@ func Init(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (grap
return nil, fmt.Errorf("Storage Option overlay2.size only supported for backingFS XFS. Found %v", backingFs)
}

logger.Debugf("backingFs=%s, projectQuotaSupported=%v", backingFs, projectQuotaSupported)
// figure out whether "index=off" option is recognized by the kernel
_, err = os.Stat("/sys/module/overlay/parameters/index")
switch {
case err == nil:
indexOff = "index=off,"
case os.IsNotExist(err):
// old kernel, no index -- do nothing
default:
logger.Warnf("Unable to detect whether overlay kernel module supports index parameter: %s", err)
}

logger.Debugf("backingFs=%s, projectQuotaSupported=%v, indexOff=%q", backingFs, projectQuotaSupported, indexOff)

return d, nil
}
Expand Down Expand Up @@ -277,14 +289,14 @@ func supportsOverlay() error {
return nil
}
}
logrus.WithField("storage-driver", "overlay2").Error("'overlay' not found as a supported filesystem on this host. Please ensure kernel is new enough and has overlay support loaded.")
logger.Error("'overlay' not found as a supported filesystem on this host. Please ensure kernel is new enough and has overlay support loaded.")
return graphdriver.ErrNotSupported
}

func useNaiveDiff(home string) bool {
useNaiveDiffLock.Do(func() {
if err := doesSupportNativeDiff(home); err != nil {
logrus.WithField("storage-driver", "overlay2").Warnf("Not using native diff for overlay2, this may cause degraded performance for building images: %v", err)
logger.Warnf("Not using native diff for overlay2, this may cause degraded performance for building images: %v", err)
useNaiveDiffOnly = true
}
})
Expand Down Expand Up @@ -522,9 +534,9 @@ func (d *Driver) Remove(id string) error {
lid, err := ioutil.ReadFile(path.Join(dir, "link"))
if err == nil {
if len(lid) == 0 {
logrus.WithField("storage-driver", "overlay2").Errorf("refusing to remove empty link for layer %v", id)
logger.Errorf("refusing to remove empty link for layer %v", id)
} else if err := os.RemoveAll(path.Join(d.home, linkDir, string(lid))); err != nil {
logrus.WithField("storage-driver", "overlay2").Debugf("Failed to remove link: %v", err)
logger.Debugf("Failed to remove link: %v", err)
}
}

Expand Down Expand Up @@ -561,11 +573,11 @@ func (d *Driver) Get(id, mountLabel string) (_ containerfs.ContainerFS, retErr e
if retErr != nil {
if c := d.ctr.Decrement(mergedDir); c <= 0 {
if mntErr := unix.Unmount(mergedDir, 0); mntErr != nil {
logrus.WithField("storage-driver", "overlay2").Errorf("error unmounting %v: %v", mergedDir, mntErr)
logger.Errorf("error unmounting %v: %v", mergedDir, mntErr)
}
// Cleanup the created merged directory; see the comment in Put's rmdir
if rmErr := unix.Rmdir(mergedDir); rmErr != nil && !os.IsNotExist(rmErr) {
logrus.WithField("storage-driver", "overlay2").Debugf("Failed to remove %s: %v: %v", id, rmErr, err)
logger.Debugf("Failed to remove %s: %v: %v", id, rmErr, err)
}
}
}
Expand All @@ -577,7 +589,7 @@ func (d *Driver) Get(id, mountLabel string) (_ containerfs.ContainerFS, retErr e
for i, s := range splitLowers {
absLowers[i] = path.Join(d.home, s)
}
opts := fmt.Sprintf("lowerdir=%s,upperdir=%s,workdir=%s", strings.Join(absLowers, ":"), path.Join(dir, "diff"), path.Join(dir, "work"))
opts := indexOff + "lowerdir=" + strings.Join(absLowers, ":") + ",upperdir=" + path.Join(dir, "diff") + ",workdir=" + path.Join(dir, "work")
mountData := label.FormatMountLabel(opts, mountLabel)
mount := unix.Mount
mountTarget := mergedDir
Expand Down Expand Up @@ -606,7 +618,7 @@ 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 = fmt.Sprintf("lowerdir=%s,upperdir=%s,workdir=%s", string(lowers), path.Join(id, "diff"), path.Join(id, "work"))
opts = indexOff + "lowerdir=" + string(lowers) + ",upperdir=" + path.Join(id, "diff") + ",workdir=" + path.Join(id, "work")
mountData = label.FormatMountLabel(opts, mountLabel)
if len(mountData) > pageSize {
return nil, fmt.Errorf("cannot mount layer, mount label too large %d", len(mountData))
Expand Down Expand Up @@ -648,7 +660,6 @@ func (d *Driver) Put(id string) error {
}

mountpoint := path.Join(dir, "merged")
logger := logrus.WithField("storage-driver", "overlay2")
if count := d.ctr.Decrement(mountpoint); count > 0 {
return nil
}
Expand Down Expand Up @@ -704,7 +715,7 @@ func (d *Driver) ApplyDiff(id string, parent string, diff io.Reader) (size int64

applyDir := d.getDiffPath(id)

logrus.WithField("storage-driver", "overlay2").Debugf("Applying tar in %s", applyDir)
logger.Debugf("Applying tar in %s", applyDir)
// Overlay doesn't need the parent id to apply the diff
if err := untar(diff, applyDir, &archive.TarOptions{
UIDMaps: d.uidMaps,
Expand Down Expand Up @@ -742,7 +753,7 @@ func (d *Driver) Diff(id, parent string) (io.ReadCloser, error) {
}

diffPath := d.getDiffPath(id)
logrus.WithField("storage-driver", "overlay2").Debugf("Tar with options on %s", diffPath)
logger.Debugf("Tar with options on %s", diffPath)
return archive.TarWithOptions(diffPath, &archive.TarOptions{
Compression: archive.Uncompressed,
UIDMaps: d.uidMaps,
Expand Down
3 changes: 1 addition & 2 deletions daemon/graphdriver/overlay2/randomid.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"syscall"
"time"

"github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
)

Expand Down Expand Up @@ -47,7 +46,7 @@ func generateID(l int) string {
if retryOnError(err) && retries < maxretries {
count += n
retries++
logrus.Errorf("error generating version 4 uuid, retrying: %v", err)
logger.Errorf("error generating version 4 uuid, retrying: %v", err)
continue
}

Expand Down

0 comments on commit 27b0fee

Please sign in to comment.