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 <christoph@zededa.com>
This commit is contained in:
Christoph Ostarek
2025-09-02 19:38:40 +02:00
committed by Avi Deitcher
parent 179f74ac24
commit 9da6903609

View File

@@ -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 {