Skip to content

Conversation

@rhatdan
Copy link
Member

@rhatdan rhatdan commented Nov 21, 2025

This fixes a race condition where concurrent 'podman artifact add' commands for different artifacts would result in only one artifact being created, without any error messages.

The root cause was in the artifact store's Add() method, which would:

  1. Acquire lock
  2. Read OCI layout index
  3. Create ImageDestination (which snapshots the index)
  4. RELEASE lock (optimization for blob copying)
  5. Copy blobs (while unlocked)
  6. Reacquire lock
  7. Commit changes (write new index)

When two concurrent additions happened:

  • Process A: Lock → Read index → Create dest A → Unlock → Copy blobs
  • Process B: Lock → Read index (no artifact A!) → Create dest B → Unlock
  • Process A: Lock → Commit (write index with A)
  • Process B: Lock → Commit (write index with B, OVERWRITING A)

The fix keeps the lock held for the entire operation. While this reduces concurrency for blob copying, it prevents the index file corruption that caused artifacts to be lost.

Changes:

  • Remove lock release/reacquire around blob copying in store.Add()
  • Simplify lock management (no more conditional unlock)

Fixes: containers/podman#27569

Generated-with: Cursor AI

@github-actions github-actions bot added the common Related to "common" package label Nov 21, 2025
podmanbot pushed a commit to podmanbot/buildah that referenced this pull request Nov 21, 2025
@podmanbot
Copy link

✅ A new PR has been created in buildah to vendor these changes: containers/buildah#6526

@packit-as-a-service
Copy link

Packit jobs failed. @containers/packit-build please check.

podmanbot pushed a commit to podmanbot/buildah that referenced this pull request Nov 21, 2025
podmanbot pushed a commit to podmanbot/buildah that referenced this pull request Nov 21, 2025
podmanbot pushed a commit to podmanbot/buildah that referenced this pull request Nov 21, 2025
podmanbot pushed a commit to podmanbot/buildah that referenced this pull request Nov 21, 2025
podmanbot pushed a commit to podmanbot/buildah that referenced this pull request Nov 21, 2025
@github-actions github-actions bot added storage Related to "storage" package image Related to "image" package labels Nov 21, 2025
This fixes a race condition where concurrent 'podman artifact add'
commands for different artifacts would result in only one artifact
being created, without any error messages.

The root cause was in the artifact store's Add() method, which
would:
1. Acquire lock
2. Read OCI layout index
3. Create ImageDestination (which snapshots the index)
4. RELEASE lock (optimization for blob copying)
5. Copy blobs (while unlocked)
6. Reacquire lock
7. Commit changes (write new index)

When two concurrent additions happened:
- Process A: Lock → Read index → Create dest A → Unlock → Copy blobs
- Process B: Lock → Read index (no artifact A!) → Create dest B → Unlock
- Process A: Lock → Commit (write index with A)
- Process B: Lock → Commit (write index with B, OVERWRITING A)

The fix keeps the lock held for the entire operation. While this
reduces concurrency for blob copying, it prevents the index file
corruption that caused artifacts to be lost.

Changes:
- Remove lock release/reacquire around blob copying in store.Add()
- Simplify lock management (no more conditional unlock)

Fixes: containers/podman#27569

Generated-with: Cursor AI
Signed-off-by: Daniel J Walsh <[email protected]>
podmanbot pushed a commit to podmanbot/buildah that referenced this pull request Nov 21, 2025
Copy link
Contributor

@mtrmac mtrmac left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

The diagnosis + fix is correct. Are we fine with paying the price? Earlier containers/podman#26524 , Cc: @mheon @baude @Luap99 .

Alternatively, it should be possible for oci/layout/newImageDestination to defer reading the index.json until the start of the “write manifests” phase; that would avoid the need to hold the lock for the duration of blob copies — with a fairly major downside that this would (again) make pkg/libartifact have a very remote dependency on internal implementation choices of oci/layout`.


as.lock.Lock()
locked = true
// Lock is still held from the beginning of the function
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment does not make much sense stand-alone for future readers of the code, without seeing it in this diff.

@Luap99
Copy link
Member

Luap99 commented Nov 22, 2025

yes, ref containers/podman#27574

It would be much better to fix this right so that we reload index.json after the relock. It means redoing the conflict check again.

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

Labels

common Related to "common" package image Related to "image" package storage Related to "storage" package

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Running two podman artifact adds at the same time, fails to create both artifacts with no errors.

4 participants