@@ -130,47 +130,34 @@ 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- // For managed NFS: create subdirectory on ONTAP for volume isolation
134- // Use readable name combining volume name and UUID for subdirectory
133+ // For managed NFS: Use flat structure (no subdirectories) like other managed storage providers
134+ // KVM expects volumes to be in the root of the NFS mount with unique names
135135 if (ProtocolType .NFS .name ().equalsIgnoreCase (details .get (Constants .PROTOCOL ))) {
136- StorageStrategy storageStrategy = getStrategyByStoragePoolDetails (details );
137- String volumeName = ((VolumeInfo ) dataObject ).getName ();
138- String volumeUuid = ((VolumeInfo ) dataObject ).getUuid ();
139- // Create readable subdirectory name: "ROOT-17_5d11c615-3142-494c-ac48-96517adbecff"
140- String readableSubdirName = volumeName + "_" + volumeUuid ;
141- s_logger .info ("createCloudStackVolumeForTypeVolume: NFS - Creating subdirectory on ONTAP: {}" , readableSubdirName );
142- CloudStackVolume cloudStackVolumeRequest = Utility .createCloudStackVolumeRequestByProtocol (storagePool , details , (VolumeInfo ) dataObject );
143- CloudStackVolume cloudStackVolume = storageStrategy .createCloudStackVolume (cloudStackVolumeRequest ); // Creates subdirectory on ONTAP
144- String subdirectoryName = cloudStackVolume .getFile ().getPath ();
145- // Store metadata in CloudStack database
146136 VolumeVO volume = volumeDao .findById (((VolumeInfo ) dataObject ).getId ());
147137 // CRITICAL: Set poolType at VOLUME level
148138 // This tells KVM to use LibvirtStorageAdaptor (NFS) instead of IscsiAdmStorageAdaptor
149139 volume .setPoolType (Storage .StoragePoolType .NetworkFilesystem );
150- // For managed NFS with subdirectories, point to file INSIDE the subdirectory
151- // Path format: subdirectory/uuid (e.g., ROOT-20_85969d09.../85969d09...)
152- String volumePath = subdirectoryName + "/" + volumeUuid ;
153- volume .setPath (volumePath );
154- // CRITICAL FIX: Also update the volume NAME to the full path
155- // This is what KVM LibvirtStorageAdaptor uses when creating the physical disk
156- // Without this, KVM uses just the original volume name (ROOT-20) instead of the path
157- volume .setName (volumePath );
158- // Set _iScsiName to subdirectory path for managed storage tracking
159- volume .set_iScsiName (subdirectoryName );
160- volume .setFolder (volumeUuid ); // Store UUID in folder field
140+ // Use unique volume name combining CloudStack volume name and UUID
141+ // This creates a unique filename directly in NFS root (flat structure)
142+ String volumeName = ((VolumeInfo ) dataObject ).getName ();
143+ String volumeUuid = ((VolumeInfo ) dataObject ).getUuid ();
144+ String uniqueVolumeName = volumeName + "_" + volumeUuid ;
145+ // For managed NFS, set the volume name to the unique name
146+ // KVM will create qcow2 file directly in NFS root: /mnt/pool/ROOT-21_uuid.qcow2
147+ volume .setName (uniqueVolumeName );
148+ volume .setPath (uniqueVolumeName );
149+ volume .setFolder (volumeUuid ); // Store UUID for reference
161150 volume .setPoolId (dataStore .getId ());
162151 volumeDao .update (volume .getId (), volume );
163- // Re-read from database to verify the changes
164- VolumeVO updatedVolume = volumeDao .findById (volume .getId ());
165- s_logger .info ("=== ONTAP NFS Volume Configuration ===" );
166- s_logger .info ("Subdirectory created: {}" , subdirectoryName );
167- s_logger .info ("Volume Name: {} (THIS IS WHAT KVM USES)" , updatedVolume .getName ());
168- s_logger .info ("Volume Path: {}" , updatedVolume .getPath ());
169- s_logger .info ("Volume _iScsiName: {}" , updatedVolume .get_iScsiName ());
170- s_logger .info ("Volume Folder: {}" , updatedVolume .getFolder ());
171- s_logger .info ("Volume PoolType: {}" , updatedVolume .getPoolType ());
172- s_logger .info ("======================================" );
173- return null ; // Return null - hypervisor will create qcow2 file inside subdirectory
152+ s_logger .info ("=== ONTAP Managed NFS Volume (Flat Structure) ===" );
153+ s_logger .info ("Volume Name: {} (used by KVM for file creation)" , uniqueVolumeName );
154+ s_logger .info ("Volume Path: {}" , volume .getPath ());
155+ s_logger .info ("Volume UUID: {}" , volumeUuid );
156+ s_logger .info ("Volume PoolType: {}" , volume .getPoolType ());
157+ s_logger .info ("Hypervisor will create: /mnt/<pool>/{}.qcow2" , uniqueVolumeName );
158+ s_logger .info ("================================================" );
159+ // Return null - let hypervisor create the qcow2 file directly in NFS root
160+ return null ;
174161 }
175162 // For iSCSI and other protocols, use ONTAP REST API
176163 StorageStrategy storageStrategy = getStrategyByStoragePoolDetails (details );
0 commit comments