Skip to content

fix(linstor): mark volumes restored from a snapshot DRBD-initialized - #4866

Open
Aleksei Sviridkin (lexfrei) wants to merge 1 commit into
mainfrom
fix/linstor-restore-initial-sync
Open

Aleksei Sviridkin (lexfrei) wants to merge 1 commit into
mainfrom
fix/linstor-restore-initial-sync

Conversation

@lexfrei

@lexfrei Aleksei Sviridkin (lexfrei) commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

What this PR does

Restoring a PVC from a LINSTOR VolumeSnapshot can leave one replica with an empty volume that DRBD marks UpToDate. A pod that lands on that replica sees an empty filesystem.

linstor-csi restores the snapshot on one node and autoplaces the other replicas. LINSTOR v1.33.3 copies Linstor/Drbd/InitialUptoDateOn from the source volume into the restored volume definition and leaves the definition without DRBD_INITIALIZED. When autoplace puts a replica on the node that name points to, that empty new volume wins the initial UpToDate race, gets a random current UUID and a fresh filesystem, and goes StandAlone against the restored replica.

LINBIT fixed this in v1.34.0. This PR backports that commit, LINBIT/linstor-server@9d8cdf5, to our v1.33.3 build as a patch. The README entry says to drop the patch with the move to v1.34.0 or later.

Tested on a three-node cluster with a thick ZFS pool and placementCount: 3. Before the change the reproduction failed every time. With the patch I ran 5 restores, 4 of them with the source volume's winner on a different node than the restore. I also restored a snapshot taken before the change, and a 10Gi volume. Every time all replicas came up connected and UpToDate, a pod on each node read the same checksum, and the backing zvols were byte-identical when read with O_DIRECT. The resync after a restore moves about the written data, around 40 s for 1Gi and 134 s for 7.5 GiB on 10Gi. CSI clone PVC-to-PVC was checked too and is not affected.

There is no e2e test. Every e2e lane runs without DRBD (COZY_LINSTOR_DRBD_ENABLED=false, StorageClass local), so a suite for replicated restores would never run in CI.

Volumes restored before this fix are not repaired by it. How to find and fix them is in this comment.

Known limitation, shared by upstream v1.34 since that code did not change: the autoplaced replicas skip the initial sync and rely on the source volume's day0 UUID still being in the restored replica's history. If that ever fails, DRBD goes StandAlone with "unrelated data" instead of syncing, which is visible, not silent. I could not reproduce it.

Closes #4862

Screenshots

Not a UI change.

Downstream repositories

Release note

fix(linstor): a PVC restored from a VolumeSnapshot no longer gets a replica with an empty volume marked UpToDate. Volumes restored before this release may still have such a replica; https://github.com/cozystack/cozystack/issues/4862#issuecomment-6106661441 explains how to check and repair them.

Summary by CodeRabbit

  • Bug Fixes
    • Restored snapshots with diskful DRBD resources are now recognized as initialized by default, helping them resume without unnecessary metadata recreation.
    • When force-initial-sync is enabled, restored volumes continue through the existing metadata-recreation path.

linstor-csi restores a snapshot on one node and autoplaces the other
replicas. In LINSTOR v1.33.3 the restored volume definition has no
DRBD_INITIALIZED flag, so the initial UpToDate race is still open, and
Linstor/Drbd/InitialUptoDateOn, copied from the source volume through
the snapshot, names the node that won it for the source. When a
replica is autoplaced on that node, the empty new volume wins the
race: it gets a random current UUID and a fresh filesystem, and goes
StandAlone against the restored replica. A pod attached there sees an
empty volume.

Backport the upstream fix, released in LINSTOR v1.34.0, which sets the
flag on a restore unless the resource definition asks for new metadata
through ForceInitialSyncPermanent, as a backup does. Nothing wins the
race any more, and an autoplaced replica resyncs from the restored one
like any replica added to an existing volume.

Link: LINBIT/linstor-server@9d8cdf5
Closes: #4862

Assisted-by: LLM
Signed-off-by: Aleksei Sviridkin <[email protected]>
@github-actions github-actions Bot added area/storage Issues or PRs related to storage (linstor, seaweedfs, bucket, velero, harbor) kind/bug Categorizes issue or PR as related to a bug size/M This PR changes 30-99 lines, ignoring generated files labels Oct 11, 2026
@coderabbitai

coderabbitai Bot commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: cozystack/cozystack/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: f6941392-5477-46e0-9a81-83c5882b0657

📥 Commits

Reviewing files that changed from the base of the PR and between df2e1c3 and e5689e2.


📒 Files selected for processing (2)
  • packages/system/linstor/images/piraeus-server/patches/README.md
  • packages/system/linstor/images/piraeus-server/patches/snapshot-restore-drbd-initialized.diff

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 6 remain after this review.



📝 Walkthrough

Walkthrough

The snapshot-restore patch now checks DRBD initialization for resource definitions with diskful resources. It sets the initial-UpToDate node property and sets DRBD_INITIALIZED according to ForceInitialSyncPermanent. The patch README documents the behavior, caveat, upstream source, and removal version.

Changes

Snapshot restore initialization

Layer / File(s) Summary
Set DRBD initialization state for restored volumes
packages/system/linstor/images/piraeus-server/patches/snapshot-restore-drbd-initialized.diff, packages/system/linstor/images/piraeus-server/patches/README.md
The patch checks resource definitions with diskful resources, sets the initial-UpToDate node property to the first diskful resource’s node, and sets DRBD_INITIALIZED based on ForceInitialSyncPermanent. The README documents the exception, the ZFS/thin-pool caveat, and patch provenance.

Priority: ⬆️ High

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: High


Merge Risk: ⚪ Minimal · up to e5689

This backports an upstream fix so restored snapshot volumes no longer risk an empty replica winning the initial sync. No actionable merge-blocking risk was found, and volumes restored before the fix still need the separate remediation steps.

Pre-merge checks | Passed 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the main change: marking volumes restored from snapshots as DRBD-initialized.
Linked Issues check Passed Issue #4862 requires snapshot-restored, three-replica PVCs to retain the snapshot data on all replicas and return the same data to a pod. The patch changes `CtrlSnapshotRestoreApiCallHandler.checkDrbd…
Out of Scope Changes check Passed The PR changes only the LINSTOR v1.33.3 patch set. The Java patch backports the linked LINBIT fix, and the README documents its source, removal version, known limitation, and issue scope. These change…
Docstring Coverage Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

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

Labels

area/storage Issues or PRs related to storage (linstor, seaweedfs, bucket, velero, harbor) kind/bug Categorizes issue or PR as related to a bug size/M This PR changes 30-99 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

linstor: restoring a PVC from a VolumeSnapshot leaves two of three replicas empty (silent data loss)

1 participant