Skip to content

Commit 8c77737

Browse files
authored
Enable concurrent support for SolidFire SAN driver
* First pass * fix review comment * Remove JIRA ref * Fix review comments * Fix goimports lint
1 parent 53befce commit 8c77737

3 files changed

Lines changed: 90 additions & 12 deletions

File tree

config/config.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,7 @@ var (
444444
"google-cloud-netapp-volumes",
445445
"ontap-nas-economy",
446446
"ontap-san-economy",
447+
"solidfire-san",
447448
}
448449

449450
// Absolute max age for ANY TAGRI (safety net to prevent stuck states) before forced deletion

storage_drivers/solidfire/solidfire_san.go

Lines changed: 84 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"regexp"
1313
"strconv"
1414
"strings"
15+
"sync"
1516

1617
"github.com/RoaringBitmap/roaring/v2"
1718
"github.com/google/uuid"
@@ -66,6 +67,16 @@ type SANStorageDriver struct {
6667
iscsiClient iscsi.Client
6768

6869
virtualPools map[string]storage.Pool
70+
71+
// mutex serializes mutating storage.Driver entrypoints (Create, Clone, Destroy,
72+
// Publish, Resize, snapshot ops, etc.) and any method that issues SolidFire API
73+
// calls. It is the former TridentOrchestrator.mutex pushed down into the driver.
74+
//
75+
// Read-only accessors that only touch fields written once during Initialize
76+
// (Name, GetConfig, GetProtocol, GetInternalVolumeName, etc.) intentionally do
77+
// not take the lock. Given SolidFire's maintenance status, fine-grained locking
78+
// is not warranted.
79+
mutex sync.Mutex
6980
}
7081

7182
type Telemetry struct {
@@ -101,12 +112,12 @@ func parseType(ctx context.Context, vTypes []api.VolType, typeName string) (qos
101112
return qos, err
102113
}
103114

104-
func (d SANStorageDriver) getTelemetry() *Telemetry {
115+
func (d *SANStorageDriver) getTelemetry() *Telemetry {
105116
return d.telemetry
106117
}
107118

108119
// Name is for returning the name of this driver
109-
func (d SANStorageDriver) Name() string {
120+
func (d *SANStorageDriver) Name() string {
110121
return tridentconfig.SolidfireSANStorageDriverName
111122
}
112123

@@ -140,6 +151,9 @@ func (d *SANStorageDriver) Initialize(
140151
ctx context.Context, context tridentconfig.DriverContext, configJSON string,
141152
commonConfig *drivers.CommonStorageDriverConfig, backendSecret map[string]string, backendUUID string,
142153
) error {
154+
d.mutex.Lock()
155+
defer d.mutex.Unlock()
156+
143157
fields := LogFields{"Method": "Initialize", "Type": "SANStorageDriver"}
144158
Logd(ctx, commonConfig.StorageDriverName,
145159
commonConfig.DebugTraceFlags["method"]).WithFields(fields).Trace(">>>> Initialize")
@@ -335,6 +349,9 @@ func (d *SANStorageDriver) Initialized() bool {
335349
}
336350

337351
func (d *SANStorageDriver) Terminate(ctx context.Context, _ string) {
352+
d.mutex.Lock()
353+
defer d.mutex.Unlock()
354+
338355
fields := LogFields{"Method": "Terminate", "Type": "SANStorageDriver"}
339356
Logd(ctx, d.Name(), d.Config.DebugTraceFlags["method"]).WithFields(fields).Trace(">>>> Terminate")
340357
defer Logd(ctx, d.Name(), d.Config.DebugTraceFlags["method"]).WithFields(fields).Trace("<<<< Terminate")
@@ -795,6 +812,9 @@ func (d *SANStorageDriver) Create(
795812
ctx context.Context, volConfig *storage.VolumeConfig, storagePool storage.Pool,
796813
volAttributes map[string]sa.Request,
797814
) error {
815+
d.mutex.Lock()
816+
defer d.mutex.Unlock()
817+
798818
name := volConfig.InternalName
799819

800820
fields := LogFields{
@@ -944,6 +964,9 @@ func (d *SANStorageDriver) Create(
944964
func (d *SANStorageDriver) CreateClone(
945965
ctx context.Context, _, cloneVolConfig *storage.VolumeConfig, storagePool storage.Pool,
946966
) error {
967+
d.mutex.Lock()
968+
defer d.mutex.Unlock()
969+
947970
name := cloneVolConfig.InternalName
948971
sourceName := cloneVolConfig.CloneSourceVolumeInternal
949972
snapshotName := cloneVolConfig.CloneSourceSnapshotInternal
@@ -1087,6 +1110,9 @@ func (d *SANStorageDriver) CreateClone(
10871110
}
10881111

10891112
func (d *SANStorageDriver) Import(ctx context.Context, volConfig *storage.VolumeConfig, originalName string) error {
1113+
d.mutex.Lock()
1114+
defer d.mutex.Unlock()
1115+
10901116
fields := LogFields{
10911117
"Method": "Import",
10921118
"Type": "SANStorageDriver",
@@ -1153,6 +1179,9 @@ func (d *SANStorageDriver) detachVolume(ctx context.Context, v api.Volume) error
11531179

11541180
// Destroy the requested docker volume
11551181
func (d *SANStorageDriver) Destroy(ctx context.Context, volConfig *storage.VolumeConfig) error {
1182+
d.mutex.Lock()
1183+
defer d.mutex.Unlock()
1184+
11561185
name := volConfig.InternalName
11571186

11581187
fields := LogFields{
@@ -1206,6 +1235,9 @@ func (d *SANStorageDriver) Destroy(ctx context.Context, volConfig *storage.Volum
12061235
func (d *SANStorageDriver) Publish(
12071236
ctx context.Context, volConfig *storage.VolumeConfig, publishInfo *models.VolumePublishInfo,
12081237
) error {
1238+
d.mutex.Lock()
1239+
defer d.mutex.Unlock()
1240+
12091241
name := volConfig.InternalName
12101242

12111243
fields := LogFields{
@@ -1268,6 +1300,9 @@ func (d *SANStorageDriver) CanSnapshot(_ context.Context, _ *storage.SnapshotCon
12681300
func (d *SANStorageDriver) GetSnapshot(
12691301
ctx context.Context, snapConfig *storage.SnapshotConfig, _ *storage.VolumeConfig,
12701302
) (*storage.Snapshot, error) {
1303+
d.mutex.Lock()
1304+
defer d.mutex.Unlock()
1305+
12711306
internalSnapName := snapConfig.InternalName
12721307
internalVolName := snapConfig.VolumeInternalName
12731308

@@ -1324,6 +1359,9 @@ func (d *SANStorageDriver) GetSnapshot(
13241359
func (d *SANStorageDriver) GetSnapshots(ctx context.Context, volConfig *storage.VolumeConfig) (
13251360
[]*storage.Snapshot, error,
13261361
) {
1362+
d.mutex.Lock()
1363+
defer d.mutex.Unlock()
1364+
13271365
internalVolName := volConfig.InternalName
13281366

13291367
fields := LogFields{
@@ -1378,6 +1416,9 @@ func (d *SANStorageDriver) GetSnapshots(ctx context.Context, volConfig *storage.
13781416
func (d *SANStorageDriver) CreateSnapshot(
13791417
ctx context.Context, snapConfig *storage.SnapshotConfig, _ *storage.VolumeConfig,
13801418
) (*storage.Snapshot, error) {
1419+
d.mutex.Lock()
1420+
defer d.mutex.Unlock()
1421+
13811422
internalSnapName := snapConfig.InternalName
13821423
internalVolName := snapConfig.VolumeInternalName
13831424

@@ -1426,6 +1467,9 @@ func (d *SANStorageDriver) CreateSnapshot(
14261467
func (d *SANStorageDriver) RestoreSnapshot(
14271468
ctx context.Context, snapConfig *storage.SnapshotConfig, _ *storage.VolumeConfig,
14281469
) error {
1470+
d.mutex.Lock()
1471+
defer d.mutex.Unlock()
1472+
14291473
internalSnapName := snapConfig.InternalName
14301474
internalVolName := snapConfig.VolumeInternalName
14311475

@@ -1469,6 +1513,9 @@ func (d *SANStorageDriver) RestoreSnapshot(
14691513
func (d *SANStorageDriver) DeleteSnapshot(
14701514
ctx context.Context, snapConfig *storage.SnapshotConfig, _ *storage.VolumeConfig,
14711515
) error {
1516+
d.mutex.Lock()
1517+
defer d.mutex.Unlock()
1518+
14721519
internalSnapName := snapConfig.InternalName
14731520
internalVolName := snapConfig.VolumeInternalName
14741521

@@ -1501,6 +1548,9 @@ func (d *SANStorageDriver) DeleteSnapshot(
15011548

15021549
// Get tests for the existence of a volume
15031550
func (d *SANStorageDriver) Get(ctx context.Context, volConfig *storage.VolumeConfig) error {
1551+
d.mutex.Lock()
1552+
defer d.mutex.Unlock()
1553+
15041554
name := volConfig.InternalName
15051555
fields := LogFields{"Method": "Get", "Type": "SANStorageDriver"}
15061556
Logd(ctx, d.Name(), d.Config.DebugTraceFlags["method"]).WithFields(fields).Trace(">>>> Get")
@@ -1605,6 +1655,9 @@ func (d *SANStorageDriver) VolumeExists(ctx context.Context, name string) (bool,
16051655

16061656
// GetStorageBackendSpecs retrieves storage backend capabilities
16071657
func (d *SANStorageDriver) GetStorageBackendSpecs(_ context.Context, backend storage.Backend) error {
1658+
d.mutex.Lock()
1659+
defer d.mutex.Unlock()
1660+
16081661
backend.SetName(d.BackendName())
16091662

16101663
virtual := len(d.virtualPools) > 0
@@ -1674,6 +1727,9 @@ func (d *SANStorageDriver) CreatePrepare(ctx context.Context, volConfig *storage
16741727
}
16751728

16761729
func (d *SANStorageDriver) CreateFollowup(ctx context.Context, volConfig *storage.VolumeConfig) error {
1730+
d.mutex.Lock()
1731+
defer d.mutex.Unlock()
1732+
16771733
fields := LogFields{
16781734
"Method": "CreateFollowup",
16791735
"Type": "SANStorageDriver",
@@ -1842,7 +1898,13 @@ func (d *SANStorageDriver) AddMissingVolumesToVag(ctx context.Context, vagID int
18421898
req.StartVAGID = vagID
18431899
req.Limit = 1
18441900

1845-
vags, _ := d.Client.ListVolumeAccessGroups(ctx, &req)
1901+
vags, err := d.Client.ListVolumeAccessGroups(ctx, &req)
1902+
if err != nil {
1903+
return fmt.Errorf("failed to list volume access groups: %v", err)
1904+
}
1905+
if len(vags) == 0 {
1906+
return fmt.Errorf("volume access group %d not found", vagID)
1907+
}
18461908
missingVolIDs := diffSlices(vags[0].Volumes, vols)
18471909

18481910
var addReq api.AddVolumesToVolumeAccessGroupRequest
@@ -1857,6 +1919,9 @@ func (d *SANStorageDriver) AddMissingVolumesToVag(ctx context.Context, vagID int
18571919
// representation of the volume. For this driver, volumeID is the name of the
18581920
// LUN on the storage system.
18591921
func (d *SANStorageDriver) GetVolumeForImport(ctx context.Context, volumeID string) (*storage.VolumeExternal, error) {
1922+
d.mutex.Lock()
1923+
defer d.mutex.Unlock()
1924+
18601925
volume, err := d.GetVolume(ctx, volumeID)
18611926
if err != nil {
18621927
return nil, err
@@ -1866,12 +1931,12 @@ func (d *SANStorageDriver) GetVolumeForImport(ctx context.Context, volumeID stri
18661931
}
18671932

18681933
// String implements stringer interface for the SANStorageDriver driver
1869-
func (d SANStorageDriver) String() string {
1870-
return convert.ToStringRedacted(&d, []string{"Client", "AccountID"}, d.GetExternalConfig(context.Background()))
1934+
func (d *SANStorageDriver) String() string {
1935+
return convert.ToStringRedacted(d, []string{"Client", "AccountID"}, d.GetExternalConfig(context.Background()))
18711936
}
18721937

18731938
// GoString implements GoStringer interface for the SANStorageDriver driver
1874-
func (d SANStorageDriver) GoString() string {
1939+
func (d *SANStorageDriver) GoString() string {
18751940
return d.String()
18761941
}
18771942

@@ -1880,6 +1945,9 @@ func (d SANStorageDriver) GoString() string {
18801945
// representation of each volume to the supplied channel, closing the channel
18811946
// when finished.
18821947
func (d *SANStorageDriver) GetVolumeExternalWrappers(ctx context.Context, channel chan *storage.VolumeExternalWrapper) {
1948+
d.mutex.Lock()
1949+
defer d.mutex.Unlock()
1950+
18831951
// Let the caller know we're done by closing the channel
18841952
defer close(channel)
18851953

@@ -1962,6 +2030,9 @@ func (d *SANStorageDriver) GetUpdateType(ctx context.Context, driverOrig storage
19622030

19632031
// Resize expands the volume size.
19642032
func (d *SANStorageDriver) Resize(ctx context.Context, volConfig *storage.VolumeConfig, sizeBytes uint64) error {
2033+
d.mutex.Lock()
2034+
defer d.mutex.Unlock()
2035+
19652036
name := volConfig.InternalName
19662037
fields := LogFields{
19672038
"Method": "Resize",
@@ -2042,6 +2113,9 @@ func (d *SANStorageDriver) Resize(ctx context.Context, volConfig *storage.Volume
20422113
func (d *SANStorageDriver) ReconcileNodeAccess(
20432114
ctx context.Context, nodes []*models.Node, _, _ string,
20442115
) error {
2116+
d.mutex.Lock()
2117+
defer d.mutex.Unlock()
2118+
20452119
nodeNames := make([]string, 0)
20462120
for _, node := range nodes {
20472121
nodeNames = append(nodeNames, node.Name)
@@ -2059,6 +2133,9 @@ func (d *SANStorageDriver) ReconcileNodeAccess(
20592133
}
20602134

20612135
func (d *SANStorageDriver) ReconcileVolumeNodeAccess(ctx context.Context, _ *storage.VolumeConfig, _ []*models.Node) error {
2136+
d.mutex.Lock()
2137+
defer d.mutex.Unlock()
2138+
20622139
fields := LogFields{
20632140
"Method": "ReconcileVolumeNodeAccess",
20642141
"Type": "SANStorageDriver",
@@ -2070,6 +2147,6 @@ func (d *SANStorageDriver) ReconcileVolumeNodeAccess(ctx context.Context, _ *sto
20702147
}
20712148

20722149
// GetCommonConfig returns driver's CommonConfig
2073-
func (d SANStorageDriver) GetCommonConfig(context.Context) *drivers.CommonStorageDriverConfig {
2150+
func (d *SANStorageDriver) GetCommonConfig(context.Context) *drivers.CommonStorageDriverConfig {
20742151
return d.Config.CommonStorageDriverConfig
20752152
}

storage_drivers/solidfire/solidfire_san_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,20 +90,20 @@ func newTestSolidfireSANDriver() *SANStorageDriver {
9090
return sanDriver
9191
}
9292

93-
func callString(s SANStorageDriver) string {
93+
func callString(s *SANStorageDriver) string {
9494
return s.String()
9595
}
9696

97-
func callGoString(s SANStorageDriver) string {
97+
func callGoString(s *SANStorageDriver) string {
9898
return s.GoString()
9999
}
100100

101101
func TestSolidfireSANStorageDriverConfigString(t *testing.T) {
102-
solidfireSANDrivers := []SANStorageDriver{
103-
*newTestSolidfireSANDriver(),
102+
solidfireSANDrivers := []*SANStorageDriver{
103+
newTestSolidfireSANDriver(),
104104
}
105105

106-
for _, toString := range []func(SANStorageDriver) string{callString, callGoString} {
106+
for _, toString := range []func(*SANStorageDriver) string{callString, callGoString} {
107107
for _, solidfireSANDriver := range solidfireSANDrivers {
108108
assert.Contains(t, toString(solidfireSANDriver), "<REDACTED>",
109109
"Solidfire driver does not contain <REDACTED>")

0 commit comments

Comments
 (0)