Skip to content

[Bug]: Possible race in implicit volume creation (Utility.getOrCreateVolume()) #774

@realrajaryan

Description

@realrajaryan

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

  1. Container A calls getOrCreateVolume(“vol”) which attempts to create a volume
  2. Container B calls getOrCreateVolume(“vol”) which also attempts to create a volume
  3. Container A’s create succeeds
  4. Container B’s create fails with volumeAlreadyExists
  5. Container B calls inspect() to get the volume
  6. 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/A

Relevant log output

N/A

Code of Conduct

  • I agree to follow this project's Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions