2929import com .cloud .storage .Volume ;
3030import com .cloud .storage .VolumeVO ;
3131import com .cloud .storage .ScopeType ;
32- import com .cloud .storage .dao .SnapshotDetailsDao ;
33- import com .cloud .storage .dao .SnapshotDetailsVO ;
3432import com .cloud .storage .dao .VolumeDao ;
3533import com .cloud .storage .dao .VolumeDetailsDao ;
3634import com .cloud .utils .Pair ;
4947import org .apache .cloudstack .engine .subsystem .api .storage .VolumeInfo ;
5048import org .apache .cloudstack .framework .async .AsyncCompletionCallback ;
5149import org .apache .cloudstack .storage .command .CommandResult ;
52- import org .apache .cloudstack .storage .command .CreateObjectAnswer ;
5350import org .apache .cloudstack .storage .datastore .db .PrimaryDataStoreDao ;
5451import org .apache .cloudstack .storage .datastore .db .StoragePoolDetailsDao ;
5552import org .apache .cloudstack .storage .datastore .db .StoragePoolVO ;
56- import org .apache .cloudstack .storage .feign .model .FileInfo ;
5753import org .apache .cloudstack .storage .feign .model .Lun ;
5854import org .apache .cloudstack .storage .service .SANStrategy ;
5955import org .apache .cloudstack .storage .service .StorageStrategy ;
6056import org .apache .cloudstack .storage .service .UnifiedSANStrategy ;
6157import org .apache .cloudstack .storage .service .model .AccessGroup ;
6258import org .apache .cloudstack .storage .service .model .CloudStackVolume ;
6359import org .apache .cloudstack .storage .service .model .ProtocolType ;
64- import org .apache .cloudstack .storage .to .SnapshotObjectTO ;
6560import org .apache .cloudstack .storage .utils .Constants ;
6661import org .apache .cloudstack .storage .utils .Utility ;
67- import org .apache .commons .lang3 .StringUtils ;
6862import org .apache .logging .log4j .LogManager ;
6963import org .apache .logging .log4j .Logger ;
7064
@@ -86,16 +80,17 @@ public class OntapPrimaryDatastoreDriver implements PrimaryDataStoreDriver {
8680 @ Inject private VMInstanceDao vmDao ;
8781 @ Inject private VolumeDao volumeDao ;
8882 @ Inject private VolumeDetailsDao volumeDetailsDao ;
89- @ Inject private SnapshotDetailsDao snapshotDetailsDao ;
9083
9184 @ Override
9285 public Map <String , String > getCapabilities () {
9386 s_logger .trace ("OntapPrimaryDatastoreDriver: getCapabilities: Called" );
9487 Map <String , String > mapCapabilities = new HashMap <>();
95- // RAW managed initial implementation: snapshot features not yet supported
96- // TODO Set it to false once we start supporting snapshot feature
97- mapCapabilities .put (DataStoreCapabilities .STORAGE_SYSTEM_SNAPSHOT .toString (), Boolean .TRUE .toString ());
98- mapCapabilities .put (DataStoreCapabilities .CAN_CREATE_VOLUME_FROM_SNAPSHOT .toString (), Boolean .TRUE .toString ());
88+ // Snapshot operations are handled by OntapSnapshotStrategy (volume-level)
89+ // and OntapVMSnapshotStrategy (VM-level) using native ONTAP FlexVol snapshots.
90+ // These capabilities are set to FALSE so that StorageSystemSnapshotStrategy
91+ // does not attempt to handle ONTAP volumes through the driver path.
92+ mapCapabilities .put (DataStoreCapabilities .STORAGE_SYSTEM_SNAPSHOT .toString (), Boolean .FALSE .toString ());
93+ mapCapabilities .put (DataStoreCapabilities .CAN_CREATE_VOLUME_FROM_SNAPSHOT .toString (), Boolean .FALSE .toString ());
9994 return mapCapabilities ;
10095 }
10196
@@ -532,84 +527,15 @@ public long getUsedIops(StoragePool storagePool) {
532527
533528 @ Override
534529 public void takeSnapshot (SnapshotInfo snapshot , AsyncCompletionCallback <CreateCmdResult > callback ) {
535- s_logger .info ("takeSnapshot : entered with snapshot id: " + snapshot .getId () + " and name: " + snapshot .getName ());
536- CreateCmdResult result ;
537-
538- try {
539- VolumeInfo volumeInfo = snapshot .getBaseVolume ();
540-
541- VolumeVO volumeVO = volumeDao .findById (volumeInfo .getId ());
542- if (volumeVO == null ) {
543- throw new CloudRuntimeException ("takeSnapshot: VolumeVO not found for id: " + volumeInfo .getId ());
544- }
545-
546- /** we are keeping file path at volumeVO.getPath() */
547-
548- StoragePoolVO storagePool = storagePoolDao .findById (volumeVO .getPoolId ());
549- if (storagePool == null ) {
550- s_logger .error ("takeSnapshot : Storage Pool not found for id: " + volumeVO .getPoolId ());
551- throw new CloudRuntimeException ("takeSnapshot : Storage Pool not found for id: " + volumeVO .getPoolId ());
552- }
553- Map <String , String > poolDetails = storagePoolDetailsDao .listDetailsKeyPairs (volumeVO .getPoolId ());
554- StorageStrategy storageStrategy = Utility .getStrategyByStoragePoolDetails (poolDetails );
555-
556- CloudStackVolume cloudStackVolume = null ;
557- long usedBytes = getUsedBytes (storagePool );
558- long capacityBytes = storagePool .getCapacityBytes ();
559- long fileSize = 0l ;
560- // Only proceed for NFS3 protocol
561- if (ProtocolType .NFS3 .name ().equalsIgnoreCase (poolDetails .get (Constants .PROTOCOL ))) {
562- Map <String , String > cloudStackVolumeRequestMap = new HashMap <>();
563- cloudStackVolumeRequestMap .put (Constants .VOLUME_UUID , poolDetails .get (Constants .VOLUME_UUID ));
564- cloudStackVolumeRequestMap .put (Constants .FILE_PATH , volumeVO .getPath ());
565- cloudStackVolume = storageStrategy .getCloudStackVolume (cloudStackVolumeRequestMap );
566- if (cloudStackVolume == null || cloudStackVolume .getFile () == null ) {
567- throw new CloudRuntimeException ("Failed to get source file to take snapshot" );
568- }
569- s_logger .info ("takeSnapshot : entered after getting cloudstack volume with file path: " + cloudStackVolume .getFile ().getPath () + " and size: " + cloudStackVolume .getFile ().getSize ());
570- fileSize = cloudStackVolume .getFile ().getSize ();
571- usedBytes += fileSize ;
572- }
573-
574- if (usedBytes > capacityBytes ) {
575- throw new CloudRuntimeException ("Insufficient space remains in this primary storage to take a snapshot" );
576- }
577-
578- storagePool .setUsedBytes (usedBytes );
579-
580- SnapshotObjectTO snapshotObjectTo = (SnapshotObjectTO )snapshot .getTO ();
581-
582- String snapshotName = volumeInfo .getName () + "-" + snapshot .getUuid ();
583-
584- int trimRequired = snapshotName .length () - Constants .MAX_SNAPSHOT_NAME_LENGTH ;
585-
586- if (trimRequired > 0 ) {
587- snapshotName = StringUtils .left (volumeInfo .getName (), (volumeInfo .getName ().length () - trimRequired )) + "-" + snapshot .getUuid ();
588- }
589-
590- CloudStackVolume snapCloudStackVolumeRequest = snapshotCloudStackVolumeRequestByProtocol (poolDetails , volumeVO .getPath (), snapshotName );
591- CloudStackVolume cloneCloudStackVolume = storageStrategy .snapshotCloudStackVolume (snapCloudStackVolumeRequest );
592-
593- updateSnapshotDetails (snapshot .getId (), volumeInfo .getId (), poolDetails .get (Constants .VOLUME_UUID ), cloneCloudStackVolume .getFile ().getPath (), volumeVO .getPoolId (), fileSize );
594-
595- snapshotObjectTo .setPath (Constants .ONTAP_SNAP_ID +"=" +cloneCloudStackVolume .getFile ().getPath ());
596-
597- /** Update size for the storage-pool including snapshot size */
598- storagePoolDao .update (volumeVO .getPoolId (), storagePool );
599-
600- CreateObjectAnswer createObjectAnswer = new CreateObjectAnswer (snapshotObjectTo );
601-
602- result = new CreateCmdResult (null , createObjectAnswer );
603-
604- result .setResult (null );
605- }
606- catch (Exception ex ) {
607- s_logger .error ("takeSnapshot: Failed due to " , ex );
608- result = new CreateCmdResult (null , new CreateObjectAnswer (ex .toString ()));
609-
610- result .setResult (ex .toString ());
611- }
612-
530+ // Snapshot operations are now handled by OntapSnapshotStrategy which intercepts
531+ // at the strategy layer before the driver is ever called. This method should
532+ // not be reached for ONTAP volumes. If it is, fail explicitly.
533+ s_logger .error ("takeSnapshot: This driver method should not be called. " +
534+ "Snapshot operations for ONTAP are handled by OntapSnapshotStrategy. " +
535+ "Snapshot id: " + snapshot .getId ());
536+ CreateCmdResult result = new CreateCmdResult (null , new Answer (null , false ,
537+ "takeSnapshot not supported via driver path; use OntapSnapshotStrategy" ));
538+ result .setResult ("takeSnapshot not supported via driver path" );
613539 callback .complete (result );
614540 }
615541
@@ -709,60 +635,4 @@ private CloudStackVolume createDeleteCloudStackVolumeRequest(StoragePool storage
709635
710636 }
711637
712- private CloudStackVolume snapshotCloudStackVolumeRequestByProtocol (Map <String , String > details ,
713- String sourcePath ,
714- String destinationPath ) {
715- CloudStackVolume cloudStackVolumeRequest = null ;
716- ProtocolType protocolType = null ;
717- String protocol = null ;
718-
719- try {
720- protocol = details .get (Constants .PROTOCOL );
721- protocolType = ProtocolType .valueOf (protocol );
722- } catch (IllegalArgumentException e ) {
723- throw new CloudRuntimeException ("getCloudStackVolumeRequestByProtocol: Protocol: " + protocol +" is not valid" );
724- }
725- switch (protocolType ) {
726- case NFS3 :
727- cloudStackVolumeRequest = new CloudStackVolume ();
728- FileInfo fileInfo = new FileInfo ();
729- fileInfo .setPath (sourcePath );
730- cloudStackVolumeRequest .setFile (fileInfo );
731- String volumeUuid = details .get (Constants .VOLUME_UUID );
732- cloudStackVolumeRequest .setFlexVolumeUuid (volumeUuid );
733- cloudStackVolumeRequest .setDestinationPath (destinationPath );
734- break ;
735- default :
736- throw new CloudRuntimeException ("createCloudStackVolumeRequestByProtocol: Unsupported protocol " + protocol );
737-
738- }
739- return cloudStackVolumeRequest ;
740- }
741-
742- /**
743- *
744- * @param csSnapshotId: generated snapshot id from cloudstack
745- * @param csVolumeId: Source CS volume id
746- * @param ontapVolumeUuid: storage flexvolume id
747- * @param ontapNewSnapshot: generated snapshot id from ONTAP
748- * @param storagePoolId: primary storage pool id
749- * @param ontapSnapSize: Size of snapshot CS volume(LUN/file)
750- */
751- private void updateSnapshotDetails (long csSnapshotId , long csVolumeId , String ontapVolumeUuid , String ontapNewSnapshot , long storagePoolId , long ontapSnapSize ) {
752- SnapshotDetailsVO snapshotDetail = new SnapshotDetailsVO (csSnapshotId , Constants .SRC_CS_VOLUME_ID , String .valueOf (csVolumeId ), false );
753- snapshotDetailsDao .persist (snapshotDetail );
754-
755- snapshotDetail = new SnapshotDetailsVO (csSnapshotId , Constants .BASE_ONTAP_FV_ID , String .valueOf (ontapVolumeUuid ), false );
756- snapshotDetailsDao .persist (snapshotDetail );
757-
758- snapshotDetail = new SnapshotDetailsVO (csSnapshotId , Constants .ONTAP_SNAP_ID , String .valueOf (ontapNewSnapshot ), false );
759- snapshotDetailsDao .persist (snapshotDetail );
760-
761- snapshotDetail = new SnapshotDetailsVO (csSnapshotId , Constants .PRIMARY_POOL_ID , String .valueOf (storagePoolId ), false );
762- snapshotDetailsDao .persist (snapshotDetail );
763-
764- snapshotDetail = new SnapshotDetailsVO (csSnapshotId , Constants .ONTAP_SNAP_SIZE , String .valueOf (ontapSnapSize ), false );
765- snapshotDetailsDao .persist (snapshotDetail );
766- }
767-
768638}
0 commit comments