fix(satellite): decouple rs-discard-granularity from discard-zeroes gating#112
Conversation
…ating
A partially-written FILE_THIN volume resynced ~2x the bytes upstream
LINSTOR did because the rendered .res lacked rs-discard-granularity.
autoDiskOptions() early-returned nil for any provider that was not
discard-zeroes-safe, coupling rs-discard-granularity (which upstream
gates ONLY on the backing device's reported discard granularity) to
discard-zeroes-if-aligned (correctly provider-gated).
Decouple the two gates to mirror upstream:
- discard-zeroes-if-aligned: provider-gated as before, but now
rendered explicitly as `no` for non-safe kinds (FILE_THIN, thick
LVM, FILE) instead of omitting the whole block — matching upstream
1.33.2's render.
- rs-discard-granularity: emitted whenever the backing device reports
a non-zero discard granularity (lsblk DISC-GRAN > 0), independent of
provider kind, so an aligned all-zero region is UNMAPped during
resync instead of transferred.
Multi-volume collapse stays conservative: discard-zeroes-if-aligned is
`yes` only when every volume is safe (one `no` pins the resource), and
rs-discard-granularity is the smallest across volumes.
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
L6 cli-matrix cell file-thin-rs-discard-granularity.sh: 512M FILE_THIN single replica, write 320M, add 2nd diskful replica, assert the new replica's resync `received` byte counter is close to the written bytes (not the full device) and the rendered .res carries the discard disk block. L7 replay file-thin-rs-discard-granularity.yaml: operator-CLI sequence asserting the rendered DRBD config carries rs-discard-granularity=4096 and discard-zeroes-if-aligned=no for a FILE_THIN resource, plus a clean 3rd-replica sync (drbd_option + sync_clean awaits). Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
After the rs-discard-granularity decoupling fix, BS renders the same thin-aware-resync disk options as upstream for a discard-capable FILE_THIN volume. Two render-shape divergences remain and are accepted: upstream additionally emits `block-size 512;` (BS omits it), and upstream renders the disk block at volume scope vs BS's resource scope — functionally identical for single-volume resources. Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
|
Too many files changed? Review this PR in Change Stack to see how the pieces fit before you dive in. Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (5)
📝 WalkthroughWalkthroughThis PR updates DRBD discard option generation to correctly handle FILE_THIN loop-backed storage by ensuring ChangesFILE_THIN discard-zeroes-if-aligned and rs-discard-granularity
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Code Review
This pull request decouples the rs-discard-granularity and discard-zeroes-if-aligned DRBD disk options, allowing them to be gated independently. Previously, if a volume provider (such as FILE_THIN or thick LVM) was not discard-zero-safe, the entire disk options block was omitted. With this change, such volumes will explicitly set discard-zeroes-if-aligned to no while still retaining rs-discard-granularity if supported by the backing device. This optimization ensures that resync operations only transfer written bytes rather than copying the entire device. Extensive unit, E2E, and integration tests have been added to verify this behavior. There are no review comments to address, and I have no additional feedback to provide.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
|
Regression found — do not merge. Both CI lane failures share one root: on this branch's image a FRESH multi-replica create performs a FULL initial resync instead of the day0-GI skip (lane-4 |
…s (FILE_THIN loop wedge)
Rendering rs-discard-granularity into a loop-backed FILE_THIN volume's
disk{} block regressed fresh-create convergence. When the elected day0
winner force-primaries to run mkfs (the FileSystem/Type path), mkfs
issues a full-device discard; on the loop backing that discard storm,
with rs-discard-granularity active, dirties the bitmap relative to the
day0-seeded peers and forces a FULL initial SyncTarget that wedges
(PausedSyncT dependency between the two targets). Proven on stand + CI:
an identical 3-replica create + mkfs converges instantly on LVM_THIN
(real block device, same disk block) but full-resyncs and wedges on
FILE_THIN (loop) — the e2e respawn-standalone-wedge failure.
Gate rs-discard-granularity on the discard-zero-safe block-device
provider set (LVM_THIN / ZFS / ZFS_THIN), the same set as
discard-zeroes-if-aligned. FILE_THIN now renders only the inert
discard-zeroes-if-aligned no (matching pre-feature behaviour) and omits
the granularity. The thin-aware-resync win is retained where it is both
safe and effective: real block-device thin/ZFS pools.
L1 pins (discardgran_test.go): FILE_THIN + thick LVM omit the
granularity; LVM_THIN/ZFS keep it; end-to-end render pins
TestBuildResFile_FileThinDay0SkipRender (no rs-discard-granularity) and
TestBuildResFile_LvmThinDay0SkipRender (keeps it). L6/L7 repurposed to
guard the FILE_THIN fresh-create + mkfs day0-skip convergence and assert
rs-discard-granularity is absent. Known-delta #76 updated.
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
…IN gate Comment-only: the rs-discard-granularity gate is no longer INDEPENDENT of provider kind — it follows the discard-zero-safe block-device set and excludes loop-backed FILE_THIN. Align the godoc with the implementation. Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
What & why
The thin-aware-resync feature renders DRBD's
discard-zeroes-if-aligned+rs-discard-granularityinto the resourcedisk { }block so a partially-written thin volume resyncs only the written bytes instead of copying the unallocated zero ranges.An earlier revision of this PR decoupled the two options and emitted
rs-discard-granularityfor FILE_THIN as well (the loop backing reports a non-zerolsblk DISC-GRANof 4096, and upstream LINSTOR 1.33.2 renders it on the same backing). That decoupling introduced a fresh-create convergence regression on loop-backed FILE_THIN.The regression (CI-proven)
On a fresh multi-replica create whose RD carries
FileSystem/Type(the elected day0 winner force-primaries to runmkfs),mkfsissues a full-device discard. On the loop backing — which has a documented DRBD kernel write-path interaction — that discard storm, withrs-discard-granularityactive, dirties the bitmap relative to the day0-seeded peers and forces a FULL initial SyncTarget that then wedges (PausedSyncT,resync-suspended:peer,dependencybetween the two targets), so the replicas never reach UpToDate.Evidence:
respawn-standalone-wedge(FILE_THIN +FileSystem/Type=ext4) FAILED on the decoupled image: worker-1SyncSource, peersInconsistent done:37%on a brand-new 512M resource, timing out at "wait all 3 replicas UpToDate". The same scenario PASSES on the baseline (no FILE_THIN disk block).replica-add-no-resync(FILE_THIN, no mkfs) PASSED on the decoupled image — so the trigger is the mkfs-discard × loop ×rs-discard-granularityinteraction, not the option in isolation.FileSystem/Type=ext4converges instantly on LVM_THIN (real block device, same full disk block incl.rs-discard-granularity 65536) but full-resyncs on FILE_THIN (loop). The disk block is inert/safe on a real block device; the wedge is loop-specific.Fix
Gate
rs-discard-granularityon the discard-zero-safe block-device provider set (LVM_THIN / ZFS / ZFS_THIN) — the same set asdiscard-zeroes-if-aligned. FILE_THIN now renders only the inertdiscard-zeroes-if-aligned no;(matching pre-feature behaviour) and omits the granularity. The thin-aware-resync win is retained where it is both safe and effective: real block-device thin/ZFS pools.Accepted delta (known-delta #76)
For FILE_THIN, BS deliberately omits
rs-discard-granularityeven though upstream 1.33.2 emits it on the same loop backing — the loop-safety divergence above. BS additionally omits upstream'sblock-size 512;and renders the disk block at resource (not volume) scope; both functionally identical for single-volume resources.Test protocol
pkg/satellite/discardgran_test.go): FILE_THIN and thick LVM omitrs-discard-granularity; LVM_THIN/ZFS keep it; end-to-end render pinsTestBuildResFile_FileThinDay0SkipRender(nors-discard-granularitythrough the productionautoDiskOptionsForResourcepath) andTestBuildResFile_LvmThinDay0SkipRender(keeps it).go test ./...+golangci-lint run ./pkg/satellite/green.tests/e2e/cli-matrix/file-thin-rs-discard-granularity.sh): 512M FILE_THIN withFileSystem/Type=ext4(drives the mkfs/force-primary path); asserts the rendered.rescarriesdiscard-zeroes-if-aligned nobut NOrs-discard-granularity, and that a 2nd diskful replica day0-skips (sync-targetreceived≪ device size).tests/operator-harness/replay/file-thin-rs-discard-granularity.yaml): operator-CLI sequence assertingdiscard-zeroes-if-aligned=no,rs-discard-granularityabsent (drbdsetup show), and a clean 2nd-replicasync_clean.Validation note
The shared dev stand runs an older deployed image and is used by parallel campaign agents, so the fix is validated via (a) L1 render pins, (b) the LVM_THIN-vs-FILE_THIN mkfs isolation on the stand (loop-specificity confirmed), and (c) the CI re-run on the fixed branch image — the authoritative gate for the e2e
respawn-standalone-wedge/disk-replace-internal-metadataconvergence scenarios.Summary by CodeRabbit
New Features
Bug Fixes
Tests