@@ -183,7 +183,7 @@ public void createAsync(DataStore dataStore, DataObject dataObject, AsyncComplet
183183 volumeDao .update (volumeVO .getId (), volumeVO );
184184 }
185185 } else if (dataObject .getType () == DataObjectType .SNAPSHOT ) {
186- // createTempVolume((SnapshotInfo)dataObject, dataStore.getId());
186+ createTempVolume ((SnapshotInfo )dataObject , dataStore .getId ());
187187 // No-op: ONTAP's takeSnapshot() already creates a LUN clone that is directly accessible.
188188 // The framework calls createAsync(SNAPSHOT) via createVolumeFromSnapshot/deleteVolumeFromSnapshot,
189189 // but ONTAP doesn't need a separate temp volume — the cloned LUN is used as-is.
@@ -208,18 +208,48 @@ public void createAsync(DataStore dataStore, DataObject dataObject, AsyncComplet
208208 }
209209
210210 private void createTempVolume (SnapshotInfo snapshotInfo , long storagePoolId ) {
211- s_logger .info ("createTempVolume: Creating temporary volume for snapshot [{}] in storage pool [{}]" , snapshotInfo .toString (), storagePoolId );
212- SnapshotDetailsVO snapshotDetails = snapshotDetailsDao .findDetail (snapshotInfo .getSnapshotId (), Constants .ONTAP_SNAP_ID );
211+ s_logger .info ("createTempVolume: Called for snapshot [{}] in storage pool [{}]" , snapshotInfo .getSnapshotId (), storagePoolId );
212+
213+ // The framework (StorageSystemDataMotionStrategy.handleSnapshotDetails) sets key "tempVolume"
214+ // with value "create" or "delete" — NOT Constants.ONTAP_SNAP_ID which holds the LUN UUID.
215+ String tempVolumeKey = "tempVolume" ;
216+ SnapshotDetailsVO snapshotDetails = snapshotDetailsDao .findDetail (snapshotInfo .getSnapshotId (), tempVolumeKey );
217+
213218 if (snapshotDetails == null || snapshotDetails .getValue () == null ) {
214- throw new CloudRuntimeException ("createTempVolume: invalid snapshot details for snapshot id: " + snapshotInfo .getSnapshotId ());
219+ s_logger .info ("createTempVolume: No '{}' detail found for snapshot [{}], nothing to do" , tempVolumeKey , snapshotInfo .getSnapshotId ());
220+ return ;
215221 }
216- Map <String , String > details = storagePoolDetailsDao .listDetailsKeyPairs (storagePoolId );
217- StorageStrategy storageStrategy = Utility .getStrategyByStoragePoolDetails (details );
218- VolumeInfo volumeInfo = snapshotInfo .getBaseVolume ();
219- VolumeVO volumeVO = volumeDao .findById (volumeInfo .getId ());
220222
221- if (snapshotDetails != null && snapshotDetails .getValue () != null && snapshotDetails .getValue ().equalsIgnoreCase (Constants .CREATE )) {
222- CloudStackVolume clonedCloudStackVolume = storageStrategy .getCloudStackVolume (getCloudStackVolumeRequestByProtocol (details , volumeVO ));
223+ String action = snapshotDetails .getValue ();
224+
225+ if (Constants .CREATE .equalsIgnoreCase (action )) {
226+ // ONTAP's takeSnapshot() already created a LUN clone that is directly accessible.
227+ // No additional temp volume creation is needed — the clone is used as-is.
228+ s_logger .info ("createTempVolume: 'create' signal — no-op for ONTAP (LUN clone already exists from takeSnapshot) for snapshot [{}]" ,
229+ snapshotInfo .getSnapshotId ());
230+ } else if (Constants .DELETE .equalsIgnoreCase (action )) {
231+ // Clean up: delete the cloned LUN and remove ONTAP-specific snapshot_details entries
232+ s_logger .info ("createTempVolume: 'delete' signal — cleaning up cloned LUN and snapshot details for snapshot [{}]" ,
233+ snapshotInfo .getSnapshotId ());
234+
235+ deleteSnapshotClone (snapshotInfo , snapshotInfo .getDataStore ());
236+
237+ // Remove ONTAP-specific details that were stored during takeSnapshot()
238+ removeSnapshotDetailIfPresent (snapshotInfo .getSnapshotId (), Constants .SRC_CS_VOLUME_ID );
239+ removeSnapshotDetailIfPresent (snapshotInfo .getSnapshotId (), Constants .BASE_ONTAP_FV_ID );
240+ removeSnapshotDetailIfPresent (snapshotInfo .getSnapshotId (), Constants .PRIMARY_POOL_ID );
241+ } else {
242+ s_logger .warn ("createTempVolume: Unexpected tempVolume value '{}' for snapshot [{}], ignoring" , action , snapshotInfo .getSnapshotId ());
243+ }
244+ }
245+
246+ /**
247+ * Safely removes a snapshot detail if it exists, avoiding NPE.
248+ */
249+ private void removeSnapshotDetailIfPresent (long snapshotId , String detailKey ) {
250+ SnapshotDetailsVO detail = snapshotDetailsDao .findDetail (snapshotId , detailKey );
251+ if (detail != null ) {
252+ snapshotDetailsDao .remove (detail .getId ());
223253 }
224254 }
225255
0 commit comments