@@ -70,9 +70,9 @@ public class OntapPrimaryDatastoreDriver implements PrimaryDataStoreDriver {
7070 public Map <String , String > getCapabilities () {
7171 s_logger .trace ("OntapPrimaryDatastoreDriver: getCapabilities: Called" );
7272 Map <String , String > mapCapabilities = new HashMap <>();
73-
74- mapCapabilities .put (DataStoreCapabilities .STORAGE_SYSTEM_SNAPSHOT .toString (), Boolean .TRUE .toString ());
75- mapCapabilities .put (DataStoreCapabilities .CAN_CREATE_VOLUME_FROM_SNAPSHOT .toString (), Boolean .TRUE .toString ());
73+ // RAW managed initial implementation: snapshot features not yet supported
74+ mapCapabilities .put (DataStoreCapabilities .STORAGE_SYSTEM_SNAPSHOT .toString (), Boolean .FALSE .toString ());
75+ mapCapabilities .put (DataStoreCapabilities .CAN_CREATE_VOLUME_FROM_SNAPSHOT .toString (), Boolean .FALSE .toString ());
7676
7777 return mapCapabilities ;
7878 }
@@ -130,36 +130,26 @@ private String createCloudStackVolumeForTypeVolume(DataStore dataStore, DataObje
130130 throw new CloudRuntimeException ("createCloudStackVolume : Storage Pool not found for id: " + dataStore .getId ());
131131 }
132132 Map <String , String > details = storagePoolDetailsDao .listDetailsKeyPairs (dataStore .getId ());
133+
134+ // For iSCSI and other protocols, use ONTAP REST API
135+ StorageStrategy storageStrategy = getStrategyByStoragePoolDetails (details );
133136 // For managed NFS: Use flat structure (no subdirectories) like other managed storage providers
134137 // KVM expects volumes to be in the root of the NFS mount with unique names
135138 if (ProtocolType .NFS .name ().equalsIgnoreCase (details .get (Constants .PROTOCOL ))) {
136139 VolumeVO volume = volumeDao .findById (((VolumeInfo ) dataObject ).getId ());
137- // CRITICAL: Set poolType at VOLUME level
138- // This tells KVM to use LibvirtStorageAdaptor (NFS) instead of IscsiAdmStorageAdaptor
139140 volume .setPoolType (Storage .StoragePoolType .NetworkFilesystem );
140- // Use UUID only (KVM's default behavior for managed NFS)
141- // KVM's getPhysicalDisk() is hardcoded to use UUID, not custom paths
142141 String volumeUuid = ((VolumeInfo ) dataObject ).getUuid ();
143- // Set path to UUID (KVM will use this)
144- volume .setPath (volumeUuid );
145- volume .setFolder ("" ); // No folder for flat structure
142+ CloudStackVolume cloudStackVolumeRequest = Utility .createCloudStackVolumeRequestByProtocol (storagePool , details , (VolumeInfo ) dataObject );
143+ CloudStackVolume created = storageStrategy .createCloudStackVolume (cloudStackVolumeRequest );
144+ String rawFileName = created .getCloudstackVolName (); // <uuid>.raw
145+ volume .setPath (rawFileName );
146+ volume .setFormat (Storage .ImageFormat .RAW );
146147 volume .setPoolId (dataStore .getId ());
147148 volumeDao .update (volume .getId (), volume );
148- s_logger .info ("=== ONTAP Managed NFS Volume (Flat Structure - UUID only) ===" );
149- s_logger .info ("Volume Name: {}" , ((VolumeInfo ) dataObject ).getName ());
150- s_logger .info ("Volume UUID: {}" , volumeUuid );
151- s_logger .info ("Volume Path: {} (UUID-based, KVM default)" , volumeUuid );
152- s_logger .info ("Volume PoolType: {}" , volume .getPoolType ());
153- s_logger .info ("Returning null - hypervisor will create: /mnt/<pool>/{}.qcow2" , volumeUuid );
154- s_logger .info ("Note: KVM's LibvirtStoragePool.getPhysicalDisk() is hardcoded to use UUID" );
155- s_logger .info ("================================================" );
156- // CRITICAL: Return null to tell CloudStack to trigger KVM volume creation!
157- // If we return a path, CloudStack thinks volume is already created and skips KVM
158- // This causes DATA volumes to never be created
159- return null ;
149+ s_logger .info ("ONTAP RAW managed NFS volume created: uuid={} path={} format=RAW" , volumeUuid , rawFileName );
150+ return rawFileName ;
160151 }
161- // For iSCSI and other protocols, use ONTAP REST API
162- StorageStrategy storageStrategy = getStrategyByStoragePoolDetails (details );
152+
163153 s_logger .info ("createCloudStackVolumeForTypeVolume: Connection to Ontap SVM [{}] successful, preparing CloudStackVolumeRequest" , details .get (Constants .SVM_NAME ));
164154 CloudStackVolume cloudStackVolumeRequest = Utility .createCloudStackVolumeRequestByProtocol (storagePool , details , (VolumeInfo ) dataObject );
165155 CloudStackVolume cloudStackVolume = storageStrategy .createCloudStackVolume (cloudStackVolumeRequest );
@@ -174,7 +164,34 @@ private String createCloudStackVolumeForTypeVolume(DataStore dataStore, DataObje
174164
175165 @ Override
176166 public void deleteAsync (DataStore store , DataObject data , AsyncCompletionCallback <CommandResult > callback ) {
177-
167+ CommandResult commandResult = new CommandResult ();
168+ try {
169+ if (store == null || data == null ) {
170+ throw new CloudRuntimeException ("deleteAsync: store or data is null" );
171+ }
172+ if (data .getType () == DataObjectType .VOLUME ) {
173+ StoragePoolVO storagePool = storagePoolDao .findById (store .getId ());
174+ Map <String , String > details = storagePoolDetailsDao .listDetailsKeyPairs (store .getId ());
175+ if (ProtocolType .NFS .name ().equalsIgnoreCase (details .get (Constants .PROTOCOL ))) {
176+ VolumeVO volume = volumeDao .findById (data .getId ());
177+ if (volume != null && volume .getPath () != null ) {
178+ StorageStrategy strategy = getStrategyByStoragePoolDetails (details );
179+ if (strategy instanceof org .apache .cloudstack .storage .service .UnifiedNASStrategy ) {
180+ boolean deleted = ((org .apache .cloudstack .storage .service .UnifiedNASStrategy ) strategy )
181+ .deleteManagedFile (details .get (Constants .VOLUME_UUID ), volume .getPath ());
182+ if (!deleted ) {
183+ throw new CloudRuntimeException ("Failed to delete RAW file " + volume .getPath ());
184+ }
185+ s_logger .info ("Deleted RAW managed file {} for volume id {}" , volume .getPath (), volume .getId ());
186+ }
187+ }
188+ }
189+ }
190+ } catch (Exception e ) {
191+ commandResult .setResult (e .getMessage ());
192+ } finally {
193+ callback .complete (commandResult );
194+ }
178195 }
179196
180197 @ Override
@@ -248,7 +265,7 @@ public void handleQualityOfServiceForVolumeMigration(VolumeInfo volumeInfo, Qual
248265
249266 @ Override
250267 public boolean canProvideStorageStats () {
251- return true ;
268+ return false ;
252269 }
253270
254271 @ Override
@@ -258,7 +275,7 @@ public Pair<Long, Long> getStorageStats(StoragePool storagePool) {
258275
259276 @ Override
260277 public boolean canProvideVolumeStats () {
261- return true ;
278+ return false ; // Not yet implemented for RAW managed NFS
262279 }
263280
264281 @ Override
0 commit comments