Skip to content

Commit

Permalink
Merge pull request #4815 from tonistiigi/overlay-size-fix
Browse files Browse the repository at this point in the history
executor: fix overlay layer limit for non-rootfs mounts
  • Loading branch information
AkihiroSuda authored Apr 1, 2024
2 parents ca7e856 + 2c9d934 commit 5f73c5d
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 19 deletions.
35 changes: 35 additions & 0 deletions client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ var allTests = []func(t *testing.T, sb integration.Sandbox){
testExportLocalNoPlatformSplitOverwrite,
testSolverOptLocalDirsStillWorks,
testOCIIndexMediatype,
testLayerLimitOnMounts,
}

func TestIntegration(t *testing.T) {
Expand Down Expand Up @@ -10242,6 +10243,40 @@ func testLLBMountPerformance(t *testing.T, sb integration.Sandbox) {
require.NoError(t, err)
}

func testLayerLimitOnMounts(t *testing.T, sb integration.Sandbox) {
integration.SkipOnPlatform(t, "windows")

ctx := sb.Context()

c, err := New(ctx, sb.Address())
require.NoError(t, err)
defer c.Close()

base := llb.Image("busybox:latest")

const numLayers = 110

for i := 0; i < numLayers; i++ {
base = base.Run(llb.Shlex("sh -c 'echo hello >> /hello'")).Root()
}

def, err := base.Marshal(sb.Context())
require.NoError(t, err)

_, err = c.Solve(ctx, def, SolveOpt{}, nil)
require.NoError(t, err)

ls := llb.Image("busybox:latest").
Run(llb.Shlexf("ls -l /base/hello"))
ls.AddMount("/base", base, llb.Readonly)

def, err = ls.Marshal(sb.Context())
require.NoError(t, err)

_, err = c.Solve(ctx, def, SolveOpt{}, nil)
require.NoError(t, err)
}

func testClientCustomGRPCOpts(t *testing.T, sb integration.Sandbox) {
var interceptedMethods []string
intercept := func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
Expand Down
72 changes: 53 additions & 19 deletions executor/oci/spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,16 @@ func GenerateSpec(ctx context.Context, meta executor.Meta, mounts []executor.Mou
}
releasers = append(releasers, release)
for _, mount := range mounts {
mount, release, err := compactLongOverlayMount(mount, m.Readonly)
if err != nil {
releaseAll()
return nil, nil, err
}

if release != nil {
releasers = append(releasers, release)
}

mount, err = sm.subMount(mount, m.Selector)
if err != nil {
releaseAll()
Expand Down Expand Up @@ -261,26 +271,8 @@ func (s *submounts) subMount(m mount.Mount, subPath string) (mount.Mount, error)
return mount.Mount{}, err
}

var mntType string
opts := []string{}
if m.ReadOnly() {
opts = append(opts, "ro")
}

if runtime.GOOS != "windows" {
// Windows uses a mechanism similar to bind mounts, but will err out if we request
// a mount type it does not understand. Leaving the mount type empty on Windows will
// yield the same result.
mntType = "bind"
opts = append(opts, "rbind")
}

s.m[h] = mountRef{
mount: mount.Mount{
Source: mp,
Type: mntType,
Options: opts,
},
mount: bind(mp, m.ReadOnly()),
unmount: lm.Unmount,
subRefs: map[string]mountRef{},
}
Expand Down Expand Up @@ -312,3 +304,45 @@ func (s *submounts) cleanup() {
}
wg.Wait()
}

func bind(p string, ro bool) mount.Mount {
m := mount.Mount{
Source: p,
}
if runtime.GOOS != "windows" {
// Windows uses a mechanism similar to bind mounts, but will err out if we request
// a mount type it does not understand. Leaving the mount type empty on Windows will
// yield the same result.
m.Type = "bind"
m.Options = []string{"rbind"}
}
if ro {
m.Options = append(m.Options, "ro")
}
return m
}

func compactLongOverlayMount(m mount.Mount, ro bool) (mount.Mount, func() error, error) {
if m.Type != "overlay" {
return m, nil, nil
}

sz := 0
for _, opt := range m.Options {
sz += len(opt) + 1
}

// can fit to single page, no need to compact
if sz < 4096-512 {
return m, nil, nil
}

lm := snapshot.LocalMounterWithMounts([]mount.Mount{m})

mp, err := lm.Mount()
if err != nil {
return mount.Mount{}, nil, err
}

return bind(mp, ro), lm.Unmount, nil
}

0 comments on commit 5f73c5d

Please sign in to comment.