Skip to content

Conversation

@christoph-zededa
Copy link
Contributor

@christoph-zededa christoph-zededa commented Sep 2, 2025

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/[email protected]/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/[email protected]/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/[email protected]/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/[email protected]/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/[email protected]/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/[email protected]/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/[email protected]/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/[email protected]/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/[email protected]/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/[email protected]/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/[email protected]/pkglib/build.go:697 +0x86
  golang.org/x/sync/errgroup.(*Group).Go.func1()
      /home/runner/go/pkg/mod/golang.org/x/[email protected]/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/[email protected]/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/[email protected]/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/[email protected]/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
==================

- What I did

Include checking for file-lock object in mutex.

- How I did it

Just must locking the mutex up.

- How to verify it

Unfortunately I was unable to reproduce it locally, I only saw it in "Go Tests" pipeline of: lf-edge/eve#5201

The test it is running is: go test -v -race -run=TestCreateMobyConfig

- Description for the changelog

Fix race condition that is rarely triggered

- A picture of a cute animal (not mandatory but encouraged)

ChatGPT Image Sep 2, 2025, 07_49_22 PM

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/[email protected]/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/[email protected]/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/[email protected]/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/[email protected]/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/[email protected]/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/[email protected]/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/[email protected]/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/[email protected]/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/[email protected]/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/[email protected]/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/[email protected]/pkglib/build.go:697 +0x86
  golang.org/x/sync/errgroup.(*Group).Go.func1()
      /home/runner/go/pkg/mod/golang.org/x/[email protected]/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/[email protected]/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/[email protected]/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/[email protected]/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 <[email protected]>
@deitch
Copy link
Collaborator

deitch commented Sep 2, 2025

I don't get why this works. The mutex only helps in the same process, yet a lockfile is meant to be across processes, so why would the mutex matter?

I don't object to it, so happy to accept it, but why does it help?

@deitch deitch merged commit 9da6903 into linuxkit:master Sep 3, 2025
25 checks passed
@christoph-zededa
Copy link
Contributor Author

I don't get why this works. The mutex only helps in the same process, yet a lockfile is meant to be across processes, so why would the mutex matter?

Apparently two goroutines in the same process can get to the Lock method at the same time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants