rbd: fix DiffIterateByID Length calculation and add callback tests#6200
Conversation
a491036 to
41d995b
Compare
|
Note Responses generated with Claude Local Test ResultsAll tests pass when run in the project's test container: Note: Building the test container requires |
…fset tests The Offset and Length fields in DiffIterateConfig and DiffIterateByIDConfig lacked documentation explaining that Length is the number of bytes to scan from Offset (range [Offset, Offset+Length)), not an absolute end position. This ambiguity contributed to a bug in ceph-csi (PR #6200) where Length was set to the full volume size instead of (volumeSize - offset), causing zero blocks to be returned when using a non-zero offset (e.g. LUKS header skip). Add doc comments clarifying the semantics and add tests exercising non-zero Offset values for both DiffIterate and DiffIterateByID, verifying that only extents within the [Offset, Offset+Length) range are reported. See: ceph/ceph-csi#6200 See: kaovilai/cephcsi-cbt-e2e#2 Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering>
There was a problem hiding this comment.
Pull request overview
Fixes snapshot diff iteration to scan the correct byte range when a non-zero starting offset is used, and adds unit tests around the diff-iterate callback behavior used for metadata streaming.
Changes:
- Fix
DiffIterateByIDConfig.Lengthto beVolSize - startingOffset(bytes remaining from the starting offset), avoiding scanning beyond the volume end. - Add unit tests for
createDiffIterateByIDCBcovering batching, LUKS padding adjustment, cancellation, and error propagation.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
internal/rbd/snap_diff.go |
Corrects diff-iterate scan length to reflect remaining bytes from the requested offset. |
internal/rbd/snap_diff_test.go |
Adds callback-focused unit tests for batching/offset adjustment/cancellation/error paths. |
| diffIterateByIDConfig := librbd.DiffIterateByIDConfig{ | ||
| Offset: uint64(startingOffset), | ||
| Length: uint64(rbdSnap.VolSize), | ||
| Length: uint64(rbdSnap.VolSize) - uint64(startingOffset), | ||
| Callback: cb, |
There was a problem hiding this comment.
The new Length calculation fixes the scan range, but the behavior isn’t covered by tests: Test_createDiffIterateByIDCB only validates the callback, and Test_handleDiffIterateError only validates error mapping. Consider adding a small unit test that asserts the computed (Offset, Length) range for a non-zero startingOffset (and with/without LUKS padding). If mocking image.DiffIterateByID is hard, extracting the range computation into a helper would make this directly testable.
|
Looks reasonable to me. Please correct the commit message formatting a little, just use |
|
golangci-lint fails on |
|
noted |
f307ff5 to
6bb479a
Compare
|
lint fixed |
|
Created #6208 to assist |
4b8a3a7 to
5f86f08
Compare
…fset tests The Offset and Length fields in DiffIterateConfig and DiffIterateByIDConfig lacked documentation explaining that Length is the number of bytes to scan from Offset (range [Offset, Offset+Length)), not an absolute end position. This ambiguity contributed to a bug in ceph-csi (PR #6200) where Length was set to the full volume size instead of (volumeSize - offset), causing zero blocks to be returned when using a non-zero offset (e.g. LUKS header skip). Add doc comments clarifying the semantics and add tests exercising non-zero Offset values for both DiffIterate and DiffIterateByID, verifying that only extents within the [Offset, Offset+Length) range are reported. See: ceph/ceph-csi#6200 See: kaovilai/cephcsi-cbt-e2e#2 Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: Happy <yesreply@happy.engineering> Signed-off-by: Tiger Kaovilai <passawit.kaovilai@gmail.com>
nixpanic
left a comment
There was a problem hiding this comment.
@Rakshith-R , backport this to the current release?
The feature is still in alpha in current release, I think we skip back-porting this fix. @kaovilai Can you please check why your commit shows as un-verified on github ? |
|
Because I didn't use the same commit email as the one I have gpg sign setup probably |
|
I can make it verified by fixing committee email to match gpg key. Never found any repos requiring gpg signing before but I guess unverified badge can be spooky. It only happens if it does gpg signing but not using matching committer email. |
I do not think it is required to address for this PR. It probably is something you want to fix for future contributions. |
Merge Queue Status
This pull request spent 37 minutes 15 seconds in the queue, including 36 minutes 54 seconds running CI. Required conditions to merge
|
Fix Length calculation in DiffIterateByID to exclude startingOffset, and add unit tests for createDiffIterateByIDCB and handleDiffIterateError. Assisted-by: Claude (Anthropic) <noreply@anthropic.com> Signed-off-by: Tiger Kaovilai <passawit.kaovilai@gmail.com>
5f86f08 to
6717dbd
Compare
|
@Mergifyio rebase |
☑️ Nothing to do, the required conditions are not metDetails
|
|
@nixpanic fixed now. it's honestly just a server side UI thing. |
|
See that prior committed commits now show verified. |
…fset tests The Offset and Length fields in DiffIterateConfig and DiffIterateByIDConfig lacked documentation explaining that Length is the number of bytes to scan from Offset (range [Offset, Offset+Length)), not an absolute end position. This ambiguity contributed to a bug in ceph-csi (PR #6200) where Length was set to the full volume size instead of (volumeSize - offset), causing zero blocks to be returned when using a non-zero offset (e.g. LUKS header skip). Add doc comments clarifying the semantics and add tests exercising non-zero Offset values for both DiffIterate and DiffIterateByID, verifying that only extents within the [Offset, Offset+Length) range are reported. See: ceph/ceph-csi#6200 See: kaovilai/cephcsi-cbt-e2e#2 Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Signed-off-by: Tiger Kaovilai <passawit.kaovilai@gmail.com>
…fset tests The Offset and Length fields in DiffIterateConfig and DiffIterateByIDConfig lacked documentation explaining that Length is the number of bytes to scan from Offset (range [Offset, Offset+Length)), not an absolute end position. This ambiguity contributed to a bug in ceph-csi (PR #6200) where Length was set to the full volume size instead of (volumeSize - offset), causing zero blocks to be returned when using a non-zero offset (e.g. LUKS header skip). Add doc comments clarifying the semantics and add tests exercising non-zero Offset values for both DiffIterate and DiffIterateByID, verifying that only extents within the [Offset, Offset+Length) range are reported. See: ceph/ceph-csi#6200 See: kaovilai/cephcsi-cbt-e2e#2 Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Signed-off-by: Tiger Kaovilai <passawit.kaovilai@gmail.com>
…fset tests The Offset and Length fields in DiffIterateConfig and DiffIterateByIDConfig lacked documentation explaining that Length is the number of bytes to scan from Offset (range [Offset, Offset+Length)), not an absolute end position. This ambiguity contributed to a bug in ceph-csi (PR #6200) where Length was set to the full volume size instead of (volumeSize - offset), causing zero blocks to be returned when using a non-zero offset (e.g. LUKS header skip). Add doc comments clarifying the semantics and add tests exercising non-zero Offset values for both DiffIterate and DiffIterateByID, verifying that only extents within the [Offset, Offset+Length) range are reported. See: ceph/ceph-csi#6200 See: kaovilai/cephcsi-cbt-e2e#2 Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Signed-off-by: Tiger Kaovilai <passawit.kaovilai@gmail.com>
…fset tests The Offset and Length fields in DiffIterateConfig and DiffIterateByIDConfig lacked documentation explaining that Length is the number of bytes to scan from Offset (range [Offset, Offset+Length)), not an absolute end position. This ambiguity contributed to a bug in ceph-csi (PR #6200) where Length was set to the full volume size instead of (volumeSize - offset), causing zero blocks to be returned when using a non-zero offset (e.g. LUKS header skip). Add doc comments clarifying the semantics and add tests exercising non-zero Offset values for both DiffIterate and DiffIterateByID, verifying that only extents within the [Offset, Offset+Length) range are reported. See: ceph/ceph-csi#6200 See: kaovilai/cephcsi-cbt-e2e#2 Generated with [Claude Code](https://claude.ai/code) via [Happy](https://happy.engineering) Signed-off-by: Tiger Kaovilai <passawit.kaovilai@gmail.com>
Summary
DiffIterateByIDConfig.Lengthwas set toVolSize(total volume size), butrbd_diff_iterate3treatslenas bytes to scan fromofs. WhenstartingOffset > 0, this scanned[startingOffset, startingOffset + VolSize)instead of[startingOffset, VolSize). Fixed by usingVolSize - startingOffset.createDiffIterateByIDCBcovering block collection, LUKS padding adjustment, batching, error propagation, context cancellation, and edge cases.Note
This project requires CGo (Ceph C libraries
librbd.h,librados.h) to compile. The tests cannot be validated on a standard dev machine without these libraries — relying on CI to verify.Test plan
go test ./internal/rbd/ -run Test_createDiffIterateByIDCBgo test ./internal/rbd/ -run Test_handleDiffIterateErrorRef: kaovilai/cephcsi-cbt-e2e#2
🤖 Generated with Claude Code
via Happy