Skip to content

nvmeof: Add GroupLock to coordinate stage and unstage operations and e2e tests#6210

Merged
mergify[bot] merged 2 commits intoceph:develfrom
gadididi:nvmeof/add_locking_nodeserver
Apr 13, 2026
Merged

nvmeof: Add GroupLock to coordinate stage and unstage operations and e2e tests#6210
mergify[bot] merged 2 commits intoceph:develfrom
gadididi:nvmeof/add_locking_nodeserver

Conversation

@gadididi
Copy link
Copy Markdown
Contributor

@gadididi gadididi commented Mar 30, 2026

Describe what this PR does

This PR adds a GroupLock to prevent race conditions between stage and unstage operations that could lead to premature NVMe controller disconnects.
Added group mutual lock into NodeStageVolume() and NodeUnStageVolume() , because these 2 operations cannot run together. but few calls of same type can run together.

The Problem

Without coordination, a stage operation can connect to NVMe controllers while an unstage operation is simultaneously checking if it's safe to disconnect them. This creates a race:

  1. Stage operation connects to controllers
  2. Unstage operation checks cache, sees no devices
  3. Unstage operation disconnects controllers
  4. Stage operation tries to mount, but device is already disconnected

Result: Stage fails with "device not found" errors.

The Solution

Add a GroupLock that allows:

  • Multiple stage operations to run concurrently (Group A)
  • Multiple unstage operations to run concurrently (Group B)
  • But prevents stage and unstage from running at the same time

Three Levels of Locking

(after the PR: nvmeof: Add mount cache and locking for safe nvme disconnect will be merged)

The code will have three levels of locks working together:

Level 1: volumeLocks (per-volume mutex)
this already exists in the code.

  • Scope: Single volume
  • Purpose: Prevents concurrent operations on the same volume
  • Example: Two NodeStageVolume calls for vol-123 cannot run at the same time

Level 2: stageUnstageLock (GroupLock)
the current PR introduces it.

  • Scope: All volumes, operation type
  • Purpose: Prevents stage and unstage from interfering with each other
  • Allows: Multiple stages together, multiple unstages together
  • Prevents: Stage and unstage at the same time

Level 3: mountCache.mu (cache mutex)
this PR nvmeof: Add mount cache and locking for safe nvme disconnect

  • Scope: Cache data structure
  • Purpose: Protects cache reads and writes
  • Duration: Nanoseconds (just for map operations)

Lock Acquisition Order

Both NodeStageVolume and NodeUnstageVolume follow the same order:

  1. volumeLocks.Lock(volumeID) // Lock this specific volume
  2. stageUnstageLock.AcquireGroup() // Lock operation type (A or B)
  3. mountCache operations // Cache mutex acquired internally as needed
  4. stageUnstageLock.ReleaseGroup() // Release operation type
  5. volumeLocks.Release(volumeID) // Release volume lock

There are unit tests for group locking here: https://github.com/ceph/ceph-csi/blob/devel/internal/util/lock/group_lock_test.go

Also, e2e tests were added.

Checklist:

  • Commit Message Formatting: Commit titles and messages follow
    guidelines in the developer
    guide
    .
  • Reviewed the developer guide on Submitting a Pull
    Request
  • Pending release
    notes

    updated with breaking and/or notable changes for the next major release.
  • Documentation has been updated, if necessary.
  • Unit tests have been added, if necessary.
  • Integration tests have been added, if necessary.

Show available bot commands

These commands are normally not required, but in case of issues, leave any of
the following bot commands in an otherwise empty comment in this PR:

  • /retest ci/centos/<job-name>: retest the <job-name> after unrelated
    failure (please report the failure too!)

@gadididi gadididi self-assigned this Mar 30, 2026
@gadididi gadididi added the component/nvme-of Issues and PRs related to NVMe-oF. label Mar 30, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a cross-volume “group mutual exclusion” lock to the NVMe-oF node server to prevent NodeStageVolume and NodeUnstageVolume from running concurrently, avoiding races that can lead to premature NVMe controller disconnects.

Changes:

  • Introduces a stageUnstageLock (lock.GroupLock) field on the NVMe-oF NodeServer.
  • Wraps NodeStageVolume() with Group A acquire/release and NodeUnstageVolume() with Group B acquire/release.
  • Adds the internal/util/lock import to support the new locking behavior.

Comment thread internal/nvmeof/nodeserver/nodeserver.go Outdated
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

@gadididi
Copy link
Copy Markdown
Contributor Author

/test ci/centos/mini-e2e/k8s-1.35/nvmeof

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

Comment thread e2e/nvmeof_helper.go Outdated
Comment thread internal/nvmeof/nodeserver/nodeserver.go
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

@gadididi
Copy link
Copy Markdown
Contributor Author

/test ci/centos/mini-e2e/k8s-1.35/nvmeof

Copy link
Copy Markdown
Member

@nixpanic nixpanic left a comment

Choose a reason for hiding this comment

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

lgtm, thanks!

Comment thread internal/nvmeof/nodeserver/nodeserver.go
Comment thread e2e/nvmeof_helper.go Outdated
@gadididi gadididi force-pushed the nvmeof/add_locking_nodeserver branch from a214c1b to 6519c04 Compare April 1, 2026 09:44
@gadididi gadididi requested a review from Copilot April 1, 2026 09:44
@gadididi
Copy link
Copy Markdown
Contributor Author

gadididi commented Apr 1, 2026

/test ci/centos/mini-e2e/k8s-1.35/nvmeof

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 6 comments.

Comment thread e2e/nvmeof_helper.go Outdated
Comment thread e2e/nvmeof_helper.go Outdated
Comment thread e2e/nvmeof_helper.go Outdated
Comment thread e2e/nvmeof_helper.go
Comment thread e2e/nvmeof_helper.go Outdated
Comment thread e2e/nvmeof_helper.go Outdated
@gadididi gadididi force-pushed the nvmeof/add_locking_nodeserver branch from 6519c04 to 9094db7 Compare April 1, 2026 09:57
@gadididi gadididi requested a review from Copilot April 1, 2026 09:58
@gadididi
Copy link
Copy Markdown
Contributor Author

gadididi commented Apr 1, 2026

/test ci/centos/mini-e2e/k8s-1.35/nvmeof

@mergify mergify Bot added the queued label Apr 13, 2026
@mergify
Copy link
Copy Markdown
Contributor

mergify Bot commented Apr 13, 2026

Merge Queue Status

  • Entered queue2026-04-13 12:06 UTC · Rule: default
  • Checks started · in-place
  • 🚫 Left the queue2026-04-13 12:46 UTC · at 5aa179784f9012b45fd514d01cfb2be44ce736a1

This pull request spent 39 minutes 51 seconds in the queue, with no time running CI.

Required conditions to merge

Reason

The merge conditions cannot be satisfied due to failing checks

Hint

You may have to fix your CI before adding the pull request to the queue again.
If you update this pull request, to fix the CI, it will automatically be requeued once the queue conditions match again.
If you think this was a flaky issue instead, you can requeue the pull request, without updating it, by posting a @mergifyio queue comment.

added group mutual lock into `NodeStageVolume()` and
`NodeUnStageVolume()` , because these 2 operations cannot
run together. but few calls of same type can run together.

Signed-off-by: gadi-didi <gadi.didi@ibm.com>
Add e2e tests to validate nvmeof NodeServer GroupLock implementation
under concurrent NodeStage (Group A) and NodeUnstage (Group B)
operations. The tests ensure no deadlock occurs when multiple PVCs and
Pods are created and deleted simultaneously.

New helper file (nvmeof_helper.go) provides reusable functions for
concurrent PVC/Pod operations with proper error tracking.
Two test cases cover:
1) sequential concurrent batches (create all, then delete
all)

2) mixed operations with pre-created batch to guarantee
continuous Group A/B switching..

Signed-off-by: gadi-didi <gadi.didi@ibm.com>
@ceph-csi-bot ceph-csi-bot force-pushed the nvmeof/add_locking_nodeserver branch from f04bd14 to 5aa1797 Compare April 13, 2026 12:06
@mergify mergify Bot added the ok-to-test Label to trigger E2E tests label Apr 13, 2026
@ceph-csi-bot
Copy link
Copy Markdown
Collaborator

/test ci/centos/upgrade-tests-cephfs

@ceph-csi-bot
Copy link
Copy Markdown
Collaborator

/test ci/centos/k8s-e2e-external-storage/1.35

@ceph-csi-bot
Copy link
Copy Markdown
Collaborator

/test ci/centos/mini-e2e-helm/k8s-1.35

@ceph-csi-bot
Copy link
Copy Markdown
Collaborator

/test ci/centos/upgrade-tests-rbd

@ceph-csi-bot
Copy link
Copy Markdown
Collaborator

/test ci/centos/k8s-e2e-external-storage/1.33

@ceph-csi-bot
Copy link
Copy Markdown
Collaborator

/test ci/centos/mini-e2e/k8s-1.35

@ceph-csi-bot
Copy link
Copy Markdown
Collaborator

/test ci/centos/k8s-e2e-external-storage/1.34

@ceph-csi-bot
Copy link
Copy Markdown
Collaborator

/test ci/centos/mini-e2e-helm/k8s-1.33

@ceph-csi-bot
Copy link
Copy Markdown
Collaborator

/test ci/centos/mini-e2e-helm/k8s-1.34

@ceph-csi-bot
Copy link
Copy Markdown
Collaborator

/test ci/centos/mini-e2e/k8s-1.33

@ceph-csi-bot
Copy link
Copy Markdown
Collaborator

/test ci/centos/mini-e2e/k8s-1.34

@ceph-csi-bot ceph-csi-bot added ci/in-progress/e2e This label acts like a guard and prevents Mergify from adding the `ok-to-test` label again. and removed ok-to-test Label to trigger E2E tests labels Apr 13, 2026
@mergify mergify Bot added dequeued and removed ci/in-progress/e2e This label acts like a guard and prevents Mergify from adding the `ok-to-test` label again. queued labels Apr 13, 2026
@gadididi
Copy link
Copy Markdown
Contributor Author

@Mergifyio rebase

@mergify
Copy link
Copy Markdown
Contributor

mergify Bot commented Apr 13, 2026

rebase

☑️ Nothing to do, the required conditions are not met

Details
  • any of:
    • #commits-behind > 0 [📌 rebase requirement]
    • -linear-history [📌 rebase requirement]
  • -closed [📌 rebase requirement]
  • -conflict [📌 rebase requirement]
  • queue-position = -1 [📌 rebase requirement]

@nixpanic
Copy link
Copy Markdown
Member

/retest ci/centos/k8s-e2e-external-storage/1.34

@nixpanic
Copy link
Copy Markdown
Member

/retest ci/centos/k8s-e2e-external-storage/1.34

Failed with something related to CephFS:

[FAIL] External Storage [Driver: cephfs.csi.ceph.com] [Testpattern: Dynamic PV (default fs)] provisioning [It] should provision storage with pvc data source

logs

@mergify
Copy link
Copy Markdown
Contributor

mergify Bot commented Apr 13, 2026

Merge Queue Status

  • Entered queue2026-04-13 16:14 UTC · Rule: default
  • Checks skipped · PR is already up-to-date
  • Merged2026-04-13 16:14 UTC · at 5aa179784f9012b45fd514d01cfb2be44ce736a1

This pull request spent 21 seconds in the queue, including 4 seconds running CI.

Required conditions to merge

@mergify mergify Bot merged commit 199e62f into ceph:devel Apr 13, 2026
44 checks passed
@mergify mergify Bot removed the dequeued label Apr 13, 2026
@gadididi gadididi deleted the nvmeof/add_locking_nodeserver branch April 14, 2026 05:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component/nvme-of Issues and PRs related to NVMe-oF. component/testing Additional test cases or CI work

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants