Fix race between lock() and AssertLocked()#657
Merged
mtrmac merged 1 commit intocontainers:mainfrom Feb 13, 2026
Merged
Conversation
mtrmac
reviewed
Feb 11, 2026
Contributor
mtrmac
left a comment
There was a problem hiding this comment.
Thanks! This LGTM but I’d really like more reviewers.
I don’t think adding an always-executed unit test for this is very valuable, certainly not enough to spend minutes of CPU time on every PR.
FWIW the test case you wrote triggered a race report within less than a second for me, on macOS.
A perhaps more direct test case:
func TestAssertLockedRaceForRLock(t *testing.T) {
lock, err := getTempLockfile()
require.NoError(t, err, "creating lock")
lock.RLock()
defer lock.Unlock()
const numGoroutines = 100
const numIterations = 100000
start := make(chan struct{})
var wg sync.WaitGroup
for range numGoroutines / 2 {
wg.Go(func() {
<-start
for range numIterations {
lock.RLock()
lock.Unlock()
}
})
}
for range numGoroutines / 2 {
wg.Go(func() {
<-start
for range numIterations {
lock.AssertLocked()
}
})
}
close(start)
wg.Wait()
}where the ~important part is that we keep the lock read-locked for the whole duration of the concurrent part, so we can have some goroutines constantly hammer the writer and some constantly hammer the reader.
Member
|
A failing test that I restarted, otherwise |
Only write l.locked and l.lockType when counter == 0 to prevent race with unsynchronized reads in AssertLocked(). Fixes: containers/podman#27924 Signed-off-by: Jan Rodák <hony.com@seznam.cz>
0020660 to
e3624fc
Compare
Member
Author
|
Fixed nit. |
Member
|
Happy Green Test Buttons! |
Contributor
|
Thanks again! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Only write
l.lockedandl.lockTypewhencounter == 0to prevent race with unsynchronized reads inAssertLocked().I'm not sure how this should be tested. I wrote a test that tries to hit the unsynchronized R+W, but hitting the exact timing is pretty hard. With enough iterations and goroutines, the chance is better.
Test:
Run command:
go test -race -v -run TestAssertLockedRaceForRLockFixes: containers/podman#27924