Skip to content

feat(engine, replica): v2 volume expand #8022#386

Merged
derekbit merged 8 commits into
longhorn:mainfrom
davidcheng0922:issue-8022-volume-expansion
Sep 10, 2025
Merged

feat(engine, replica): v2 volume expand #8022#386
derekbit merged 8 commits into
longhorn:mainfrom
davidcheng0922:issue-8022-volume-expansion

Conversation

@davidcheng0922
Copy link
Copy Markdown
Contributor

@davidcheng0922 davidcheng0922 commented Jul 25, 2025

Which issue(s) this PR fixes:

longhorn/longhorn#8022

What this PR does / why we need it:

support v2 volume expansion, only for nvme frontend

Special notes for your reviewer:

Additional documentation or context

v2-expansion.webm
v2-expansion-with-live-IO.webm

@davidcheng0922 davidcheng0922 requested a review from a team July 25, 2025 06:09
@davidcheng0922 davidcheng0922 changed the title Issue 8022 volume expansion feat(engine, replica): v2 volume expand #8022 Jul 25, 2025
@codecov
Copy link
Copy Markdown

codecov Bot commented Jul 25, 2025

Codecov Report

❌ Patch coverage is 0% with 586 lines in your changes missing coverage. Please review.
✅ Project coverage is 0.67%. Comparing base (4d9b75a) to head (f0e90a9).
⚠️ Report is 9 commits behind head on main.

Files with missing lines Patch % Lines
pkg/spdk/engine.go 0.00% 438 Missing ⚠️
pkg/spdk/replica.go 0.00% 88 Missing ⚠️
pkg/spdk/server.go 0.00% 31 Missing ⚠️
pkg/client/client.go 0.00% 29 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff            @@
##            main    #386      +/-   ##
========================================
- Coverage   0.77%   0.67%   -0.10%     
========================================
  Files         24      24              
  Lines       9866   11273    +1407     
========================================
  Hits          76      76              
- Misses      9783   11190    +1407     
  Partials       7       7              
Flag Coverage Δ
unittests 0.67% <0.00%> (-0.10%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment thread pkg/spdk/engine.go Outdated
Comment on lines +1400 to +1412
// partial success
// for the fail one, we set it to ERR
aggregatedErr := map[string]string{}
for replicaName, err := range failedReplica {
e.ReplicaStatusMap[replicaName].Mode = types.ModeERR
aggregatedErr[replicaName] = err.Error()
}

e.log.WithFields(logrus.Fields{
"engineName": e.Name,
"volumeName": e.VolumeName,
"failedReplicas": aggregatedErr,
}).Error("Some replicas failed to expand and have been marked as ERR")
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.

Good idea to mark the failed to expand replica as failed.

Quick question, is this possible to revert the replica expansion?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, go-spdk-helper bdev-lvol resize support to shrink size.
But it will be dangerous, I think it will directly remove the blobs without any data protection.

During the expansion, as we suspend the I/O, I think it will be ok, but I don't think we have to revert the size; instead only contain the successful ones.

If it is needed for other rpc call, maybe need a snapshot before doing it and it will become more complicated for revert.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

it will be dangerous

Why is the operation dangerous?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The dangerous means if we allow shrink in some cases, I'm afraid the data will be erased and the fs is broken.
If we can make sure the data is not used, it might be ok.

Comment thread pkg/spdk/engine.go Outdated
@davidcheng0922 davidcheng0922 force-pushed the issue-8022-volume-expansion branch 2 times, most recently from 02a8b79 to ac856a7 Compare August 1, 2025 09:44
Comment thread pkg/spdk/replica.go Outdated
Comment thread pkg/spdk/replica.go Outdated
Comment thread pkg/spdk/replica.go Outdated
Comment thread pkg/spdk/engine.go Outdated
Comment thread pkg/spdk/engine.go Outdated
Comment thread pkg/spdk/engine.go Outdated
Comment thread pkg/spdk/engine.go Outdated
Comment thread pkg/spdk/engine.go Outdated
Comment thread pkg/spdk/engine.go Outdated
@davidcheng0922 davidcheng0922 force-pushed the issue-8022-volume-expansion branch 2 times, most recently from d5ab71e to 89173b4 Compare August 11, 2025 01:28
@davidcheng0922
Copy link
Copy Markdown
Contributor Author

davidcheng0922 commented Aug 11, 2025

Blocker:

ublk expansion process
the current workable expansion process for nvme is

  1. suspend --noflush=false --nolockfs=false
  2. bdev-raid delete
  3. controller detach
  4. resize lvol
  5. controller attach
  6. bdev-raid create
  7. reload / resume dm

For ublk,

  1. suspend --noflush=false --nolockfs=false -> success
  2. bdev-raid delete -> the raid is deleted, but timeout, no response from spdk (not sure the reason, maybe ublk kernel driver hang the response)
  3. controller detach -> although we ignore the timeout issue previous, it still hang in this step

Interesting things, if I manually execute command in the same order
the bdev-raid will not timeout, but still hang in controller detach
maybe the resource is not fully released

Tried method :

  • Add backoff and time to check if it is race condition
  • Stop ublk disk before/after suspension without removing the dm

To brief, my guess,
When suspend succeeds, the kernel believes the ublk device is idle. The SPDK application is blocked because it can't free up resources that the kernel's ublk driver is still holding.
nvme can work maybe is because of network block device
I'm not sure about my understanding is correct or not, any comment is welcomed

Currently, because ublk is not the priority, I will stop here, and do more research in the future.

@davidcheng0922 davidcheng0922 force-pushed the issue-8022-volume-expansion branch from 89173b4 to 159083a Compare August 20, 2025 03:10
@davidcheng0922 davidcheng0922 force-pushed the issue-8022-volume-expansion branch from 159083a to e3152e4 Compare August 21, 2025 08:21
Comment thread pkg/spdk/engine.go
Comment thread pkg/spdk/engine.go Outdated
Comment thread pkg/spdk/engine.go Outdated
Comment thread pkg/spdk/engine.go Outdated
Comment thread pkg/spdk/engine.go
Comment thread pkg/spdk/engine.go Outdated
Comment thread pkg/spdk/engine.go Outdated
Comment thread pkg/spdk/engine.go Outdated
Comment thread pkg/spdk/engine.go Outdated
Comment thread pkg/spdk/replica.go Outdated
@mergify
Copy link
Copy Markdown

mergify Bot commented Aug 26, 2025

This pull request is now in conflict. Could you fix it @davidcheng0922? 🙏

@davidcheng0922 davidcheng0922 force-pushed the issue-8022-volume-expansion branch 3 times, most recently from f0b8910 to dcf99a0 Compare August 27, 2025 09:48
@davidcheng0922 davidcheng0922 requested a review from shuo-wu August 27, 2025 09:52
Comment thread pkg/spdk/engine.go Outdated
Comment thread pkg/spdk/engine.go Outdated
Comment thread pkg/spdk/engine.go Outdated
Comment thread pkg/spdk/engine.go Outdated
Comment thread pkg/spdk/engine.go Outdated
Comment thread pkg/spdk/engine.go

// Suspend IO if frontend is active
if e.Frontend == types.FrontendSPDKTCPBlockdev && e.Endpoint != "" {
if err := e.initiator.Suspend(false, false); err != 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.

Just want to double check. This function means dm device suspension, right?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

yeah, it actually calls
dmsetup suspend --noflush=false --nolockfs=false

@davidcheng0922 davidcheng0922 force-pushed the issue-8022-volume-expansion branch 3 times, most recently from 0dbf28f to 9d8a90d Compare August 28, 2025 07:52
Comment thread pkg/client/client.go
Comment thread pkg/client/client.go Outdated
Comment thread pkg/spdk/replica.go Outdated
Comment thread pkg/spdk/replica.go Outdated
@derekbit derekbit force-pushed the issue-8022-volume-expansion branch from 8970b27 to 5736962 Compare September 6, 2025 03:21
Comment thread pkg/spdk/engine.go Outdated
Comment thread pkg/spdk/engine.go
Comment thread pkg/spdk/replica.go Outdated
Comment thread pkg/spdk/engine.go Outdated
Comment thread pkg/spdk/engine.go Outdated
Comment thread pkg/spdk/engine.go
@davidcheng0922 davidcheng0922 force-pushed the issue-8022-volume-expansion branch 2 times, most recently from 98f0ae2 to 7ca6e43 Compare September 9, 2025 08:19
Comment thread pkg/client/client.go Outdated

func (c *SPDKClient) ReplicaExpand(name string, size uint64) error {
if name == "" {
return fmt.Errorf("failed to delete SPDK replica: missing required parameter")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
return fmt.Errorf("failed to delete SPDK replica: missing required parameter")
return fmt.Errorf("failed to expand replica: missing required parameter")

Comment thread pkg/client/client.go Outdated
Comment thread pkg/spdk/engine.go Outdated
Comment thread pkg/spdk/server.go
Comment thread pkg/spdk/replica.go Outdated
Comment thread pkg/spdk/replica.go
Comment thread pkg/spdk/engine.go
Comment thread pkg/spdk/engine.go Outdated
Comment thread pkg/spdk/engine.go Outdated
Comment thread pkg/spdk/engine.go Outdated
Comment thread pkg/spdk/engine.go Outdated
Comment thread pkg/spdk/engine.go
@derekbit derekbit force-pushed the issue-8022-volume-expansion branch from 7ca6e43 to 6b71171 Compare September 10, 2025 00:20
@davidcheng0922 davidcheng0922 force-pushed the issue-8022-volume-expansion branch from 6b71171 to 4206442 Compare September 10, 2025 07:22
Signed-off-by: David Cheng <davidcheng0922@gmail.com>
- disconnect nvme target & stop expose bdev before deleting raid

Signed-off-by: David Cheng <davidcheng0922@gmail.com>
Signed-off-by: David Cheng <davidcheng0922@gmail.com>
Signed-off-by: David Cheng <davidcheng0922@gmail.com>
Signed-off-by: David Cheng <davidcheng0922@gmail.com>
Signed-off-by: David Cheng <davidcheng0922@gmail.com>
- Replace backoff with retry.RetryOnConflict for update retry
- Use handleNvmeTcpFrontend instead of reconnectNvmeTcpFrontend
- Remove unnecessary check in replica expand
- Refactor finishExpansion for clarity and separation of concerns

Signed-off-by: David Cheng <davidcheng0922@gmail.com>
…and polish log

Signed-off-by: David Cheng <davidcheng0922@gmail.com>
Copy link
Copy Markdown
Member

@derekbit derekbit left a comment

Choose a reason for hiding this comment

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

LGTM

@derekbit derekbit merged commit d7f9a69 into longhorn:main Sep 10, 2025
8 of 11 checks passed
@derekbit
Copy link
Copy Markdown
Member

@davidcheng0922 Thank you. You can update longhorn-instance-manager PR.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants