Skip to content

feat(linstor): bump linstor-csi to v1.10.6 with Protocol-C dual-attach fix - #2496

Merged
Andrei Kvapil (kvaps) merged 1 commit into
cozystack:mainfrom
kvaps:feat/linstor-csi-protocol-c-dual-attach
Apr 27, 2026
Merged

Andrei Kvapil (kvaps) merged 1 commit into
cozystack:mainfrom
kvaps:feat/linstor-csi-protocol-c-dual-attach

Conversation

@kvaps

@kvaps Andrei Kvapil (kvaps) commented Apr 27, 2026 •

Copy link
Copy Markdown
Member

What this PR does

Bumps linstor-csi from v1.10.5 to v1.10.6 and ships an out-of-tree patch that fixes live migration of KubeVirt VMs whose volumes sit on a DRBD Protocol-A/B resource (e.g. a replicated-async StorageClass).

Problem

DRBD requires Protocol C whenever allow-two-primaries=yes is enabled. Operators commonly opt into Protocol A on a per-resource-group basis for async / WAN replication, which silently breaks every subsequent live migration of consumers of those volumes: drbdadm adjust rejects the second-attach with Protocol C required (errno 139), KubeVirt's evacuation loop retries indefinitely, and the VM stays pinned to the source node.

Change

  • LINSTOR_CSI_VERSION 1.10.5 → 1.10.6 (Makefile + Dockerfile default).
  • New patch 002-protocol-c-override-for-dual-attach.diff: when Attach installs allow-two-primaries=yes on the resource-definition during a second attach, it also installs DrbdOptions/Net/protocol=C as an override on the resource-definition. The override applies to every connection (including diskless TieBreaker peers, where a per-pair override would still leave one connection broken). It is tagged with Aux/csi-protocol-override=yes so Detach removes only the override this driver installed, leaving any operator-set Protocol property on the resource-definition untouched.
  • Existing patch 001-relocate-after-clone-restore.diff regenerated against v1.10.6 (context shift only, no logic change — the old patch hunks no longer aligned cleanly).

Verification

  • make image-linstor-csi builds successfully on linux/amd64 with both patches applied.
  • End-to-end test on dev5 cluster (KubeVirt v1.6.3, 3-node Talos): created a Protocol-A resource-group + StorageClass, provisioned a VM on top, and triggered live migration. Migration succeeds in a single Attach with the override installed during dual-attach and removed by Detach. Reproducer (without the patch) is the well-known evacuation loop with (node) Failed to adjust DRBD resource ... Protocol C required.

Upstream

Upstreamed as draft PR piraeusdatastore/linstor-csi#435.

Compatibility

  • No behaviour change for resources already using Protocol C (the common case).
  • No behaviour change for resources never attached with allow-two-primaries.
  • Idempotent: re-running Attach is a no-op once the override is installed.
  • Operator-set Protocol overrides on the resource-definition are preserved (gated by the Aux marker).

Release note

fix(linstor): live migration of KubeVirt VMs on Protocol-A/B (async) DRBD volumes no longer fails with "Protocol C required" — linstor-csi now installs a Protocol=C override on the resource-definition during dual-attach and reverts it on detach.

Summary by CodeRabbit

  • New Features

    • Automatic replica relocation after volume clone and snapshot restore to improve placement and load distribution.
    • Conditional DRBD protocol override to enable/clean up dual-attach (two-primaries) scenarios more reliably.
  • Chores

    • Updated LINSTOR CSI default to v1.10.6.

@coderabbitai

coderabbitai Bot commented Apr 27, 2026 •

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 981e8ce0-7ec0-49e1-91ca-ab70723ce78c

📥 Commits

Reviewing files that changed from the base of the PR and between 3f2902c and 073fb16.

📒 Files selected for processing (4)
  • packages/system/linstor/Makefile
  • packages/system/linstor/images/linstor-csi/Dockerfile
  • packages/system/linstor/images/linstor-csi/patches/001-relocate-after-clone-restore.diff
  • packages/system/linstor/images/linstor-csi/patches/002-protocol-c-override-for-dual-attach.diff
✅ Files skipped from review due to trivial changes (2)
  • packages/system/linstor/Makefile
  • packages/system/linstor/images/linstor-csi/Dockerfile
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/system/linstor/images/linstor-csi/patches/002-protocol-c-override-for-dual-attach.diff

📝 Walkthrough

Walkthrough

Updates LINSTOR CSI from v1.10.5 to v1.10.6; adds best-effort replica relocation after clone/restore (configurable) and conditional DRBD protocol=C overrides to support dual-attach (RWX) with marker-based reversion logic.

Changes

Cohort / File(s) Summary
Version Bump
packages/system/linstor/Makefile, packages/system/linstor/images/linstor-csi/Dockerfile
Bump LINSTOR_CSI_VERSION / VERSION from v1.10.5 → v1.10.6.
Resource Relocation
packages/system/linstor/images/linstor-csi/patches/001-relocate-after-clone-restore.diff
Adds relocateResources helper, new params RelocateAfterClone and RelocateAfterRestore, idempotent CSI aux prop Aux/csi-relocation-triggered, snapshot node selection changes, migration loop with bounded replica moves, and switches status handling to resource-aware views. Review volume-aware status logic and migration error handling.
DRBD Protocol Override (dual-attach)
packages/system/linstor/images/linstor-csi/patches/002-protocol-c-override-for-dual-attach.diff
When enabling allow-two-primaries would fail, sets resource protocol=C and a CSI marker prop, and removes them on detach only if marker present. Adds getEffectiveDrbdProtocol helper and new constants PropertyDrbdNetProtocol, PropertyCsiProtocolOverride. Review marker semantics and operator-set preservation on revert.

Sequence Diagram(s)

sequenceDiagram
    participant Driver as CSI Driver
    participant Client as LINSTOR Client
    participant Auto as Autoplacer
    participant RD as Resource Definition

    Note over Driver: Clone/Restore flow (when relocate enabled)
    Driver->>Driver: Check RelocateAfterClone / RelocateAfterRestore
    Driver->>Client: QuerySizeInfo (current diskful nodes)
    Client-->>Driver: Current placement
    Driver->>Auto: Compute optimal node targets
    Auto-->>Driver: Preferred targets
    Driver->>Client: Create diskless targets on preferred nodes
    Client-->>Driver: Diskless targets created
    Driver->>Client: Trigger Migrate from current -> preferred
    Client-->>Driver: Migration started / per-pair status
    Driver->>RD: Set Aux/csi-relocation-triggered (idempotent)
    RD-->>Driver: Property set
Loading
sequenceDiagram
    participant Driver as CSI Driver
    participant Client as LINSTOR Client
    participant RD as Resource Definition

    Note over Driver: Attach (RWX dual-attach)
    Driver->>Client: GetResourceDefinition / view properties
    Client-->>Driver: RD properties (protocol, rg-level fallback)
    Driver->>Driver: getEffectiveDrbdProtocol(vol)
    alt Protocol is A or B
        Driver->>RD: Set `protocol=C` override and CSI marker
        RD-->>Driver: Override applied
    end
    Driver->>Client: Enable allow-two-primaries
    Client-->>Driver: Allow-two-primaries set

    Note over Driver: Detach (when resInUse → 1)
    Driver->>Client: Remove allow-two-primaries
    Driver->>RD: Check CSI marker
    alt Marker present
        Driver->>RD: Remove `protocol` override and marker
        RD-->>Driver: Reverted
    else Marker absent
        Note over Driver: Preserve operator configuration
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 I hop through code with fluffy cheer,
Relocate clones so they settle near,
Two primaries dance, protocol set to C,
Markers kept tidy, reverting carefully,
A rabbit's patch, neat as a carrot tree. 🥕

🚥 Pre-merge checks | ✅ 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 summarizes the main change: bumping linstor-csi to v1.10.6 and adding a Protocol-C dual-attach fix, which aligns with the primary modifications across the Makefile, Dockerfile, and new patch files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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 and usage tips.

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Claude Code Review

This pull request is from a fork — automated review is disabled. A repository maintainer can comment @claude review to run a one-time review.

@dosubot dosubot Bot added the size/L This PR changes 100-499 lines, ignoring generated files label Apr 27, 2026
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request upgrades the LINSTOR CSI driver to version 1.10.6 and introduces a critical fix for KubeVirt live migrations. By dynamically applying a Protocol=C override during dual-attach operations, the driver now correctly handles DRBD resources that are configured for asynchronous replication, preventing migration failures caused by protocol mismatches.

Highlights

  • Version Upgrade: Updated LINSTOR_CSI_VERSION from v1.10.5 to v1.10.6 in both the Makefile and Dockerfile.
  • Live Migration Fix: Introduced a new patch to automatically apply a Protocol=C override during dual-attach for DRBD resources, enabling successful live migration for KubeVirt VMs using Protocol-A/B volumes.
  • Patch Maintenance: Regenerated the existing relocation patch to ensure compatibility with the v1.10.6 codebase.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Ignored Files
  • Ignored by pattern: **/*.diff (2)
    • packages/system/linstor/images/linstor-csi/patches/001-relocate-after-clone-restore.diff
    • packages/system/linstor/images/linstor-csi/patches/002-protocol-c-override-for-dual-attach.diff
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment Gemini (@gemini-code-assist) Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on Gemini (@gemini-code-assist) comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request updates the LINSTOR CSI version from v1.10.5 to v1.10.6 in the Makefile and Dockerfile. A review comment identifies a critical issue where patch files mentioned in the PR description are missing from the diff, which will cause the build to fail during the application step.

FROM golang:1.25 AS builder

ARG VERSION=v1.10.5
ARG VERSION=v1.10.6

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.

high

The pull request description mentions a new patch 002-protocol-c-override-for-dual-attach.diff and a regenerated 001-relocate-after-clone-restore.diff, but these files are missing from the pull request diff. Please ensure that all new and modified patch files are included in the packages/system/linstor/images/linstor-csi/patches/ directory. Without them, the build will fail during the git apply step or the intended fix will not be applied to the new version.

@github-actions github-actions Bot added area/storage Issues or PRs related to storage (linstor, seaweedfs, bucket, velero, harbor) kind/feature Categorizes issue or PR as related to a new feature labels Apr 27, 2026

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 3

🧹 Nitpick comments (1)
packages/system/linstor/images/linstor-csi/patches/001-relocate-after-clone-restore.diff (1)

81-81: Optional: align Aux-marker style with patch 002 for consistency.

Patch 002 defines PropertyCsiProtocolOverride = lc.NamespcAuxiliary + "/csi-protocol-override" as an exported constant in pkg/linstor/const.go. This patch keeps propertyRelocationTriggered as a file-local string literal "Aux/csi-relocation-triggered" in pkg/client/linstor.go. Functionally identical, but two new Aux markers introduced in the same PR with different styles is a small inconsistency.

Since the PR notes upstreaming is already in flight as a draft and this hunk is "regenerated with no logic change", treat this purely as nice-to-have — best fixed in the upstream draft to avoid Cozystack-side patch churn.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/system/linstor/images/linstor-csi/patches/001-relocate-after-clone-restore.diff`
at line 81, The Aux marker string "Aux/csi-relocation-triggered" is declared as
a file-local literal (propertyRelocationTriggered) while another Aux marker
(PropertyCsiProtocolOverride) is exported from pkg/linstor/const.go; make the
style consistent by moving propertyRelocationTriggered into the shared constants
file as an exported constant (e.g., PropertyCsiRelocationTriggered) alongside
PropertyCsiProtocolOverride, update all references to use the new constant name
instead of the local variable, and keep the original string value unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@packages/system/linstor/images/linstor-csi/patches/002-protocol-c-override-for-dual-attach.diff`:
- Around line 24-36: The current path in the attach flow silently skips
installing the Protocol=C override when getEffectiveDrbdProtocol(ctx, volId)
returns an error, which leaves Protocol A/B resources broken for live-migration;
update the logic in the attach code that calls getEffectiveDrbdProtocol (the
block that sets rdProps and uses s.log) to either (a) escalate the log/metric
when protoErr != nil and still install the override unconditionally (set
rdProps[linstor.PropertyDrbdNetProtocol] = "C" and
rdProps[linstor.PropertyCsiProtocolOverride] = "yes") on error, or (b) if you
prefer conditional behavior, emit a higher-severity metric/alert and return the
error so the caller can retry; ensure you reference getEffectiveDrbdProtocol,
rdProps, linstor.PropertyDrbdNetProtocol and linstor.PropertyCsiProtocolOverride
when making the change so the marker-based Detach will still remove the override
later.
- Around line 53-71: The current Detach path silently skips removing Protocol=C
and the CSI override when s.client.ResourceDefinitions.Get fails; change it so
the cleanup is best-effort: regardless of getErr, include
linstor.PropertyDrbdNetProtocol and linstor.PropertyCsiProtocolOverride in
deleteProps (since DeleteProps is a no-op for missing keys) before calling
s.client.ResourceDefinitions.Modify, or alternatively return getErr instead of
proceeding; update the logic around s.client.ResourceDefinitions.Get,
deleteProps, and the Modify call so the override + marker are always attempted
to be removed (use linestor.PropertyCsiProtocolOverride and
linstor.PropertyDrbdNetProtocol as the identifying symbols).
- Around line 79-104: Update the doc comment for getEffectiveDrbdProtocol to
explicitly state that the function only checks resource-definition and
resource-group properties and does not consult resource-connection (per-peer)
overrides; mention that connection-level DrbdOptions/Net/protocol settings have
higher precedence in LINSTOR and therefore may cause the helper to miss an
existing Protocol=C configured at the connection level (reference
getEffectiveDrbdProtocol and linstor.PropertyDrbdNetProtocol so maintainers can
locate the behavior).

---

Nitpick comments:
In
`@packages/system/linstor/images/linstor-csi/patches/001-relocate-after-clone-restore.diff`:
- Line 81: The Aux marker string "Aux/csi-relocation-triggered" is declared as a
file-local literal (propertyRelocationTriggered) while another Aux marker
(PropertyCsiProtocolOverride) is exported from pkg/linstor/const.go; make the
style consistent by moving propertyRelocationTriggered into the shared constants
file as an exported constant (e.g., PropertyCsiRelocationTriggered) alongside
PropertyCsiProtocolOverride, update all references to use the new constant name
instead of the local variable, and keep the original string value unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 52954d95-461d-49da-8fac-a8433c5f312b

📥 Commits

Reviewing files that changed from the base of the PR and between 62d2516 and 3f2902c.

📒 Files selected for processing (4)
  • packages/system/linstor/Makefile
  • packages/system/linstor/images/linstor-csi/Dockerfile
  • packages/system/linstor/images/linstor-csi/patches/001-relocate-after-clone-restore.diff
  • packages/system/linstor/images/linstor-csi/patches/002-protocol-c-override-for-dual-attach.diff

Comment on lines +24 to +36
+ proto, protoErr := s.getEffectiveDrbdProtocol(ctx, volId)
+ if protoErr != nil {
+ s.log.WithError(protoErr).WithField("volume", volId).
+ Warn("failed to determine effective DRBD protocol; skipping Protocol=C override for dual-attach")
+ } else if proto == "A" || proto == "B" {
+ s.log.WithFields(logrus.Fields{
+ "volume": volId,
+ "protocol": proto,
+ }).Info("installing Protocol=C override on resource-definition for dual-attach")
+
+ rdProps[linstor.PropertyDrbdNetProtocol] = "C"
+ rdProps[linstor.PropertyCsiProtocolOverride] = "yes"
+ }

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.

⚠️ Potential issue | 🟡 Minor

Degraded path on protocol-lookup failure silently leaves Protocol=A/B resources broken for live migration.

If getEffectiveDrbdProtocol returns an error (controller hiccup, transient 5xx, etc.), Attach logs a warning and falls through, installing only allow-two-primaries=yes. For Protocol-A/B resources this is exactly the failure mode this patch is designed to fix — drbdadm adjust will fail with "Protocol C required" (errno 139) and live migration will not proceed, with no further indication that the override was skipped due to a lookup error rather than a deliberate "already C" decision.

Two minor improvements worth considering before this hits production:

  1. Surface the skip in metrics or a higher log level (the current Warn will be lost in Attach noise).
  2. Optionally make the override unconditional when protoErr != nil (i.e., default-safe to install Protocol=C when we can't prove it's already C). Since Detach is gated by the marker, an unnecessary override would be removed cleanly on the next Detach.

Not a blocker — the previous behavior was equally broken — but the warning-and-continue path deserves a follow-up.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/system/linstor/images/linstor-csi/patches/002-protocol-c-override-for-dual-attach.diff`
around lines 24 - 36, The current path in the attach flow silently skips
installing the Protocol=C override when getEffectiveDrbdProtocol(ctx, volId)
returns an error, which leaves Protocol A/B resources broken for live-migration;
update the logic in the attach code that calls getEffectiveDrbdProtocol (the
block that sets rdProps and uses s.log) to either (a) escalate the log/metric
when protoErr != nil and still install the override unconditionally (set
rdProps[linstor.PropertyDrbdNetProtocol] = "C" and
rdProps[linstor.PropertyCsiProtocolOverride] = "yes") on error, or (b) if you
prefer conditional behavior, emit a higher-severity metric/alert and return the
error so the caller can retry; ensure you reference getEffectiveDrbdProtocol,
rdProps, linstor.PropertyDrbdNetProtocol and linstor.PropertyCsiProtocolOverride
when making the change so the marker-based Detach will still remove the override
later.

Comment on lines +53 to +71
+ deleteProps := []string{linstor.PropertyAllowTwoPrimaries}
+
+ // Drop the Protocol=C override only if Attach installed it (gated by
+ // our marker), so an operator-set Protocol property on the
+ // resource-definition is preserved.
+ rd, getErr := s.client.ResourceDefinitions.Get(ctx, volId)
+ if getErr != nil {
+ log.WithError(getErr).Warn("failed to fetch resource-definition props; skipping Protocol=C override removal")
+ } else if rd.Props[linstor.PropertyCsiProtocolOverride] != "" {
+ log.Info("removing Protocol=C override from resource-definition")
+ deleteProps = append(deleteProps,
+ linstor.PropertyDrbdNetProtocol,
+ linstor.PropertyCsiProtocolOverride,
+ )
+ }
+
+ err = s.client.ResourceDefinitions.Modify(ctx, volId, lapi.GenericPropsModify{
+ DeleteProps: deleteProps,
+ })

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.

⚠️ Potential issue | 🟡 Minor

Detach cleanup: Get-then-Modify is fine, but consider tightening the failure path.

When s.client.ResourceDefinitions.Get fails on line 58, Detach logs a warning and proceeds with only allow-two-primaries in deleteProps. If the marker actually was present, the Protocol=C override and the Aux marker leak onto the RD until the next Attach/Detach pair — and the next Attach won't re-add anything because getEffectiveDrbdProtocol will then report proto == "C", so the override-marker pair could persist indefinitely.

Two possible refinements:

  • On getErr != nil, return the error (let the caller retry) rather than silently dropping the cleanup.
  • Or explicitly best-effort delete PropertyDrbdNetProtocol + PropertyCsiProtocolOverride whenever they're present, regardless of Get outcome (LINSTOR DeleteProps for a non-existent key is a no-op).

Idempotency-wise, leaving Protocol=C set is harmless for correctness (it's stricter than A/B), but it does mask any subsequent operator-driven downgrade to A/B at the RD level. Minor.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/system/linstor/images/linstor-csi/patches/002-protocol-c-override-for-dual-attach.diff`
around lines 53 - 71, The current Detach path silently skips removing Protocol=C
and the CSI override when s.client.ResourceDefinitions.Get fails; change it so
the cleanup is best-effort: regardless of getErr, include
linstor.PropertyDrbdNetProtocol and linstor.PropertyCsiProtocolOverride in
deleteProps (since DeleteProps is a no-op for missing keys) before calling
s.client.ResourceDefinitions.Modify, or alternatively return getErr instead of
proceeding; update the logic around s.client.ResourceDefinitions.Get,
deleteProps, and the Modify call so the override + marker are always attempted
to be removed (use linestor.PropertyCsiProtocolOverride and
linstor.PropertyDrbdNetProtocol as the identifying symbols).

Comment on lines +79 to +104
+// getEffectiveDrbdProtocol returns the DRBD network protocol ("A", "B" or "C")
+// that LINSTOR will hand to drbdadm for the given resource. Resource-definition
+// properties take precedence; otherwise the value is inherited from the
+// resource-group. An empty string is returned when neither level sets the
+// property (LINSTOR's compiled-in default is "C").
+func (s *Linstor) getEffectiveDrbdProtocol(ctx context.Context, volId string) (string, error) {
+ rd, err := s.client.ResourceDefinitions.Get(ctx, volId)
+ if err != nil {
+ return "", err
+ }
+
+ if v, ok := rd.Props[linstor.PropertyDrbdNetProtocol]; ok {
+ return v, nil
+ }
+
+ if rd.ResourceGroupName == "" {
+ return "", nil
+ }
+
+ rg, err := s.client.ResourceGroups.Get(ctx, rd.ResourceGroupName)
+ if err != nil {
+ return "", err
+ }
+
+ return rg.Props[linstor.PropertyDrbdNetProtocol], nil
+}

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.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🌐 Web query:

LINSTOR DRBD options precedence: resource-definition vs resource-connection vs resource-group for DrbdOptions/Net/protocol

💡 Result:

In LINSTOR, DRBD options like DrbdOptions/Net/protocol follow the general properties inheritance hierarchy where settings closer to the actual resource take precedence. The precedence order is: resource-connection (highest, specific to node pairs) > resource-definition > resource-group (lowest). Resource-connection options override those from resource-definition, which override resource-group. This aligns with the documented rule: "the value 'closer' to the resource or volume wins. [...] resource definition settings take precedence over resource group settings." Resource-connections, being more specific (per node pair), have highest precedence for net options like protocol, as evidenced by Piraeus documentation setting DrbdOptions/Net/protocol on node connections and LINSTOR API supporting resource_conn_modify for properties.

Citations:


🏁 Script executed:

# First, let's examine the patch file to understand the broader context
fd -t f '002-protocol-c-override-for-dual-attach.diff' packages/system/

Repository: cozystack/cozystack

Length of output: 159


🏁 Script executed:

# Let's also check if there are any LINSTOR-related documentation or code that explains the precedence
rg -l 'DrbdOptions' packages/system/ --type patch

Repository: cozystack/cozystack

Length of output: 93


🏁 Script executed:

# Search for property precedence or protocol resolution logic
rg 'precedence|override' packages/system/ -i --type patch -A 3 -B 3

Repository: cozystack/cozystack

Length of output: 93


🏁 Script executed:

# Read the patch file directly to understand the context
cat packages/system/linstor/images/linstor-csi/patches/002-protocol-c-override-for-dual-attach.diff

Repository: cozystack/cozystack

Length of output: 5785


Add a note to the doc comment clarifying that resource-connection level overrides are not consulted.

The helper only checks resource-definition and resource-group properties, not connection-level overrides. Per the LINSTOR precedence model, resource-connection options (set per peer) actually have higher precedence than resource-definition settings. This means if an operator has already set DrbdOptions/Net/protocol on a specific connection, that value wins over whatever the resource-definition specifies.

The current implementation could lead to installing an unnecessary Protocol=C override on the resource-definition even if some connections are already running Protocol C via connection-level configuration. Document this limitation in the helper's comment so future maintainers understand the detection only surveys RD/RG-level settings.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/system/linstor/images/linstor-csi/patches/002-protocol-c-override-for-dual-attach.diff`
around lines 79 - 104, Update the doc comment for getEffectiveDrbdProtocol to
explicitly state that the function only checks resource-definition and
resource-group properties and does not consult resource-connection (per-peer)
overrides; mention that connection-level DrbdOptions/Net/protocol settings have
higher precedence in LINSTOR and therefore may cause the helper to miss an
existing Protocol=C configured at the connection level (reference
getEffectiveDrbdProtocol and linstor.PropertyDrbdNetProtocol so maintainers can
locate the behavior).

@kvaps Andrei Kvapil (kvaps) added the kind/backport Categorizes issue or PR as requiring a backport to the current release line label Apr 27, 2026
IvanHunters
IvanHunters previously approved these changes Apr 27, 2026
@dosubot dosubot Bot added the lgtm This PR has been approved by a maintainer label Apr 27, 2026
…h fix

Bump linstor-csi to v1.10.6 and add an out-of-tree patch that overrides
DrbdOptions/Net/protocol to C on the resource-definition whenever a
volume is attached to a second node with allow-two-primaries (the
live-migration flow), and reverts it on detach.

Without the patch, any KubeVirt live migration of a VM whose volume
sits on a Protocol-A/B resource (for example a "replicated-async"
StorageClass) ends up in a permanent evacuation loop: drbdadm adjust
on the satellite rejects allow-two-primaries with "Protocol C
required" (errno 139), the migration fails, and KubeVirt retries
until manual intervention.

The override is set at the resource-definition level so it covers
every connection, including diskless TieBreaker peers, and is tagged
with an Aux marker so Detach reverts only the override we installed.
The 001 relocate-after-clone patch was regenerated against v1.10.6
(context shift only, no logic change).

Verified end-to-end on dev5: live migration of a KubeVirt VM whose
PVC sits on a Protocol-A resource-group now succeeds in a single
Attach.

Patch is upstreamed as draft PR piraeusdatastore/linstor-csi#435.

Co-Authored-By: Claude <[email protected]>
Signed-off-by: Andrei Kvapil <[email protected]>
@kvaps
Andrei Kvapil (kvaps) force-pushed the feat/linstor-csi-protocol-c-dual-attach branch from 3f2902c to 073fb16 Compare April 27, 2026 12:50
@kvaps
Andrei Kvapil (kvaps) merged commit f1e5641 into cozystack:main Apr 27, 2026
8 of 9 checks passed
@github-actions

Copy link
Copy Markdown

Andrei Kvapil (kvaps) added a commit that referenced this pull request Apr 27, 2026
…h Protocol-C dual-attach fix (#2505)

# Description
Backport of #2496 to `release-1.3`.
myasnikovdaniil added a commit that referenced this pull request Apr 29, 2026
The auto-generated changelog only listed #2459/#2467 (velero-configmap
Role move). Five additional PRs were backported and merged into
release-1.3 between then and the v1.3.1 tag (2026-04-28):

- #2471/#2524 - fix(api): IDOR in TenantNamespace Get/Watch
- #2496/#2505 - feat(linstor): linstor-csi v1.10.6 (Protocol-C dual-attach)
- #2462/#2511 - fix(etcd): remove destructive post-upgrade hook
- #2421/#2491 - fix(kamaji): memory limits + startup probe
- #2498/#2518 - build(linstor): wire linstor-gui into root build target

Update the release date to match the actual tag (2026-04-28), rewrite
the intro paragraph, and add @kvaps to contributors.

Signed-off-by: Myasnikov Daniil <[email protected]>
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/backport Categorizes issue or PR as requiring a backport to the current release line kind/feature Categorizes issue or PR as related to a new feature lgtm This PR has been approved by a maintainer size/L This PR changes 100-499 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants