Skip to content

libimage: report the size a removal actually frees - #1105

Open
ROKUMATE wants to merge 1 commit into
podman-container-tools:mainfrom
ROKUMATE:prune-report-freed-size
Open

ROKUMATE wants to merge 1 commit into
podman-container-tools:mainfrom
ROKUMATE:prune-report-freed-size

Conversation

@ROKUMATE

Copy link
Copy Markdown
Contributor

Fixes: podman-container-tools/podman#27592.

report.Size carried the image's full size: i.Size() is store.ImageSize(), which counts every layer including shared ones. podman sums those reports, so a layer shared by N pruned images was counted N times — users saw "reclaimed 346GB" on a 128GB disk.

This reports the physical size the removal actually frees. A layer counts only if every image referencing it is being removed, and each freed layer is credited to exactly one report. sum(report.Size) then equals the real disk delta, so podman's PruneReportsSize() needs no change.

Computing this needs the layer topology from before the removal, since the surviving images decide what is actually freed, so RemoveImages snapshots it and fills in the sizes once allimages have been processed instead of per image.

Also fixed by the same change: the old size was computed before the untag logic ran, so an image that was only untagged still contributed its full size to "reclaimed".

@github-actions github-actions Bot added the common Related to "common" package label Aug 20, 2026
@packit-as-a-service

Copy link
Copy Markdown

Packit jobs failed. @podman-container-tools/packit-jobs please check.

@ROKUMATE

Copy link
Copy Markdown
Contributor Author

@Honny1 this pr is the fix for the issue from podman ... i tagged it in the pr description...
followed the way that you suggested libimage now reports the physical size 👍🏼
do tell if any fixes or changes are required in this pr 👍🏼

@Honny1 Honny1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I did a brew check of the approach.

cc @mtrmac

Comment thread common/libimage/image.go Outdated

@mtrmac mtrmac left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

(I didn’t read this at all carefully.)

I think this approach is fairly elegant, but the cost (e.g. if zstd:chunked layers exist) is excessive.

Maybe it would work to, at the time of image removal, walk the top layers of that image until one finds a layer with >1 reference, and count sizes at that time. I have no idea what the complexity of such an approach would be.


Either way, we don’t (and currently can’t) hold storage locks between the individual removal calls, so the returned size might be inaccurate with concurrent image additions / removals. I don’t think that’s easily fixable.

Comment thread common/libimage/disk_usage.go Outdated
Comment thread common/libimage/disk_usage.go Outdated
@ROKUMATE
ROKUMATE force-pushed the prune-report-freed-size branch from ded8717 to 88d568d Compare August 22, 2026 20:30
@ROKUMATE

Copy link
Copy Markdown
Contributor Author

updated the changes 👍🏼

Comment thread common/libimage/image.go Outdated
// proportional to the data that is actually released, and it accounts a layer
// shared by several removed images to the removal that releases it.
func (i *Image) freedSize() (int64, error) {
layers, err := i.runtime.store.DeleteImage(i.ID(), false)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The overall approach looks good, but the calculation can be inaccurate since images can be removed concurrently. I think DeleteImage could also report the freed size. Measuring the size of the staging TempDir before cleanup would give the exact bytes released. However, that would report the combined size of all removed layers rather than per-layer sizes.

Since DeleteImage is a public API, I'm not sure how much of its signature can change. Adding a DeleteImageWithSize variant might be an option.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Agreed ... Staging happens under the lock, so once paths are renamed the measurement is exact. Combined-per-call is fine too. libimage calls DeleteImage once per image, which is the granularity FreedSize needs.

One catch that i wanted to say ... there are two staging dirs internalDelete stages only metadata (datadir, tspath)... the contents go through driver.DeferredRemove, which creates its own TempDir (vfs/driver.go:301, overlay/overlay.go:1448). Measuring only the first reports a few KB. The size needs accumulating in tempdir and summing across both cleanup functions

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Both cleanup functions.

@ROKUMATE

Copy link
Copy Markdown
Contributor Author

@Honny1 two things i wanted to clarify before i start to resolve the comments

  • staged bytes are on-disk size ... UncompressedSize/DiffSize are uncompressed tar size. podman system df uses the latter, so prune's "reclaimed" would stop matching what df reports ... which one do you want or you suggest?
  • should the storage change go in this PR, or land the libimage side first and follow up then?

@ROKUMATE

Copy link
Copy Markdown
Contributor Author

@Honny1 Sorry to tag again sir but can you clarify the 2 doubts i commented ... as after that i can then proceed to solution else i have to assume mine assumption ...

@Honny1

Honny1 commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

@Honny1 two things i wanted to clarify before i start to resolve the comments

  • staged bytes are on-disk size ... UncompressedSize/DiffSize are uncompressed tar size. podman system df uses the latter, so prune's "reclaimed" would stop matching what df reports ... which one do you want or you suggest?

I would use the same metric.

  • should the storage change go in this PR, or land the libimage side first and follow up then?

I think yes.

Signed-off-by: ROKUMATE <rohitkumawat0110@gmail.com>
@ROKUMATE
ROKUMATE force-pushed the prune-report-freed-size branch from 88d568d to f55970b Compare August 26, 2026 16:07
@github-actions github-actions Bot added the storage Related to "storage" package label Aug 26, 2026
@ROKUMATE

Copy link
Copy Markdown
Contributor Author

@Honny1 hey, i have updated the pr can you please review and check if its good to go ? thank you

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

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Total reclaimed space reports nonsensical value

3 participants