From 17741804f40a9c8716e99373606d6987260561e7 Mon Sep 17 00:00:00 2001 From: Derek Su Date: Tue, 26 Nov 2024 22:52:15 +0800 Subject: [PATCH] feat(v2 upgrade): expose nvme subsystem information Longhorn 9104 Signed-off-by: Derek Su --- pkg/api/types.go | 29 +++++++++++++++++++++++++++++ pkg/spdk/engine.go | 27 +++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/pkg/api/types.go b/pkg/api/types.go index 1f600307..1edf936b 100644 --- a/pkg/api/types.go +++ b/pkg/api/types.go @@ -40,6 +40,18 @@ type Lvol struct { SnapshotTimestamp string `json:"snapshot_timestamp"` } +type NvmeDevicePath struct { + Trtype string `json:"trtype"` + Traddr string `json:"traddr"` + Trsvcid string `json:"trsvcid"` + SrcAddr string `json:"src_addr"` + State string `json:"state"` +} + +type NvmeSubsystem struct { + Paths map[string]*NvmeDevicePath `json:"paths"` +} + func ProtoLvolToLvol(l *spdkrpc.Lvol) *Lvol { if l == nil { return nil @@ -138,9 +150,25 @@ type Engine struct { Endpoint string `json:"endpoint"` State string `json:"state"` ErrorMsg string `json:"error_msg"` + NvmeSubsystem NvmeSubsystem `json:"nvme_subsystem"` } func ProtoEngineToEngine(e *spdkrpc.Engine) *Engine { + nvme := NvmeSubsystem{ + Paths: map[string]*NvmeDevicePath{}, + } + if e.NvmeSubsystem != nil { + for pathName, path := range e.NvmeSubsystem.Paths { + nvme.Paths[pathName] = &NvmeDevicePath{ + Trtype: path.Trtype, + Traddr: path.Traddr, + Trsvcid: path.Trsvcid, + SrcAddr: path.SrcAddr, + State: path.State, + } + } + } + res := &Engine{ Name: e.Name, VolumeName: e.VolumeName, @@ -159,6 +187,7 @@ func ProtoEngineToEngine(e *spdkrpc.Engine) *Engine { Endpoint: e.Endpoint, State: e.State, ErrorMsg: e.ErrorMsg, + NvmeSubsystem: nvme, } for rName, mode := range e.ReplicaModeMap { res.ReplicaModeMap[rName] = types.GRPCReplicaModeToReplicaMode(mode) diff --git a/pkg/spdk/engine.go b/pkg/spdk/engine.go index 5815273c..e614b793 100644 --- a/pkg/spdk/engine.go +++ b/pkg/spdk/engine.go @@ -47,6 +47,7 @@ type Engine struct { Endpoint string Nqn string Nguid string + NvmeSubsystem api.NvmeSubsystem ReplicaStatusMap map[string]*EngineReplicaStatus @@ -99,6 +100,10 @@ func NewEngine(engineName, volumeName, frontend string, specSize uint64, engineU SnapshotMap: map[string]*api.Lvol{}, + NvmeSubsystem: api.NvmeSubsystem{ + Paths: map[string]*api.NvmeDevicePath{}, + }, + UpdateCh: engineUpdateCh, log: log, @@ -613,6 +618,19 @@ func (e *Engine) Get() (res *spdkrpc.Engine) { } func (e *Engine) getWithoutLock() (res *spdkrpc.Engine) { + nvmeSubsystem := &spdkrpc.NvmeSubsystem{ + Paths: map[string]*spdkrpc.NvmeDevicePath{}, + } + for pathName, path := range e.NvmeSubsystem.Paths { + nvmeSubsystem.Paths[pathName] = &spdkrpc.NvmeDevicePath{ + Trtype: path.Trtype, + Traddr: path.Traddr, + Trsvcid: path.Trsvcid, + SrcAddr: path.SrcAddr, + State: path.State, + } + } + res = &spdkrpc.Engine{ Name: e.Name, SpecSize: e.SpecSize, @@ -629,6 +647,7 @@ func (e *Engine) getWithoutLock() (res *spdkrpc.Engine) { Endpoint: e.Endpoint, State: string(e.State), ErrorMsg: e.ErrorMsg, + NvmeSubsystem: nvmeSubsystem, } for replicaName, replicaStatus := range e.ReplicaStatusMap { @@ -935,6 +954,14 @@ func (e *Engine) validateAndUpdateFrontend(subsystemMap map[string]*spdktypes.Nv } return err } + + e.NvmeSubsystem.Paths[e.initiator.ControllerName] = &api.NvmeDevicePath{ + Trtype: string(spdktypes.NvmeTransportTypeTCP), + Traddr: e.initiator.TransportAddress, + Trsvcid: e.initiator.TransportServiceID, + State: e.initiator.ControllerState, + } + if err := e.initiator.LoadEndpoint(e.dmDeviceBusy); err != nil { return err }