mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-11-06 12:07:51 +01:00
feat: Phase 10 CP10-2 -- CSI NVMe/TCP node plugin, 210 tests
NVMe/TCP transport support in the CSI driver so Kubernetes pods can mount block volumes via NVMe alongside (or instead of) iSCSI. Transport selection: NVMe preferred when nvme_tcp module loaded + metadata present + nvmeUtil available. Fail-fast on NVMe errors (no silent iSCSI fallback). .transport file persists across CSI restarts. Key changes: - BuildNQN() single source of truth for NQN construction (naming.go) - NVMeUtil interface + realNVMeUtil wrapping nvme-cli (nvme_util.go) - NodeStageVolume/Unstage/Expand dual-transport paths (node.go) - NvmeAddr/NQN fields in VolumeInfo, Controller contexts - VolumeManager NvmeAddr()/VolumeNQN() getters - BlockService NvmeListenAddr()/NQN() accessors - 27 unit tests + 26 QA adversarial tests (nvme_node_test.go, qa_cp102) - Fix: flaky TestQA_Node_ConcurrentStageUnstage (pre-alloc temp dirs) Review fixes applied: F1 (NQN format mismatch), F2 (CreateVolume drops NVMe context), F3 (IsConnected error classification), F4 (findSubsys path validation), F5 (MasterVolumeClient NVMe gap documented). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
0e234f5c80
commit
bbadeeb89b
11 files changed
+2883
-90
No files matched your search
@@ -33,13 +33,14 @@ type NVMeConfig struct {
|
||||
|
||||
// BlockService manages block volumes and the iSCSI/NVMe target servers.
|
||||
type BlockService struct {
|
||||
blockStore *storage.BlockVolumeStore
|
||||
targetServer *iscsi.TargetServer
|
||||
nvmeServer *nvme.Server
|
||||
iqnPrefix string
|
||||
nqnPrefix string
|
||||
blockDir string
|
||||
listenAddr string
|
||||
blockStore *storage.BlockVolumeStore
|
||||
targetServer *iscsi.TargetServer
|
||||
nvmeServer *nvme.Server
|
||||
iqnPrefix string
|
||||
nqnPrefix string
|
||||
blockDir string
|
||||
listenAddr string
|
||||
nvmeListenAddr string
|
||||
|
||||
// Replication state (CP6-3).
|
||||
replMu sync.RWMutex
|
||||
@@ -63,11 +64,12 @@ func StartBlockService(listenAddr, blockDir, iqnPrefix, portalAddr string, nvmeC
|
||||
}
|
||||
|
||||
bs := &BlockService{
|
||||
blockStore: storage.NewBlockVolumeStore(),
|
||||
iqnPrefix: iqnPrefix,
|
||||
nqnPrefix: nqnPrefix,
|
||||
blockDir: blockDir,
|
||||
listenAddr: listenAddr,
|
||||
blockStore: storage.NewBlockVolumeStore(),
|
||||
iqnPrefix: iqnPrefix,
|
||||
nqnPrefix: nqnPrefix,
|
||||
blockDir: blockDir,
|
||||
listenAddr: listenAddr,
|
||||
nvmeListenAddr: nvmeCfg.ListenAddr,
|
||||
}
|
||||
|
||||
// iSCSI target setup.
|
||||
@@ -165,7 +167,7 @@ func (bs *BlockService) registerVolume(vol *blockvol.BlockVol, name string) {
|
||||
bs.targetServer.AddVolume(iqn, adapter)
|
||||
|
||||
if bs.nvmeServer != nil {
|
||||
nqn := bs.nqnPrefix + blockvol.SanitizeIQN(name)
|
||||
nqn := blockvol.BuildNQN(bs.nqnPrefix, name)
|
||||
nvmeAdapter := nvme.NewNVMeAdapter(vol)
|
||||
bs.nvmeServer.AddVolume(nqn, nvmeAdapter, nvmeAdapter.DeviceNGUID())
|
||||
}
|
||||
@@ -188,6 +190,19 @@ func (bs *BlockService) ListenAddr() string {
|
||||
return bs.listenAddr
|
||||
}
|
||||
|
||||
// NvmeListenAddr returns the configured NVMe/TCP target listen address, or empty if NVMe is disabled.
|
||||
func (bs *BlockService) NvmeListenAddr() string {
|
||||
if bs.nvmeServer != nil {
|
||||
return bs.nvmeListenAddr
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// NQN returns the NVMe subsystem NQN for a volume name.
|
||||
func (bs *BlockService) NQN(name string) string {
|
||||
return blockvol.BuildNQN(bs.nqnPrefix, name)
|
||||
}
|
||||
|
||||
// CreateBlockVol creates a new .blk file, registers it with BlockVolumeStore
|
||||
// and iSCSI TargetServer. Returns path, IQN, iSCSI addr.
|
||||
// Idempotent: if volume already exists with same or larger size, returns existing info.
|
||||
@@ -209,7 +224,7 @@ func (bs *BlockService) CreateBlockVol(name string, sizeBytes uint64, diskType s
|
||||
adapter := blockvol.NewBlockVolAdapter(vol)
|
||||
bs.targetServer.AddVolume(iqn, adapter)
|
||||
if bs.nvmeServer != nil {
|
||||
nqn := bs.nqnPrefix + blockvol.SanitizeIQN(name)
|
||||
nqn := blockvol.BuildNQN(bs.nqnPrefix, name)
|
||||
nvmeAdapter := nvme.NewNVMeAdapter(vol)
|
||||
bs.nvmeServer.AddVolume(nqn, nvmeAdapter, nvmeAdapter.DeviceNGUID())
|
||||
}
|
||||
@@ -250,7 +265,7 @@ func (bs *BlockService) CreateBlockVol(name string, sizeBytes uint64, diskType s
|
||||
bs.targetServer.AddVolume(iqn, adapter)
|
||||
|
||||
if bs.nvmeServer != nil {
|
||||
nqn := bs.nqnPrefix + blockvol.SanitizeIQN(name)
|
||||
nqn := blockvol.BuildNQN(bs.nqnPrefix, name)
|
||||
nvmeAdapter := nvme.NewNVMeAdapter(vol)
|
||||
bs.nvmeServer.AddVolume(nqn, nvmeAdapter, nvmeAdapter.DeviceNGUID())
|
||||
}
|
||||
@@ -273,7 +288,7 @@ func (bs *BlockService) DeleteBlockVol(name string) error {
|
||||
|
||||
// Remove from NVMe target.
|
||||
if bs.nvmeServer != nil {
|
||||
nqn := bs.nqnPrefix + blockvol.SanitizeIQN(name)
|
||||
nqn := blockvol.BuildNQN(bs.nqnPrefix, name)
|
||||
bs.nvmeServer.RemoveVolume(nqn)
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user