Skip to content

walking differ: use DiffDirChanges for overlay fast path#12842

Open
gogasca wants to merge 2 commits intocontainerd:mainfrom
gogasca:overlay-fast-diff
Open

walking differ: use DiffDirChanges for overlay fast path#12842
gogasca wants to merge 2 commits intocontainerd:mainfrom
gogasca:overlay-fast-diff

Conversation

@gogasca
Copy link
Copy Markdown

@gogasca gogasca commented Jan 31, 2026

Summary

Enables fast overlay diff using continuity's DiffDirChanges function for active snapshots with overlay mounts. This avoids walking the entire rootfs and instead leverages
overlayfs's native diff directory.

Changes

  • Detect overlay mounts and extract upperdir
  • Use fs.DiffDirChanges() for fast single-walk diff
  • Fall back to double-walk for non-overlay mounts
  • Add unit tests for overlay detection

Fixes containerd/continuity#236
Related #9663

@gogasca
Copy link
Copy Markdown
Author

gogasca commented Feb 2, 2026

There is a CI failure, the node-e2e.yml workflow needs fetch-depth: 0 added to the containerd checkout step to fetch tags

@pankajkumar229
Copy link
Copy Markdown

Thank you, which release will have the fixes?

@gogasca
Copy link
Copy Markdown
Author

gogasca commented Feb 11, 2026

@pankajkumar229 thanks for responding, I'm waiting for a repo owner to take a look at this PR and provide this info (I see versions: 2.x or 1.7x ) . Do you know who may be able to help so I can tag them here? Thanks!

@gogasca
Copy link
Copy Markdown
Author

gogasca commented Feb 24, 2026

Hi, @AkihiroSuda Could you please review when you have time ?

@AkihiroSuda
Copy link
Copy Markdown
Member

fast

Any benchmark results?

Comment thread plugins/diff/walking/differ.go Outdated
@gogasca
Copy link
Copy Markdown
Author

gogasca commented Feb 27, 2026

fast

Any benchmark results?

Added three benchmarks to plugins/diff/overlay/differ_linux_test.go:

│                     Benchmark                     │ Time/op │ Allocs/op │  B/op  │                                                                                                 
├───────────────────────────────────────────────────┼─────────┼───────────┼────────┤                                                                                                 
│ BenchmarkGetUpperDir                              │ 19 ns   │ 0         │ 0      │
├───────────────────────────────────────────────────┼─────────┼───────────┼────────┤
│ BenchmarkSingleWalkUpperDir (overlay fast-path)   │ 76 µs   │ 82        │ 7,337  │
├───────────────────────────────────────────────────┼─────────┼───────────┼────────┤
│ BenchmarkDoubleWalkDiff (walking differ baseline) │ 708 µs  │ 916       │ 85,247 │
└───────────────────────────────────────────────────┴─────────┴───────────┴────────┘

With 200 files in the lower layer and 10 changed files in the upper layer, the overlay single-walk approach is ~9x faster with ~11x fewer allocations — and the gap grows with larger
base images.

@gogasca gogasca force-pushed the overlay-fast-diff branch 2 times, most recently from 42a5e9a to 0fe5bc4 Compare March 4, 2026 17:25
@gogasca gogasca requested a review from AkihiroSuda March 4, 2026 23:03
Comment thread integration/client/testdata/default-1.6.toml
Comment thread plugins/diff/overlay/differ.go
Comment thread plugins/diff/overlay/differ_linux.go
Comment thread plugins/diff/overlay/differ_linux.go
Comment thread plugins/diff/overlay/plugin/plugin_linux.go
@gogasca gogasca force-pushed the overlay-fast-diff branch 4 times, most recently from a926f50 to 903dea3 Compare March 11, 2026 05:23
@gogasca gogasca requested a review from AkihiroSuda March 11, 2026 17:18
@gogasca gogasca force-pushed the overlay-fast-diff branch from 903dea3 to 9aec0cd Compare March 11, 2026 22:10
@AkihiroSuda AkihiroSuda requested review from dmcgowan and ktock March 12, 2026 06:32
@AkihiroSuda
Copy link
Copy Markdown
Member

Please squash the commits

@gogasca gogasca force-pushed the overlay-fast-diff branch from 9aec0cd to 92bc582 Compare March 12, 2026 17:30
@gogasca
Copy link
Copy Markdown
Author

gogasca commented Mar 12, 2026

Please squash the commits

done. Thanks for looking into it.

Copy link
Copy Markdown
Member

@dmcgowan dmcgowan left a comment

Choose a reason for hiding this comment

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

The single walk differ code is pretty old and won't correctly handle overlay's metacopy or redirect options. I worry this may have some lurking issues we need to fully address, either in containerd to skip in those cases or in continuity to properly handle those xattrs. I'm curious if this is likely to hit in build cases or if redirect/metacopy is not really used by builders.

Looks like the same is true of the erofs differ, but that snapshotter is newer and hasn't been as thoroughly used.

cw := archive.NewChangeWriter(io.Discard, upperDir)
// Walk only the upperdir; lowerDir is referenced but not traversed here.
// In production this uses fs.DiffDirChanges + DiffSourceOverlayFS which
// reads overlay xattrs. Here we use filepath.Walk for pure I/O comparison.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why does this need to be benchmarked then? Its just benchmarking walking a directory.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

You're right. The benchmarks use filepath. Walk as a proxy rather than the actual DiffDirChanges + DiffSourceOverlayFS path (which requires real overlay mounts and is not runnable in unit test environments). They don't accurately reflect the production code path and are essentially pure IO benchmarks. I'll remove them.

Comment thread plugins/diff/overlay/differ_linux_test.go Outdated
Comment thread contrib/fuzz/diff_fuzz_test.go
gogasca added 2 commits March 15, 2026 06:41
Move the overlay fast-diff logic from the walking differ into a dedicated
differ package. Register the overlay differ with higher priority so it is
used by default when overlay is available.

- Introduce diff/overlay package with OverlayDiffer
- Walking differ delegates to DiffDirChanges for overlay fast path
- Integration tests updated to reflect new differ registration order
- Fix migration tests for 1.6/1.7 configs without overlay differ

Signed-off-by: Gonzalo Gasca Meza <[email protected]>
Fuzz inputs with randomly generated mount structures could cause
Compare and Apply to hang indefinitely when accessing non-existent
paths. Add a 25s context timeout to guard against this.

Signed-off-by: Gonzalo Gasca Meza <[email protected]>
@gogasca
Copy link
Copy Markdown
Author

gogasca commented Apr 6, 2026

dmcgowan@ can you please take another look? Thanks!

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

Labels

Projects

Status: Needs Triage

Development

Successfully merging this pull request may close these issues.

nerdctl commit taking long time possibly because of fs.Changes walking through all files

5 participants