Skip to content

layout: close layer reader when blob already exists - #317

Merged
jabrown85 merged 1 commit into
mainfrom
jab/close-reader-on-existing-blob
Oct 21, 2026
Merged

jabrown85 merged 1 commit into
mainfrom
jab/close-reader-on-existing-blob

Conversation

@jabrown85

Copy link
Copy Markdown
Contributor

Summary

layout.Path.writeBlob returned early without closing the reader when the blob already existed on disk. For remote layers, go-containerregistry holds a pull limiter slot (default 4) until the reader is closed, so the slot leaked. Once enough blobs already exist, the remaining writeLayer goroutines block forever in pullLimiter.acquire and the process dies with fatal error: all goroutines are asleep - deadlock!.

This surfaces in the lifecycle restorer (pullSparse) on a second build with an extension, when the cached base image layout already contains the blobs.

The fix closes the reader on the early-return path. Includes a unit test that fails without the change.

Fixes buildpacks/lifecycle#1733

@jabrown85
jabrown85 requested a review from a team as a code owner October 21, 2026 21:16
writeBlob returned early without closing the reader. For remote layers
this leaks the go-containerregistry pull limiter slot, so once enough
blobs are already on disk later layers block forever in
pullLimiter.acquire and the process dies with a deadlock.

Refs buildpacks/lifecycle#1733

Signed-off-by: Jesse Brown <jabrown85@gmail.com>
@jabrown85
jabrown85 force-pushed the jab/close-reader-on-existing-blob branch from ee6582b to a6caa50 Compare October 21, 2026 21:32
@jabrown85
jabrown85 merged commit 195bdfd into main Oct 21, 2026
5 of 7 checks passed
Weirong-Zhu pushed a commit to Weirong-Zhu/lifecycle that referenced this pull request Oct 29, 2026
Fixes a restorer deadlock on rebuilds when the cached sparse base image
layout already contains the blobs (buildpacks/imgutil#317).

Signed-off-by: Jesse Brown <jabrown85@gmail.com>
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.

Restoring phase fails when the extension participates and build runs two times

2 participants