feat(spdk): thread NVMe-oF transport type through engine/replica create - #654
feat(spdk): thread NVMe-oF transport type through engine/replica create#654abonillabeeche wants to merge 2 commits into
Conversation
b956331 to
1ec2e82
Compare
| SalvageRequested: salvageRequested, | ||
| SnapshotMaxCount: snapshotMaxCount, | ||
| DataLayoutType: dataLayoutType, | ||
| DataEngineTransport: dataEngineTransport, |
There was a problem hiding this comment.
NIT: TransportType may be better. No need to add prefix DataEngine
There was a problem hiding this comment.
dropping the DataEngine prefix: the remaining DataEngineTransport here is the generated proto field from longhorn/types#121. Renaming it to transport_type is a clean change but cascades to longhorn-manager and instance-manager. Want me to rename it in #121 for consistency, or keep the proto field namespaced and only use TransportType on the Go structs?
| // data_engine_transport; unset (empty) is treated as TCP for backward | ||
| // compatibility. Only the internal engine<->replica data fabric honors this; | ||
| // the host-facing NVMe-TCP frontend and all EC/transient paths stay TCP. | ||
| Trtype spdktypes.NvmeTransportType |
| e.Name, e.NvmeTcpTarget.IP, e.NvmeTcpTarget.Port, initialANAState, cntlid, nsUUID) | ||
| if err := spdkClient.StartExposeBdevWithANAState(e.NvmeTcpTarget.Nqn, e.Name, e.NvmeTcpTarget.Nguid, nsUUID, | ||
| e.NvmeTcpTarget.IP, strconv.Itoa(int(e.NvmeTcpTarget.Port)), spdkANAState, cntlid, cntlid); err != nil { | ||
| e.NvmeTcpTarget.IP, strconv.Itoa(int(e.NvmeTcpTarget.Port)), spdktypes.NvmeTransportTypeTCP, spdkANAState, cntlid, cntlid); err != nil { |
There was a problem hiding this comment.
NIT: Add a TODO comment for the Frontend adaptation
There was a problem hiding this comment.
renamed the struct field to TransportType on both Engine and Replica, and the client-method params to transportType
| e.backends[replicaName] = backendFactory(replicaName, replicaAddr) | ||
|
|
||
| bdevName, err := connectNVMfBdev(spdkClient, replicaName, replicaAddr, e.ctrlrLossTimeout, e.fastIOFailTimeoutSec, maxRetries, retryInterval) | ||
| bdevName, err := connectNVMfBdev(spdkClient, replicaName, replicaAddr, e.Trtype, e.ctrlrLossTimeout, e.fastIOFailTimeoutSec, maxRetries, retryInterval) |
There was a problem hiding this comment.
Probably we need to validate whether the replicas are using the same tytype with this engine. The validation can be applied by refactoring func validateReplicaSize
| // Select the internal engine<->replica NVMe-oF transport. Unset (TCP=0) | ||
| // preserves historical TCP behavior. Must match the transport the replicas | ||
| // used to expose their heads. | ||
| e.Trtype = nvmeTransportFromProto(req.DataEngineTransport) | ||
|
|
There was a problem hiding this comment.
It's better to directly add an input TransportType for the above NewEngine instead
There was a problem hiding this comment.
TransportType is now an argument to NewEngine(...) and set at construction; dropped the post-construct assignment.
| if err := spdkClient.StartExposeBdev(helpertypes.GetNQN(r.snapshotCloningDstCache.cloningLvol.Name), | ||
| r.snapshotCloningDstCache.cloningLvol.UUID, generateNGUID(r.snapshotCloningDstCache.cloningLvol.Name), r.IP, | ||
| strconv.Itoa(int(r.snapshotCloningDstCache.cloningPort)), helpertypes.InternalHostNQN); err != nil { | ||
| strconv.Itoa(int(r.snapshotCloningDstCache.cloningPort)), spdktypes.NvmeTransportTypeTCP, helpertypes.InternalHostNQN); err != nil { |
There was a problem hiding this comment.
Can we use RDMA here (clone) or in the below rebuilding/expansion? Or you can add TODO comments first.
|
Besides, I am thinking whether Longhorn needs to detect the availability of RDMA hardware before accepting the transport type |
Add an RDMA option to the internal engine<->replica data path of the v2 data engine. Adds a TransportType field (default TCP) to the Engine and Replica objects, set from the new spdkrpc DataEngineTransport field, and uses it at the two sites that cross the network: replica head export (StartExposeBdev) and engine->replica connect (connectNVMfBdev). The engine's TransportType is now passed into NewEngine at construction rather than set on the returned object. All other exposure/connect sites (frontend, transient, clone, rebuild-src, external snapshot, EC shard/shardgroup) stay pinned to TCP, with TODOs on the frontend and transient paths for future RDMA support. validateNvmeTransport relaxed to accept TCP or RDMA. Default behavior is unchanged (unset => TCP). Ref: longhorn/longhorn#13796 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Alejandro Bonilla <abonilla@suse.com>
1ec2e82 to
dfc5f2e
Compare
|
Thanks for the review — pushed a revision addressing the NITs.
Default behavior is unchanged: an unset transport maps to TCP, so an older control plane keeps working. Not e2e-tested in this revision. |
Rename the struct field to TransportType on Engine and Replica and the client-method params to transportType, and consume the renamed spdkrpc.TransportType enum. No behavior change. Ref: longhorn/longhorn#13796 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Alejandro Bonilla <abonilla@suse.com>
Address review on longhorn/longhorn-spdk-engine#654: this proto lives in a v2-data-engine-only surface, and this repo's convention is TransportType, so drop the DataEngine prefix on the generated type. - imrpc/spdkrpc: enum DataEngineTransport -> TransportType, values DATA_ENGINE_TRANSPORT_{TCP,RDMA} -> TRANSPORT_TYPE_{TCP,RDMA}, field data_engine_transport -> transport_type. Wire-compatible: field numbers and enum values are unchanged, so already deployed peers keep interoperating; only source that references the Go/py identifiers must be recompiled. Ref: longhorn/longhorn#13796 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Alejandro Bonilla <abonilla@suse.com>
…for v2 Address review on longhorn/longhorn-spdk-engine#654: detect RDMA hardware availability in longhorn-manager so an invalid RDMA volume is rejected early, and handle mixed clusters where only some nodes are RoCE-capable. Node detection: - environment check monitor reports a new RDMACapable node condition for v2-enabled nodes, based on whether /sys/class/infiniband enumerates any device. Validation and scheduling: - volume validator rejects dataEngineTransport=rdma unless the data engine is v2 and at least NumberOfReplicas RDMA-capable nodes exist (checked on create and on replica scale-up). - replica scheduler confines RDMA-volume replicas to RDMA-capable nodes, keeping mixed clusters correct. Device access: - new opt-in setting v2-data-engine-rdma-device-resource. When set to an extended resource advertised by an RDMA shared device plugin (e.g. k8s-rdma-shared-dev-plugin), the v2 instance-manager pod requests it, gaining declarative shared access to the RoCE verbs device without a bond and preserving per-pod RoCEv2 GIDs. Empty (default) keeps the prior privileged host-mount behavior. Ref: longhorn/longhorn#13796 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Alejandro Bonilla <abonilla@suse.com>
Part of longhorn/longhorn#13796. Depends on longhorn/types#121 and longhorn/go-spdk-helper#308.
Carry the
DataEngineTransportfrom the spdkrpc create requests into replica and engine setup: create the matching NVMe-oF transport (RDMA or TCP) on the SPDK target, add the listener with the right trtype, and connect the engine's controllers over the selected transport. RDMA uses RoCEv2 (adrfam=ipv4). Unset means TCP; existing volumes and the host frontend are unaffected (frontend stays TCP).Files:
pkg/spdk/{engine,replica,server,server_engine,util,shard,shardgroup}.go,pkg/client/{client_engine,client_replica}.go.