Skip to content

Commit 928f419

Browse files
authored
fix san economy snapshot issue with name template
1 parent c3415c1 commit 928f419

3 files changed

Lines changed: 436 additions & 93 deletions

File tree

storage_drivers/ontap/ontap_san_economy.go

Lines changed: 53 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -96,11 +96,15 @@ func (o *LUNHelper) GetSnapPath(bucketName, internalVolName, snapName string) st
9696
return snapPath
9797
}
9898

99-
// parameter: volName=my-Vol
100-
// output: /vol/*/storagePrefix_my_Vol_snapshot_*
101-
func (o *LUNHelper) GetSnapPathPatternForVolume(externalVolumeName string) string {
102-
externalVolumeName = strings.ReplaceAll(externalVolumeName, "-", "_")
103-
snapPattern := fmt.Sprintf("/vol/*/*%v"+snapshotNameSeparator+"*", externalVolumeName)
99+
// GetSnapPathPatternForVolume returns a LUN path pattern matching every snap-LUN of the volume whose LUN is named
100+
// internalVolumeName. The internal name must be used here because it is the only name that appears in ONTAP; a
101+
// pattern built from the external (Kubernetes) volume name matches nothing when the backend assigns internal names
102+
// from a nameTemplate.
103+
// parameter: internalVolumeName=my-Lun
104+
// output: /vol/*/my_Lun_snapshot_*
105+
func (o *LUNHelper) GetSnapPathPatternForVolume(internalVolumeName string) string {
106+
internalVolumeName = strings.ReplaceAll(internalVolumeName, "-", "_")
107+
snapPattern := fmt.Sprintf("/vol/*/%v"+snapshotNameSeparator+"*", internalVolumeName)
104108
return snapPattern
105109
}
106110

@@ -180,6 +184,23 @@ func (o *LUNHelper) GetSnapshotNameFromSnapLUNPath(snapLunPath string) string {
180184
return ""
181185
}
182186

187+
// GetSnapshotNameForVolume returns the snapshot name encoded in a snap-LUN path belonging to the volume whose LUN is
188+
// named internalVolumeName, or "" if the path is not a snap-LUN of that volume. Unlike
189+
// GetSnapshotNameFromSnapLUNPath, this does not assume the LUN name begins with the configured storage prefix, so
190+
// it also works for volumes whose internal names come from a nameTemplate.
191+
// parameters: snapLunPath=/vol/myBucket/storagePrefix_myLun_snapshot_mySnap internalVolumeName=storagePrefix_myLun
192+
// output: mySnap
193+
func (o *LUNHelper) GetSnapshotNameForVolume(snapLunPath, internalVolumeName string) string {
194+
snapLunName := o.GetInternalVolumeNameFromPath(snapLunPath)
195+
snapLunPrefix := strings.ReplaceAll(internalVolumeName, "-", "_") + snapshotNameSeparator
196+
197+
if internalVolumeName == "" || !strings.HasPrefix(snapLunName, snapLunPrefix) {
198+
return ""
199+
}
200+
201+
return strings.TrimPrefix(snapLunName, snapLunPrefix)
202+
}
203+
183204
// parameter: snapLunPath=/vol/myBucket/storagePrefix_myLun_snapshot_mySnap
184205
// result [2] is the volume name: myLun
185206
func (o *LUNHelper) GetExternalVolumeNameFromPath(lunPath string) string {
@@ -1247,8 +1268,7 @@ func (d *SANEconomyStorageDriver) Destroy(ctx context.Context, volConfig *storag
12471268

12481269
// Before deleting the LUN, check if a LUN has associated snapshots. If so, delete all associated snapshots
12491270
// Note: DeleteSnapshot acquires its own FlexVol lock, so we don't hold the lock here
1250-
externalVolumeName := d.helper.GetExternalVolumeNameFromPath(lunPathEco)
1251-
snapList, err := d.getSnapshotsEconomy(ctx, name, externalVolumeName)
1271+
snapList, err := d.getSnapshotsEconomy(ctx, name, volConfig.Name)
12521272
if err != nil {
12531273
Logc(ctx).WithError(err).Error("Error enumerating snapshots.")
12541274
return deleteError
@@ -1722,7 +1742,7 @@ func (d *SANEconomyStorageDriver) getSnapshotsEconomy(
17221742
Logd(ctx, d.Name(), d.Config.DebugTraceFlags["method"]).WithFields(fields).Trace(">>>> getSnapshotsEconomy")
17231743
defer Logd(ctx, d.Name(), d.Config.DebugTraceFlags["method"]).WithFields(fields).Trace("<<<< getSnapshotsEconomy")
17241744

1725-
snapPathPattern := d.helper.GetSnapPathPatternForVolume(externalVolumeName)
1745+
snapPathPattern := d.helper.GetSnapPathPatternForVolume(internalVolumeName)
17261746

17271747
snapList, err := d.API.LunList(ctx, snapPathPattern)
17281748
if err != nil {
@@ -1739,9 +1759,8 @@ func (d *SANEconomyStorageDriver) getSnapshotsEconomy(
17391759
if err != nil {
17401760
return nil, fmt.Errorf("%v is an invalid volume size: %w", snap.Size, err)
17411761
}
1742-
// Check to see if it has the following string pattern. If so, add to snapshot List. Else, skip.
1743-
if d.helper.IsValidSnapLUNPath(snapLunPath) {
1744-
snapLunName := d.helper.GetSnapshotNameFromSnapLUNPath(snapLunPath)
1762+
// Only LUNs that are snapshots of this volume belong in the list; skip anything else.
1763+
if snapLunName := d.helper.GetSnapshotNameForVolume(snapLunPath, internalVolumeName); snapLunName != "" {
17451764
snapshot := &storage.Snapshot{
17461765
Config: &storage.SnapshotConfig{
17471766
Version: tridentconfig.OrchestratorAPIVersion,
@@ -1809,31 +1828,34 @@ func (d *SANEconomyStorageDriver) CreateSnapshot(
18091828
return nil, fmt.Errorf("could not create snapshot: %w", err)
18101829
}
18111830

1812-
// Fetching list of snapshots to get snapshot creation time
1813-
snapListResponse, err := d.getSnapshotsEconomy(ctx, internalVolumeName, snapConfig.VolumeName)
1831+
// Read the new snap-LUN back by its exact path to get the snapshot creation time. The snap-LUN is a clone of
1832+
// the source LUN and therefore lives in the source LUN's Flexvol, so it is addressable directly and must not
1833+
// be searched for by name pattern: only one of the snap-LUNs a pattern returns is the one just created.
1834+
snapLunInfo, err := d.API.LunGetByName(ctx, GetLUNPathEconomy(bucketVol, lunName))
18141835
if err != nil {
1815-
return nil, fmt.Errorf("error enumerating snapshots: %w", err)
1836+
return nil, fmt.Errorf("could not find snapshot %s for source volume %s: %w",
1837+
internalSnapName, internalVolumeName, err)
1838+
}
1839+
if snapLunInfo == nil {
1840+
return nil, fmt.Errorf("could not find snapshot %s for source volume %s", internalSnapName, internalVolumeName)
18161841
}
18171842

1818-
for _, snap := range snapListResponse {
1819-
Logc(ctx).WithFields(LogFields{
1820-
"snapshotName": snapConfig.InternalName,
1821-
"volumeName": snapConfig.VolumeInternalName,
1822-
}).Info("Snapshot created.")
1843+
sizeBytes, err := convert.ToPositiveInt64(size)
1844+
if err != nil {
1845+
return nil, fmt.Errorf("error %v is an invalid volume size: %w", size, err)
1846+
}
18231847

1824-
sizeBytes, err := convert.ToPositiveInt64(size)
1825-
if err != nil {
1826-
return nil, fmt.Errorf("error %v is an invalid volume size: %w", size, err)
1827-
}
1848+
Logc(ctx).WithFields(LogFields{
1849+
"snapshotName": snapConfig.InternalName,
1850+
"volumeName": snapConfig.VolumeInternalName,
1851+
}).Info("Snapshot created.")
18281852

1829-
return &storage.Snapshot{
1830-
Config: snapConfig,
1831-
Created: snap.Created,
1832-
SizeBytes: sizeBytes,
1833-
State: storage.SnapshotStateOnline,
1834-
}, nil
1835-
}
1836-
return nil, fmt.Errorf("could not find snapshot %s for source volume %s", internalSnapName, internalVolumeName)
1853+
return &storage.Snapshot{
1854+
Config: snapConfig,
1855+
Created: snapLunInfo.CreateTime,
1856+
SizeBytes: sizeBytes,
1857+
State: storage.SnapshotStateOnline,
1858+
}, nil
18371859
}
18381860

18391861
// RestoreSnapshot restores a volume (in place) from a snapshot.

storage_drivers/ontap/ontap_san_economy_flexvol_autosize_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,7 @@ func TestDestroy_PreDeleteSizingUnderFlexvolLock(t *testing.T) {
446446
internalName := "storagePrefix_vol1"
447447
lunPath := GetLUNPathEconomy(bucketVol, internalName)
448448
helper := driver.helper
449-
snapPattern := helper.GetSnapPathPatternForVolume(helper.GetExternalVolumeNameFromPath(lunPath))
449+
snapPattern := helper.GetSnapPathPatternForVolume(internalName)
450450

451451
mainLun := economyLun(testEcoDeletedLunBytes, "lun_"+internalName)
452452
mainLun.VolumeName = bucketVol

0 commit comments

Comments
 (0)