Skip to content

Commit 33fa90d

Browse files
authored
Node restart idempotency
Handle node cleanup upon a node restart for ontap-san/iSCSI
1 parent 5650bb0 commit 33fa90d

File tree

4 files changed

+39
-17
lines changed

4 files changed

+39
-17
lines changed

frontend/csi/node_server.go

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1940,16 +1940,15 @@ func (p *Plugin) nodeUnstageISCSIVolume(
19401940
Logc(ctx).WithError(err).Debug("Could not find devices.")
19411941
return fmt.Errorf("could not get device info: %v", err)
19421942
} else if deviceInfo == nil {
1943-
Logc(ctx).Debug("Could not find devices, nothing to do.")
1944-
return nil
1943+
Logc(ctx).Debug("No devices found.")
19451944
}
19461945

19471946
// Remove Portal/LUN entries in self-healing map.
19481947
p.iscsi.RemoveLUNFromSessions(ctx, publishInfo, &publishedISCSISessions)
19491948

19501949
var luksMapperPath string
19511950
// If the multipath device is not present, the LUKS device should not exist.
1952-
if convert.ToBool(publishInfo.LUKSEncryption) && deviceInfo.MultipathDevice != "" {
1951+
if convert.ToBool(publishInfo.LUKSEncryption) && deviceInfo != nil && deviceInfo.MultipathDevice != "" {
19531952
fields := LogFields{
19541953
"lunID": publishInfo.IscsiLunNumber,
19551954
"publishedDevice": publishInfo.DevicePath,
@@ -1985,18 +1984,21 @@ func (p *Plugin) nodeUnstageISCSIVolume(
19851984
}
19861985

19871986
// Delete the device from the host.
1988-
unmappedMpathDevice, err := p.iscsi.PrepareDeviceForRemoval(ctx, deviceInfo, publishInfo, nil, p.unsafeDetach,
1989-
force)
1990-
if err != nil {
1991-
if errors.IsISCSISameLunNumberError(err) {
1992-
// There is a need to pass all the publish infos this time
1993-
unmappedMpathDevice, err = p.iscsi.PrepareDeviceForRemoval(ctx, deviceInfo, publishInfo,
1994-
p.readAllTrackingFiles(ctx),
1995-
p.unsafeDetach, force)
1996-
}
1987+
var unmappedMpathDevice string
1988+
if deviceInfo != nil {
1989+
unmappedMpathDevice, err = p.iscsi.PrepareDeviceForRemoval(ctx, deviceInfo, publishInfo, nil, p.unsafeDetach,
1990+
force)
1991+
if err != nil {
1992+
if errors.IsISCSISameLunNumberError(err) {
1993+
// There is a need to pass all the publish infos this time
1994+
unmappedMpathDevice, err = p.iscsi.PrepareDeviceForRemoval(ctx, deviceInfo, publishInfo,
1995+
p.readAllTrackingFiles(ctx),
1996+
p.unsafeDetach, force)
1997+
}
19971998

1998-
if err != nil && !p.unsafeDetach {
1999-
return status.Error(codes.Internal, err.Error())
1999+
if err != nil && !p.unsafeDetach {
2000+
return status.Error(codes.Internal, err.Error())
2001+
}
20002002
}
20012003
}
20022004

frontend/csi/node_server_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2379,12 +2379,30 @@ func TestNodeUnstageISCSIVolume(t *testing.T) {
23792379
mockISCSIClient := mock_iscsi.NewMockISCSI(gomock.NewController(t))
23802380
mockISCSIClient.EXPECT().GetDeviceInfoForLUN(gomock.Any(), gomock.Any(),
23812381
gomock.Any(), gomock.Any(), false).Return(nil, nil)
2382+
mockISCSIClient.EXPECT().RemoveLUNFromSessions(gomock.Any(), gomock.Any(), gomock.Any())
2383+
mockISCSIClient.EXPECT().TargetHasMountedDevice(gomock.Any(),
2384+
"iqn.1992-08.com.netapp:sn.a0e6b50f49e611efa8b5005056b33c0d:vs.2").Return(false, nil)
2385+
mockISCSIClient.EXPECT().SafeToLogOut(gomock.Any(), 6, 3).Return(true)
2386+
mockISCSIClient.EXPECT().RemovePortalsFromSession(gomock.Any(), gomock.Any(), gomock.Any())
2387+
mockISCSIClient.EXPECT().Logout(gomock.Any(), gomock.Any(), gomock.Any())
23822388
return mockISCSIClient
23832389
},
2390+
getMountClient: func() mount.Mount {
2391+
mockMountClient := mock_mount.NewMockMount(gomock.NewController(t))
2392+
mockMountClient.EXPECT().UmountAndRemoveTemporaryMountPoint(gomock.Any(), gomock.Any()).Return(nil)
2393+
return mockMountClient
2394+
},
23842395
getDeviceClient: func() devices.Devices {
23852396
mockDeviceClient := mock_devices.NewMockDevices(gomock.NewController(t))
2397+
mockDeviceClient.EXPECT().RemoveMultipathDeviceMappingWithRetries(gomock.Any(), gomock.Any(),
2398+
gomock.Any(), gomock.Any()).Return(nil)
23862399
return mockDeviceClient
23872400
},
2401+
getNodeHelper: func() nodehelpers.NodeHelper {
2402+
mockNodeHelper := mockNodeHelpers.NewMockNodeHelper(gomock.NewController(t))
2403+
mockNodeHelper.EXPECT().DeleteTrackingInfo(gomock.Any(), gomock.Any()).Return(nil)
2404+
return mockNodeHelper
2405+
},
23882406
},
23892407
"SAN: iSCSI unstage: GetDeviceInfoForLUN error": {
23902408
assertError: assert.Error,

utils/iscsi/iscsi.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -796,7 +796,9 @@ func (client *Client) GetDeviceInfoForLUN(
796796
if err != nil {
797797
return nil, err
798798
} else if len(devicesForLUN) == 0 {
799-
return nil, fmt.Errorf("scan not completed for LUN %d on target %s", lunID, iSCSINodeName)
799+
// No devices found may be due to a node reboot
800+
Logc(ctx).WithFields(fields).Info("No devices found for LUN.")
801+
return nil, nil
800802
}
801803

802804
multipathDevice := ""

utils/iscsi/iscsi_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2997,7 +2997,7 @@ func TestClient_getDeviceInfoForLUN(t *testing.T) {
29972997
getFileSystemUtils: func() afero.Fs {
29982998
return afero.NewMemMapFs()
29992999
},
3000-
assertError: assert.Error,
3000+
assertError: assert.NoError,
30013001
expectedDeviceInfo: nil,
30023002
},
30033003
"error getting devices for LUN": {
@@ -3035,7 +3035,7 @@ func TestClient_getDeviceInfoForLUN(t *testing.T) {
30353035
getFileSystemUtils: func() afero.Fs {
30363036
return afero.NewMemMapFs()
30373037
},
3038-
assertError: assert.Error,
3038+
assertError: assert.NoError,
30393039
expectedDeviceInfo: nil,
30403040
},
30413041
"no multipath device found": {

0 commit comments

Comments
 (0)