@@ -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
185206func (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.
0 commit comments