- 
                Notifications
    
You must be signed in to change notification settings  - Fork 509
 
Open
Description
I have done the following
- I have searched the existing issues
 - If possible, I've reproduced the issue using the 'main' branch of this project
 
Steps to reproduce
The current implicit volume creation logic in Utility.getOrCreateVolume() has a race condition in the create or inspect pattern:
do {
    volume = try await ClientVolume.create(...)
} catch let error as VolumeError {
    guard case .volumeAlreadyExists = error else { throw error }
    volume = try await ClientVolume.inspect(parsed.name)
}
Current behavior
- Container A calls getOrCreateVolume(“vol”) which attempts to create a volume
 - Container B calls getOrCreateVolume(“vol”) which also attempts to create a volume
 - Container A’s create succeeds
 - Container B’s create fails with volumeAlreadyExists
 - Container B calls inspect() to get the volume
 - But between steps 3 and 5, if Container A’s container fails and is cleaned up along with its volume, Container B’s inspect() will fail with volumeNotFound
 
Expected behavior
In practice the race window is small. What I added in ContainersService is a precedent that solves similar races using withContainerList() (see ContainersService.swift#L122), where we do atomic check-and-create operations within a single lock context.
Environment
N/ARelevant log output
N/ACode of Conduct
- I agree to follow this project's Code of Conduct
 
Metadata
Metadata
Assignees
Labels
No labels