Skip to content

Commit a8c7fc0

Browse files
authored
Makes FCP protocol inline with ISCSI.
1 parent 34b7b8b commit a8c7fc0

File tree

7 files changed

+342
-206
lines changed

7 files changed

+342
-206
lines changed

frontend/csi/node_server.go

Lines changed: 84 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1148,6 +1148,7 @@ func (p *Plugin) nodeStageFCPVolume(
11481148

11491149
publishInfo.MountOptions = req.PublishContext["mountOptions"]
11501150
publishInfo.FCTargetWWNN = req.PublishContext["fcTargetWWNN"]
1151+
publishInfo.FormatOptions = req.PublishContext["formatOptions"]
11511152
publishInfo.FCPLunNumber = lunID
11521153
publishInfo.FCPLunSerial = req.PublishContext["fcpLunSerial"]
11531154
publishInfo.FCPIgroup = req.PublishContext["fcpIgroup"]
@@ -1158,6 +1159,22 @@ func (p *Plugin) nodeStageFCPVolume(
11581159
return err
11591160
}
11601161

1162+
volTrackingInfo := &models.VolumeTrackingInfo{
1163+
VolumePublishInfo: *publishInfo,
1164+
StagingTargetPath: stagingTargetPath,
1165+
PublishedPaths: map[string]struct{}{},
1166+
}
1167+
if err := p.nodeHelper.WriteTrackingInfo(ctx, volumeId, volTrackingInfo); err != nil {
1168+
Logc(ctx).WithFields(LogFields{
1169+
"volumeID": volumeId,
1170+
"stagingTargetPath": stagingTargetPath,
1171+
}).WithError(err).Error("Could not write tracking file.")
1172+
return err
1173+
}
1174+
1175+
if err := afterInitialTrackingInfoWrite.Inject(); err != nil {
1176+
return err
1177+
}
11611178
// In the case of a failed CSI NodeStageVolume call, CSI node clients may call NodeStageVolume or NodeUnstageVolume.
11621179
// To ensure Trident can handle a subsequent CSI NodeUnstageVolume call, Trident always writes a tracking file.
11631180
// This should result in Trident having all it needs to for CSI NodeUnstageVolume should an attachment fail.
@@ -1190,15 +1207,13 @@ func (p *Plugin) nodeStageFCPVolume(
11901207
}
11911208

11921209
if isLUKS {
1193-
var luksDevice luks.Device
1194-
luksDevice, err = luks.NewLUKSDeviceFromMappingPath(
1195-
ctx, p.command, publishInfo.DevicePath,
1196-
req.VolumeContext["internalName"],
1197-
)
1198-
if err != nil {
1210+
if err := betweenAttachAndLUKSPassphrase.Inject(); err != nil {
11991211
return err
12001212
}
12011213

1214+
var luksDevice luks.Device
1215+
luksDevice = luks.NewLUKSDevice(publishInfo.DevicePath, req.VolumeContext["internalName"], p.command)
1216+
12021217
// Ensure we update the passphrase in case it has never been set before
12031218
err = ensureLUKSVolumePassphrase(ctx, p.restClient, luksDevice, volumeId, req.GetSecrets(), true)
12041219
if err != nil {
@@ -1247,8 +1262,14 @@ func (p *Plugin) ensureAttachFCPVolume(
12471262
func (p *Plugin) nodeUnstageFCPVolume(
12481263
ctx context.Context, req *csi.NodeUnstageVolumeRequest, publishInfo *models.VolumePublishInfo, force bool,
12491264
) error {
1250-
deviceInfo, err := utils.GetDeviceInfoForFCPLUN(ctx, nil, int(publishInfo.FCPLunNumber), publishInfo.FCTargetWWNN,
1251-
false)
1265+
hostSessionMap := fcpUtils.GetFCPHostSessionMapForTarget(ctx, publishInfo.FCTargetWWNN)
1266+
if len(hostSessionMap) == 0 {
1267+
Logc(ctx).Debug("No host sessions found, nothing to do.")
1268+
return nil
1269+
}
1270+
1271+
deviceInfo, err := p.fcp.GetDeviceInfoForLUN(ctx, hostSessionMap, int(publishInfo.FCPLunNumber),
1272+
publishInfo.FCTargetWWNN, false)
12521273
if err != nil {
12531274
return fmt.Errorf("could not get device info: %v", err)
12541275
}
@@ -1259,48 +1280,52 @@ func (p *Plugin) nodeUnstageFCPVolume(
12591280
}
12601281

12611282
var luksMapperPath string
1262-
if convert.ToBool(publishInfo.LUKSEncryption) {
1263-
fields := LogFields{"luksDevicePath": publishInfo.DevicePath, "lunID": publishInfo.FCPLunNumber}
1264-
1265-
// Before closing the LUKS device, get the underlying mapper device from cryptsetup.
1266-
mapperPath, err := luks.GetUnderlyingDevicePathForLUKSDevice(ctx, p.command, publishInfo.DevicePath)
1267-
if err != nil {
1268-
// No need to return an error
1269-
Logc(ctx).WithFields(fields).WithError(err).Error("Could not determine underlying device for LUKS.")
1283+
// If the multipath device is not present, the LUKS device should not exist.
1284+
if convert.ToBool(publishInfo.LUKSEncryption) && deviceInfo.MultipathDevice != "" {
1285+
fields := LogFields{
1286+
"luksDevicePath": publishInfo.DevicePath,
1287+
"lunID": publishInfo.FCPLunNumber,
1288+
"multipathDevice": deviceInfo.MultipathDevice,
12701289
}
1271-
fields["mapperPath"] = mapperPath
12721290

1273-
err = p.devices.EnsureLUKSDeviceClosedWithMaxWaitLimit(ctx, publishInfo.DevicePath)
1291+
luksMapperPath, err = p.devices.GetLUKSDeviceForMultipathDevice(deviceInfo.MultipathDevice)
12741292
if err != nil {
1275-
if errors.IsMaxWaitExceededError(err) {
1276-
Logc(ctx).WithFields(LogFields{
1277-
"devicePath": publishInfo.DevicePath,
1278-
"lun": publishInfo.FCPLunNumber,
1279-
"err": err,
1280-
}).Debug("LUKS close wait time exceeded, continuing with device removal.")
1281-
} else {
1293+
if !errors.IsNotFoundError(err) {
1294+
Logc(ctx).WithFields(fields).
1295+
WithError(err).Error("Failed to get LUKS device path from multipath device.")
12821296
return err
12831297
}
1298+
Logc(ctx).WithFields(fields).Info("No LUKS device path found from multipath device.")
12841299
}
12851300

1286-
// Get the underlying device mapper device for the block device used by LUKS.
1287-
dmDevicePath, err := utils.GetDMDeviceForMapperPath(ctx, mapperPath)
1288-
if err != nil {
1289-
Logc(ctx).WithFields(fields).WithError(err).Error("Failed to determine dm device from device mapper.")
1301+
// Ensure the LUKS device is closed if the luksMapperPath is set.
1302+
if luksMapperPath != "" {
1303+
1304+
fields["mapperPath"] = luksMapperPath
1305+
err = p.devices.EnsureLUKSDeviceClosedWithMaxWaitLimit(ctx, luksMapperPath)
1306+
if err != nil {
1307+
if !errors.IsMaxWaitExceededError(err) {
1308+
Logc(ctx).WithFields(fields).WithError(err).Error("Failed to close LUKS device.")
1309+
return err
1310+
}
1311+
Logc(ctx).WithFields(fields).WithError(err).
1312+
Debug("LUKS close wait time exceeded continuing with device removal.")
1313+
}
12901314
}
12911315

1292-
luksMapperPath = publishInfo.DevicePath
1293-
// Save device mapper path to publishInfo for the subsequent removal steps.
1294-
publishInfo.DevicePath = dmDevicePath
1316+
// Set device path to dm device to correctly verify legacy volumes.
1317+
if luks.IsLegacyLUKSDevicePath(publishInfo.DevicePath) {
1318+
publishInfo.DevicePath = deviceInfo.MultipathDevice
1319+
}
12951320
}
12961321

12971322
// Delete the device from the host.
1298-
unmappedMpathDevice, err := p.iscsi.PrepareDeviceForRemoval(ctx, deviceInfo, publishInfo, nil, p.unsafeDetach,
1323+
unmappedMpathDevice, err := p.fcp.PrepareDeviceForRemoval(ctx, deviceInfo, publishInfo, nil, p.unsafeDetach,
12991324
force)
13001325
if err != nil {
13011326
if errors.IsFCPSameLunNumberError(err) {
13021327
// There is a need to pass all the publish infos this time
1303-
unmappedMpathDevice, err = p.iscsi.PrepareDeviceForRemoval(ctx, deviceInfo, publishInfo,
1328+
unmappedMpathDevice, err = p.fcp.PrepareDeviceForRemoval(ctx, deviceInfo, publishInfo,
13041329
p.readAllTrackingFiles(ctx),
13051330
p.unsafeDetach, force)
13061331
}
@@ -1337,11 +1362,12 @@ func (p *Plugin) nodeUnstageFCPVolume(
13371362
}).WithError(err).Warning("Unable to remove LUKS mapper device.")
13381363
}
13391364
// Clear the time duration for the LUKS device.
1340-
delete(devices.LuksCloseDurations, luksMapperPath)
1365+
devices.LuksCloseDurations.RemoveDurationTracking(luksMapperPath)
13411366
}
13421367

13431368
// If there is multipath device, flush(remove) mappings
1344-
if err := p.devices.RemoveMultipathDeviceMapping(ctx, unmappedMpathDevice); err != nil {
1369+
if err := p.devices.RemoveMultipathDeviceMappingWithRetries(ctx, unmappedMpathDevice,
1370+
removeMultipathDeviceMappingRetries, removeMultipathDeviceMappingRetryDelay); err != nil {
13451371
return err
13461372
}
13471373

@@ -1361,8 +1387,7 @@ func (p *Plugin) nodeUnstageFCPVolumeRetry(
13611387
}
13621388

13631389
nodeUnstageFCPVolumeAttempt := func() error {
1364-
return p.
1365-
nodeUnstageFCPVolume(ctx, req, publishInfo, force)
1390+
return p.nodeUnstageFCPVolume(ctx, req, publishInfo, force)
13661391
}
13671392

13681393
nodeUnstageFCPVolumeBackoff := backoff.NewExponentialBackOff()
@@ -1401,17 +1426,30 @@ func (p *Plugin) nodePublishFCPVolume(
14011426
publishInfo.MountOptions = collection.AppendToStringList(publishInfo.MountOptions, "ro", ",")
14021427
}
14031428

1429+
devicePath := publishInfo.DevicePath
14041430
if convert.ToBool(publishInfo.LUKSEncryption) {
14051431
// Rotate the LUKS passphrase if needed, on failure, log and continue to publish
1406-
luksDevice, err := luks.NewLUKSDeviceFromMappingPath(ctx, p.command, publishInfo.DevicePath,
1407-
req.VolumeContext["internalName"])
1408-
if err != nil {
1409-
return nil, status.Error(codes.Internal, err.Error())
1432+
1433+
var luksDevice luks.Device
1434+
if luks.IsLegacyLUKSDevicePath(devicePath) {
1435+
// Supports legacy volumes that store the LUKS device path
1436+
luksDevice, err = luks.NewLUKSDeviceFromMappingPath(
1437+
ctx, p.command, devicePath, req.VolumeContext["internalName"],
1438+
)
1439+
if err != nil {
1440+
return nil, status.Error(codes.Internal, err.Error())
1441+
}
1442+
} else {
1443+
luksDevice = luks.NewLUKSDevice(publishInfo.DevicePath, req.VolumeContext["internalName"], p.command)
14101444
}
1445+
14111446
err = ensureLUKSVolumePassphrase(ctx, p.restClient, luksDevice, req.GetVolumeId(), req.GetSecrets(), false)
14121447
if err != nil {
14131448
Logc(ctx).WithError(err).Error("Failed to ensure current LUKS passphrase.")
14141449
}
1450+
1451+
// Mount LUKS device instead of mpath.
1452+
devicePath = luksDevice.MappedDevicePath()
14151453
}
14161454

14171455
if publishInfo.FilesystemType == filesystem.Raw {
@@ -1423,13 +1461,13 @@ func (p *Plugin) nodePublishFCPVolume(
14231461
}
14241462

14251463
// Place the block device at the target path for the raw-block.
1426-
err = p.mount.MountDevice(ctx, publishInfo.DevicePath, req.TargetPath, publishInfo.MountOptions, true)
1464+
err = p.mount.MountDevice(ctx, devicePath, req.TargetPath, publishInfo.MountOptions, true)
14271465
if err != nil {
14281466
return nil, status.Errorf(codes.Internal, "unable to bind mount raw device; %s", err)
14291467
}
14301468
} else {
14311469
// Mount the device.
1432-
err = p.mount.MountDevice(ctx, publishInfo.DevicePath, req.TargetPath, publishInfo.MountOptions, false)
1470+
err = p.mount.MountDevice(ctx, devicePath, req.TargetPath, publishInfo.MountOptions, false)
14331471
if err != nil {
14341472
return nil, status.Errorf(codes.Internal, "unable to mount device; %s", err)
14351473
}
@@ -2313,7 +2351,8 @@ func (p *Plugin) performISCSISelfHealing(ctx context.Context) {
23132351
}
23142352

23152353
if err := utils.PopulateCurrentSessions(ctx, &currentISCSISessions); err != nil {
2316-
Logc(ctx).WithError(err).Error("Failed to get current state of iSCSI Sessions LUN mappings; skipping iSCSI self-heal cycle.")
2354+
Logc(ctx).WithError(err).
2355+
Error("Failed to get current state of iSCSI Sessions LUN mappings; skipping iSCSI self-heal cycle.")
23172356
return
23182357
}
23192358

mocks/mock_utils/mock_fcp/mock_fcp_client.go

Lines changed: 2 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

storage_drivers/common.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,7 @@ func RemoveSCSIDeviceByPublishInfo(ctx context.Context, publishInfo *tridentmode
382382
return
383383
}
384384

385-
deviceInfo, err := utils.GetDeviceInfoForFCPLUN(ctx, nil, int(publishInfo.FCPLunNumber),
385+
deviceInfo, err := utils.GetDeviceInfoForFCPLUN(ctx, hostSessionMap, int(publishInfo.FCPLunNumber),
386386
publishInfo.FCTargetWWNN, false)
387387
if err != nil {
388388
Logc(ctx).WithError(err).WithFields(fields).Error("Error getting device info.")

utils/adaptors.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,9 @@ func GetDeviceInfoForLUN(
1717
}
1818

1919
func GetDeviceInfoForFCPLUN(
20-
ctx context.Context, hostSessionMap map[int]int, lunID int, iSCSINodeName string, isDetachCall bool,
20+
ctx context.Context, hostSessionMap []map[string]int, lunID int, iSCSINodeName string, isDetachCall bool,
2121
) (*models.ScsiDeviceInfo, error) {
22-
// TODO: check if we require both isDetachCall and needFSType
23-
deviceInfo, err := fcpClient.GetDeviceInfoForLUN(ctx, lunID, iSCSINodeName, false, isDetachCall)
22+
deviceInfo, err := fcpClient.GetDeviceInfoForLUN(ctx, hostSessionMap, lunID, iSCSINodeName, false)
2423
if err != nil {
2524
return nil, err
2625
}

0 commit comments

Comments
 (0)