From 9da6903609ed7cbb7642e929a2d9e5ddae61b430 Mon Sep 17 00:00:00 2001 From: Christoph Ostarek Date: Tue, 2 Sep 2025 19:38:40 +0200 Subject: [PATCH] cache/provider: use lock correctly even checking if the file-lock object is non-nil needs to be guarded with the lock `go test -race` output: ``` ================== WARNING: DATA RACE Read at 0x00c0005283f0 by goroutine 17: github.com/linuxkit/linuxkit/src/cmd/linuxkit/cache.(*Provider).Lock() /home/runner/go/pkg/mod/github.com/linuxkit/linuxkit/src/cmd/linuxkit@v0.0.0-20250829112740-179f74ac245b/cache/provider.go:57 +0x55 github.com/linuxkit/linuxkit/src/cmd/linuxkit/cache.(*Provider).Index() /home/runner/go/pkg/mod/github.com/linuxkit/linuxkit/src/cmd/linuxkit@v0.0.0-20250829112740-179f74ac245b/cache/provider.go:47 +0x47 github.com/linuxkit/linuxkit/src/cmd/linuxkit/cache.(*Provider).FindDescriptor() /home/runner/go/pkg/mod/github.com/linuxkit/linuxkit/src/cmd/linuxkit@v0.0.0-20250829112740-179f74ac245b/cache/find.go:86 +0x46 github.com/linuxkit/linuxkit/src/cmd/linuxkit/pkglib.(*dockerRunnerImpl).build() /home/runner/go/pkg/mod/github.com/linuxkit/linuxkit/src/cmd/linuxkit@v0.0.0-20250829112740-179f74ac245b/pkglib/dockerimpl.go:683 +0x2a90 github.com/linuxkit/linuxkit/src/cmd/linuxkit/pkglib.(*dockerRunnerImpl).builder() /home/runner/go/pkg/mod/github.com/linuxkit/linuxkit/src/cmd/linuxkit@v0.0.0-20250829112740-179f74ac245b/pkglib/dockerimpl.go:245 +0x748 github.com/linuxkit/linuxkit/src/cmd/linuxkit/pkglib.(*dockerRunnerImpl).build() /home/runner/go/pkg/mod/github.com/linuxkit/linuxkit/src/cmd/linuxkit@v0.0.0-20250829112740-179f74ac245b/pkglib/dockerimpl.go:507 +0xec github.com/linuxkit/linuxkit/src/cmd/linuxkit/pkglib.Pkg.buildArch() /home/runner/go/pkg/mod/github.com/linuxkit/linuxkit/src/cmd/linuxkit@v0.0.0-20250829112740-179f74ac245b/pkglib/build.go:718 +0x13cf github.com/linuxkit/linuxkit/src/cmd/linuxkit/pkglib.Pkg.Build() /home/runner/go/pkg/mod/github.com/linuxkit/linuxkit/src/cmd/linuxkit@v0.0.0-20250829112740-179f74ac245b/pkglib/build.go:495 +0x4b64 bpftrace-compiler.(*imageBuilder).buildPkgs() /home/runner/work/eve/eve/eve-tools/bpftrace-compiler/pkgbuild.go:150 +0xf2d path/filepath.walkDir() /opt/hostedtoolcache/go/1.24.6/x64/src/path/filepath/path.go:332 +0x39e path/filepath.walkDir() /opt/hostedtoolcache/go/1.24.6/x64/src/path/filepath/path.go:332 +0x39e path/filepath.walkDir() /opt/hostedtoolcache/go/1.24.6/x64/src/path/filepath/path.go:310 +0x84 path/filepath.walkDir() /opt/hostedtoolcache/go/1.24.6/x64/src/path/filepath/path.go:332 +0x39e path/filepath.walkDir() /opt/hostedtoolcache/go/1.24.6/x64/src/path/filepath/path.go:310 +0x84 path/filepath.walkDir() /opt/hostedtoolcache/go/1.24.6/x64/src/path/filepath/path.go:332 +0x39e path/filepath.walkDir() /opt/hostedtoolcache/go/1.24.6/x64/src/path/filepath/path.go:310 +0x84 path/filepath.walkDir() /opt/hostedtoolcache/go/1.24.6/x64/src/path/filepath/path.go:332 +0x39e path/filepath.walkDir() /opt/hostedtoolcache/go/1.24.6/x64/src/path/filepath/path.go:332 +0x39e path/filepath.walkDir() /opt/hostedtoolcache/go/1.24.6/x64/src/path/filepath/path.go:310 +0x84 path/filepath.walkDir() /opt/hostedtoolcache/go/1.24.6/x64/src/path/filepath/path.go:332 +0x39e path/filepath.WalkDir() /opt/hostedtoolcache/go/1.24.6/x64/src/path/filepath/path.go:400 +0x89 bpftrace-compiler.hashDir() /home/runner/work/eve/eve/eve-tools/bpftrace-compiler/util.go:103 +0x2ae bpftrace-compiler.(*imageBuilder).buildPkgs() /home/runner/work/eve/eve/eve-tools/bpftrace-compiler/pkgbuild.go:96 +0x144 bpftrace-compiler.TestCreateMobyConfig() /home/runner/work/eve/eve/eve-tools/bpftrace-compiler/pkgbuild_test.go:14 +0x26f testing.tRunner() /opt/hostedtoolcache/go/1.24.6/x64/src/testing/testing.go:1792 +0x225 testing.(*T).Run.gowrap1() /opt/hostedtoolcache/go/1.24.6/x64/src/testing/testing.go:1851 +0x44 Previous write at 0x00c0005283f0 by goroutine 65: github.com/linuxkit/linuxkit/src/cmd/linuxkit/cache.(*Provider).Lock() /home/runner/go/pkg/mod/github.com/linuxkit/linuxkit/src/cmd/linuxkit@v0.0.0-20250829112740-179f74ac245b/cache/provider.go:67 +0x2da github.com/linuxkit/linuxkit/src/cmd/linuxkit/cache.(*Provider).ImageLoad() /home/runner/go/pkg/mod/github.com/linuxkit/linuxkit/src/cmd/linuxkit@v0.0.0-20250829112740-179f74ac245b/cache/write.go:157 +0x279 github.com/linuxkit/linuxkit/src/cmd/linuxkit/pkglib.Pkg.buildArch.func2() /home/runner/go/pkg/mod/github.com/linuxkit/linuxkit/src/cmd/linuxkit@v0.0.0-20250829112740-179f74ac245b/pkglib/build.go:697 +0x86 golang.org/x/sync/errgroup.(*Group).Go.func1() /home/runner/go/pkg/mod/golang.org/x/sync@v0.16.0/errgroup/errgroup.go:93 +0x91 Goroutine 17 (running) created at: testing.(*T).Run() /opt/hostedtoolcache/go/1.24.6/x64/src/testing/testing.go:1851 +0x8f2 testing.runTests.func1() /opt/hostedtoolcache/go/1.24.6/x64/src/testing/testing.go:2279 +0x85 testing.tRunner() /opt/hostedtoolcache/go/1.24.6/x64/src/testing/testing.go:1792 +0x225 testing.runTests() /opt/hostedtoolcache/go/1.24.6/x64/src/testing/testing.go:2277 +0x96c testing.(*M).Run() /opt/hostedtoolcache/go/1.24.6/x64/src/testing/testing.go:2142 +0xeea main.main() _testmain.go:69 +0x164 Goroutine 65 (running) created at: golang.org/x/sync/errgroup.(*Group).Go() /home/runner/go/pkg/mod/golang.org/x/sync@v0.16.0/errgroup/errgroup.go:78 +0x124 github.com/linuxkit/linuxkit/src/cmd/linuxkit/pkglib.Pkg.buildArch() /home/runner/go/pkg/mod/github.com/linuxkit/linuxkit/src/cmd/linuxkit@v0.0.0-20250829112740-179f74ac245b/pkglib/build.go:696 +0xb05 github.com/linuxkit/linuxkit/src/cmd/linuxkit/pkglib.Pkg.Build() /home/runner/go/pkg/mod/github.com/linuxkit/linuxkit/src/cmd/linuxkit@v0.0.0-20250829112740-179f74ac245b/pkglib/build.go:495 +0x4b64 bpftrace-compiler.(*imageBuilder).buildPkgs() /home/runner/work/eve/eve/eve-tools/bpftrace-compiler/pkgbuild.go:150 +0xf2d path/filepath.walkDir() /opt/hostedtoolcache/go/1.24.6/x64/src/path/filepath/path.go:332 +0x39e path/filepath.walkDir() /opt/hostedtoolcache/go/1.24.6/x64/src/path/filepath/path.go:332 +0x39e path/filepath.walkDir() /opt/hostedtoolcache/go/1.24.6/x64/src/path/filepath/path.go:310 +0x84 path/filepath.walkDir() /opt/hostedtoolcache/go/1.24.6/x64/src/path/filepath/path.go:332 +0x39e path/filepath.walkDir() /opt/hostedtoolcache/go/1.24.6/x64/src/path/filepath/path.go:310 +0x84 path/filepath.walkDir() /opt/hostedtoolcache/go/1.24.6/x64/src/path/filepath/path.go:332 +0x39e path/filepath.walkDir() /opt/hostedtoolcache/go/1.24.6/x64/src/path/filepath/path.go:310 +0x84 path/filepath.walkDir() /opt/hostedtoolcache/go/1.24.6/x64/src/path/filepath/path.go:332 +0x39e path/filepath.walkDir() /opt/hostedtoolcache/go/1.24.6/x64/src/path/filepath/path.go:332 +0x39e path/filepath.walkDir() /opt/hostedtoolcache/go/1.24.6/x64/src/path/filepath/path.go:310 +0x84 path/filepath.walkDir() /opt/hostedtoolcache/go/1.24.6/x64/src/path/filepath/path.go:332 +0x39e path/filepath.WalkDir() /opt/hostedtoolcache/go/1.24.6/x64/src/path/filepath/path.go:400 +0x89 bpftrace-compiler.hashDir() /home/runner/work/eve/eve/eve-tools/bpftrace-compiler/util.go:103 +0x2ae bpftrace-compiler.(*imageBuilder).buildPkgs() /home/runner/work/eve/eve/eve-tools/bpftrace-compiler/pkgbuild.go:96 +0x144 bpftrace-compiler.TestCreateMobyConfig() /home/runner/work/eve/eve/eve-tools/bpftrace-compiler/pkgbuild_test.go:14 +0x26f testing.tRunner() /opt/hostedtoolcache/go/1.24.6/x64/src/testing/testing.go:1792 +0x225 testing.(*T).Run.gowrap1() /opt/hostedtoolcache/go/1.24.6/x64/src/testing/testing.go:1851 +0x44 ================== ``` Signed-off-by: Christoph Ostarek --- src/cmd/linuxkit/cache/provider.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/cmd/linuxkit/cache/provider.go b/src/cmd/linuxkit/cache/provider.go index d9b2ff812..3e9cf7331 100644 --- a/src/cmd/linuxkit/cache/provider.go +++ b/src/cmd/linuxkit/cache/provider.go @@ -53,12 +53,13 @@ func (p *Provider) Index() (v1.ImageIndex, error) { // Lock locks the cache directory to prevent concurrent access func (p *Provider) Lock() error { + p.lockMut.Lock() + defer p.lockMut.Unlock() + // if the lock is already set, we do not need to do anything if p.lock != nil { return nil } - p.lockMut.Lock() - defer p.lockMut.Unlock() var lockFile = filepath.Join(p.dir, lockfile) lock, err := util.Lock(lockFile) if err != nil {