Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CSI PowerMax: update nguid match to WWN #52

Merged
merged 2 commits into from
Jun 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions base_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ func (bmh *baseMockHelper) SCSIWaitUdevSymlinkErr(
return bmh.SCSIWaitUdevSymlinkCall(m).Return(mh.ErrTest)
}

func BaseConnectorCleanDeviceMock(mock *baseMockHelper,
func BaseConnectorCleanMultiPathDeviceMock(mock *baseMockHelper,
scsi *intscsi.MockSCSI, mp *intmultipath.MockMultipath,
) {
mock.SCSIGetDMDeviceByChildrenCallDevices = []string{
Expand All @@ -405,8 +405,22 @@ func BaseConnectorCleanDeviceMock(mock *baseMockHelper,
mock.MultipathDelPathOK(mp)
}

func BaseConnectorCleanDeviceMock(mock *baseMockHelper,
scsi *intscsi.MockSCSI,
) {
mock.SCSIGetDMDeviceByChildrenCallDevices = []string{
mh.ValidDeviceName, mh.ValidDeviceName2,
}
mock.SCSIGetDMDeviceByChildrenErr(scsi)

mock.SCSIDeleteSCSIDeviceByNameCallName = mh.ValidDeviceName
mock.SCSIDeleteSCSIDeviceByNameOK(scsi)
mock.SCSIDeleteSCSIDeviceByNameCallName = mh.ValidDeviceName2
mock.SCSIDeleteSCSIDeviceByNameOK(scsi)
}

func BaserConnectorDisconnectDevicesByDeviceNameMock(mock *baseMockHelper,
scsi *intscsi.MockSCSI, mp *intmultipath.MockMultipath,
scsi *intscsi.MockSCSI,
) {
mock.SCSIIsDeviceExistCallDevice = mh.ValidDMName
mock.SCSIIsDeviceExistOKReturn = true
Expand All @@ -424,5 +438,5 @@ func BaserConnectorDisconnectDevicesByDeviceNameMock(mock *baseMockHelper,
mock.SCSIGetDevicesByWWNOKReturn = mh.ValidDevices
mock.SCSIGetDevicesByWWNOK(scsi)

BaseConnectorCleanDeviceMock(mock, scsi, mp)
BaseConnectorCleanDeviceMock(mock, scsi)
}
8 changes: 6 additions & 2 deletions fc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,11 @@ func cleanConnectionMock(mock *baseMockHelper,
mock.SCSIGetDeviceNameByHCTLCallH = validHCTL1Target1
mock.SCSIGetDeviceNameByHCTLErr(scsi).AnyTimes()

BaseConnectorCleanDeviceMock(mock, scsi, multipath)
if mock.MultipathIsDaemonRunningOKReturn {
BaseConnectorCleanMultiPathDeviceMock(mock, scsi, multipath)
} else {
BaseConnectorCleanDeviceMock(mock, scsi)
}
}

func TestFCConnector_ConnectVolume(t *testing.T) {
Expand Down Expand Up @@ -438,7 +442,7 @@ func TestFCConnector_DisconnectVolumeByDeviceName(t *testing.T) {
fields: getDefaultFCFields(ctrl),
stateSetter: func(fields fcFields) {
BaserConnectorDisconnectDevicesByDeviceNameMock(
&mock, fields.scsi, fields.multipath)
&mock, fields.scsi)
},
args: defaultArgs,
wantErr: false,
Expand Down
1 change: 1 addition & 0 deletions gobrick_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ var (
validLunNumber = 199
validSCSIHost1 = "34"
validSCSIHost2 = "35"
validNQN = "11aaa111111111a11a111a1111aa1111"
validHostOnlyHCTL1 = scsi.HCTL{Host: validSCSIHost1, Channel: "-", Target: "-", Lun: "-"}
validHostOnlyHCTL2 = scsi.HCTL{Host: validSCSIHost2, Channel: "-", Target: "-", Lun: "-"}
validHCTL1 = scsi.HCTL{
Expand Down
13 changes: 11 additions & 2 deletions iscsi_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import (
"testing"
"time"

"github.com/dell/gobrick/internal/powerpath"

"github.com/dell/gobrick/internal/mockhelper"
intmultipath "github.com/dell/gobrick/internal/multipath"
intscsi "github.com/dell/gobrick/internal/scsi"
Expand Down Expand Up @@ -91,6 +93,7 @@ type iscsiFields struct {
scsi *intscsi.MockSCSI
iscsiLib *wrp.MockISCSILib
filePath *wrp.MockLimitedFilepath
powerpath *powerpath.MockPowerpath

manualSessionManagement bool
waitDeviceTimeout time.Duration
Expand All @@ -106,12 +109,14 @@ func getDefaultISCSIFields(ctrl *gomock.Controller) iscsiFields {
bc := con.baseConnector
mpMock := intmultipath.NewMockMultipath(ctrl)
scsiMock := intscsi.NewMockSCSI(ctrl)
ppath := powerpath.NewMockPowerpath(ctrl)
bc.multipath = mpMock
bc.scsi = scsiMock
return iscsiFields{
baseConnector: bc,
multipath: mpMock,
scsi: scsiMock,
powerpath: ppath,
iscsiLib: wrp.NewMockISCSILib(ctrl),
filePath: wrp.NewMockLimitedFilepath(ctrl),
manualSessionManagement: con.manualSessionManagement,
Expand Down Expand Up @@ -394,6 +399,7 @@ func TestISCSIConnector_ConnectVolume(t *testing.T) {
baseConnector: tt.fields.baseConnector,
multipath: tt.fields.multipath,
scsi: tt.fields.scsi,
powerpath: tt.fields.powerpath,
iscsiLib: tt.fields.iscsiLib,
manualSessionManagement: tt.fields.manualSessionManagement,
waitDeviceTimeout: tt.fields.waitDeviceTimeout,
Expand Down Expand Up @@ -467,6 +473,7 @@ func TestISCSIConnector_GetInitiatorName(t *testing.T) {
c := &ISCSIConnector{
baseConnector: tt.fields.baseConnector,
multipath: tt.fields.multipath,
powerpath: tt.fields.powerpath,
scsi: tt.fields.scsi,
iscsiLib: tt.fields.iscsiLib,
manualSessionManagement: tt.fields.manualSessionManagement,
Expand Down Expand Up @@ -556,7 +563,7 @@ func TestISCSIConnector_DisconnectVolume(t *testing.T) {
mock.SCSIGetDeviceNameByHCTLCallH = validHCTL2
mock.SCSIGetDeviceNameByHCTLOK(fields.scsi)

BaseConnectorCleanDeviceMock(&mock, fields.scsi, fields.multipath)
BaseConnectorCleanDeviceMock(&mock, fields.scsi)
},
args: defaultArgs,
wantErr: false,
Expand All @@ -567,6 +574,7 @@ func TestISCSIConnector_DisconnectVolume(t *testing.T) {
c := &ISCSIConnector{
baseConnector: tt.fields.baseConnector,
multipath: tt.fields.multipath,
powerpath: tt.fields.powerpath,
scsi: tt.fields.scsi,
iscsiLib: tt.fields.iscsiLib,
manualSessionManagement: tt.fields.manualSessionManagement,
Expand Down Expand Up @@ -613,7 +621,7 @@ func TestISCSIConnector_DisconnectVolumeByDeviceName(t *testing.T) {
name: "ok",
fields: getDefaultISCSIFields(ctrl),
stateSetter: func(fields iscsiFields) {
BaserConnectorDisconnectDevicesByDeviceNameMock(&mock, fields.scsi, fields.multipath)
BaserConnectorDisconnectDevicesByDeviceNameMock(&mock, fields.scsi)
},
args: defaultArgs,
wantErr: false,
Expand All @@ -624,6 +632,7 @@ func TestISCSIConnector_DisconnectVolumeByDeviceName(t *testing.T) {
c := &ISCSIConnector{
baseConnector: tt.fields.baseConnector,
multipath: tt.fields.multipath,
powerpath: tt.fields.powerpath,
scsi: tt.fields.scsi,
iscsiLib: tt.fields.iscsiLib,
manualSessionManagement: tt.fields.manualSessionManagement,
Expand Down
55 changes: 35 additions & 20 deletions nvme.go
Original file line number Diff line number Diff line change
Expand Up @@ -279,13 +279,12 @@ func (c *NVMeConnector) cleanConnection(ctx context.Context, force bool, info NV
}
var devicePath string
var namespace string

log.Debugf("DevicePathsAndNamespaces: %s", DevicePathsAndNamespaces)
for _, DevicePathAndNamespace := range DevicePathsAndNamespaces {
devicePath = DevicePathAndNamespace.DevicePath
namespace = DevicePathAndNamespace.Namespace

nguid, newnamespace, _ := c.nvmeLib.GetNVMeDeviceData(devicePath)

log.Debugf("nguid: %s, wwn: %s, newnamespace: %s, namespace: %s", nguid, wwn, newnamespace, namespace)
if c.wwnMatches(nguid, wwn) && namespace == newnamespace {
devices = append(devices, devicePath)
}
Expand Down Expand Up @@ -481,7 +480,7 @@ func (c *NVMeConnector) validateNVMeVolumeInfo(ctx context.Context, info NVMeVol
}

func (c *NVMeConnector) discoverDevice(ctx context.Context, wg *sync.WaitGroup, result chan DevicePathResult, info NVMeVolumeInfo, useFC bool) {
defer tracer.TraceFuncCall(ctx, "NVMeConnector.findDevice")()
defer tracer.TraceFuncCall(ctx, "NVMeConnector.discoverDevice")()
defer wg.Done()
wwn := info.WWN

Expand All @@ -494,18 +493,15 @@ func (c *NVMeConnector) discoverDevice(ctx context.Context, wg *sync.WaitGroup,
if err != nil {
log.Errorf("Couldn't find the nvme namespaces %s", err.Error())
}

var devicePaths []string
var devicePath string
var namespace string

log.Debugf("DevicePathsAndNamespaces %+v retryCount %d", DevicePathsAndNamespaces, retryCount)
for _, DevicePathAndNamespace := range DevicePathsAndNamespaces {

devicePath = DevicePathAndNamespace.DevicePath
namespace = DevicePathAndNamespace.Namespace

nguid, newnamespace, _ := c.nvmeLib.GetNVMeDeviceData(devicePath)

log.Debugf("nguid %s, wwn %s, newnamespace %s, namespace %s", nguid, wwn, newnamespace, namespace)
if c.wwnMatches(nguid, wwn) && namespace == newnamespace {
devicePaths = append(devicePaths, devicePath)
nguidResult = nguid
Expand All @@ -516,7 +512,7 @@ func (c *NVMeConnector) discoverDevice(ctx context.Context, wg *sync.WaitGroup,
}
}
devicePathResult = DevicePathResult{devicePaths: devicePaths, nguid: nguidResult}

logger.Debug(ctx, "devicePathResult", devicePathResult, "nguidResult", nguidResult, "retryCount", retryCount)
if nguidResult != "" || retryCount == 1 {
break
}
Expand All @@ -532,20 +528,39 @@ func (c *NVMeConnector) discoverDevice(ctx context.Context, wg *sync.WaitGroup,

func (c *NVMeConnector) wwnMatches(nguid, wwn string) bool {
/*
Sample wwn : naa.68ccf098001111a2222b3d4444a1b23c
wwn1 : 1111a2222b3d4444
wwn2 : a1b23c
Sample nguid : 1111a2222b3d44448ccf096800a1b23c
Sample wwn : naa.68ccf098001111a2222b3d4444a1b23c
wwn1 : 1111a2222b3d4444
wwn2 : a1b23c
Sample nguid : 1111a2222b3d44448ccf096800a1b23c
/ pmax:
nguid: 12635330303134340000976000012000
wwn: 60000970000120001263533030313434
11aaa111111111a11a111a1111aa1111
1a111a1111aa1111 1aaa11 1 1111111a1
nguid: wwn[last16] + wwn[1:6] + wwn[0] + wwn[7:15]
1263533030313434 + 000097 + 6 + 000012000
*/
if len(wwn) < 32 {
return false
}
wwn1 := wwn[13 : len(wwn)-7]
wwn2 := wwn[len(wwn)-6 : len(wwn)-1]

if strings.Contains(nguid, wwn1) && strings.Contains(nguid, wwn2) {
return true
var wwn1, wwn2 string
if strings.Contains(wwn, "naa") {
// powerstore
wwn1 = wwn[13 : len(wwn)-7]
wwn2 = wwn[len(wwn)-6 : len(wwn)-1]
if strings.Contains(nguid, wwn1) && strings.Contains(nguid, wwn2) {
return true
}
} else {
// pmax
wwn1 = wwn[16:]
wwn2 = wwn[1:7]
log.Infof("Powermax: %s %s %s %t", wwn1, wwn2, nguid, strings.HasPrefix(nguid, wwn1+wwn2))
if strings.HasPrefix(nguid, wwn1+wwn2) {
return true
}
}
return false
}
Expand Down
Loading