From 1e71f85c24025ef4e14c57fa02a747da1694b4a2 Mon Sep 17 00:00:00 2001 From: sr73318 Date: Thu, 9 Jul 2026 21:22:24 +0530 Subject: [PATCH 1/5] CSTACKEX-212: fix for snapshot failure for attached cs volumes nfs and iscsi --- .../storage/driver/OntapPrimaryDatastoreDriver.java | 12 ++++++++++++ .../driver/OntapPrimaryDatastoreDriverTest.java | 3 +++ 2 files changed, 15 insertions(+) diff --git a/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/driver/OntapPrimaryDatastoreDriver.java b/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/driver/OntapPrimaryDatastoreDriver.java index 5e7a80b1af7c..4b4626c06e39 100644 --- a/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/driver/OntapPrimaryDatastoreDriver.java +++ b/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/driver/OntapPrimaryDatastoreDriver.java @@ -26,6 +26,7 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.host.Host; import com.cloud.host.HostVO; +import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.Storage; import com.cloud.storage.StoragePool; import com.cloud.storage.Volume; @@ -173,10 +174,15 @@ public void createAsync(DataStore dataStore, DataObject dataObject, AsyncComplet volumeVO.setFolder(created.getLun().getUuid()); } + volumeVO.setFormat(getImageFormatByHypervisor(storagePool.getHypervisor())); + logger.info("createAsync: Volume format set to [{}] for hypervisor [{}] and protocol [{}]", volumeVO.getFormat(), storagePool.getHypervisor(), details.get(OntapStorageConstants.PROTOCOL)); logger.info("createAsync: Created LUN [{}] for volume [{}]. LUN mapping will occur during grantAccess() to per-host igroup.", lunName, volumeVO.getId()); createCmdResult = new CreateCmdResult(lunName, new Answer(null, true, null)); } else if (ProtocolType.NFS3.name().equalsIgnoreCase(details.get(OntapStorageConstants.PROTOCOL))) { + + volumeVO.setFormat(getImageFormatByHypervisor(storagePool.getHypervisor())); + logger.info("createAsync: Volume format set to [{}] for hypervisor [{}] and protocol [{}]", volumeVO.getFormat(), storagePool.getHypervisor(), details.get(OntapStorageConstants.PROTOCOL)); createCmdResult = new CreateCmdResult(volInfo.getUuid(), new Answer(null, true, null)); logger.info("createAsync: Managed NFS volume [{}] with path [{}] associated with pool {}", volumeVO.getId(), volInfo.getUuid(), storagePool.getId()); @@ -1004,6 +1010,12 @@ private String buildSnapshotName(String cloudStackSnapshotName, long snapshotId) } + private Storage.ImageFormat getImageFormatByHypervisor(HypervisorType hypervisorType) { + if (hypervisorType == HypervisorType.KVM) { + return Storage.ImageFormat.QCOW2; + } + throw new CloudRuntimeException("Unsupported hypervisor [" + hypervisorType + "] for ONTAP image format resolution"); + } /** * Persists snapshot metadata in snapshot_details table. * diff --git a/plugins/storage/volume/ontap/src/test/java/org/apache/cloudstack/storage/driver/OntapPrimaryDatastoreDriverTest.java b/plugins/storage/volume/ontap/src/test/java/org/apache/cloudstack/storage/driver/OntapPrimaryDatastoreDriverTest.java index 571002df2a7f..00765a4fc6f0 100644 --- a/plugins/storage/volume/ontap/src/test/java/org/apache/cloudstack/storage/driver/OntapPrimaryDatastoreDriverTest.java +++ b/plugins/storage/volume/ontap/src/test/java/org/apache/cloudstack/storage/driver/OntapPrimaryDatastoreDriverTest.java @@ -21,6 +21,7 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.host.Host; import com.cloud.host.HostVO; +import com.cloud.hypervisor.Hypervisor; import com.cloud.storage.ScopeType; import com.cloud.storage.Storage; import com.cloud.storage.VolumeVO; @@ -167,6 +168,7 @@ void testCreateAsync_VolumeWithISCSI_Success() { when(storagePoolDao.findById(1L)).thenReturn(storagePool); when(storagePool.getId()).thenReturn(1L); when(storagePool.getPoolType()).thenReturn(Storage.StoragePoolType.NetworkFilesystem); + when(storagePool.getHypervisor()).thenReturn(Hypervisor.HypervisorType.KVM); when(storagePoolDetailsDao.listDetailsKeyPairs(1L)).thenReturn(storagePoolDetails); when(volumeDao.findById(100L)).thenReturn(volumeVO); @@ -220,6 +222,7 @@ void testCreateAsync_VolumeWithNFS_Success() { when(storagePoolDao.findById(1L)).thenReturn(storagePool); when(storagePool.getId()).thenReturn(1L); when(storagePool.getPoolType()).thenReturn(Storage.StoragePoolType.NetworkFilesystem); + when(storagePool.getHypervisor()).thenReturn(Hypervisor.HypervisorType.KVM); when(storagePoolDetailsDao.listDetailsKeyPairs(1L)).thenReturn(storagePoolDetails); when(volumeDao.findById(100L)).thenReturn(volumeVO); when(volumeVO.getId()).thenReturn(100L); From 88564377c7319766a41a1c4bab635c4e00a7da99 Mon Sep 17 00:00:00 2001 From: sr73318 Date: Fri, 10 Jul 2026 16:08:11 +0530 Subject: [PATCH 2/5] CSTACKEX-212: resolving comments --- .../storage/driver/OntapPrimaryDatastoreDriver.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/driver/OntapPrimaryDatastoreDriver.java b/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/driver/OntapPrimaryDatastoreDriver.java index 4b4626c06e39..94c1e517c6a3 100644 --- a/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/driver/OntapPrimaryDatastoreDriver.java +++ b/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/driver/OntapPrimaryDatastoreDriver.java @@ -160,6 +160,8 @@ public void createAsync(DataStore dataStore, DataObject dataObject, AsyncComplet volumeVO.setPoolType(storagePool.getPoolType()); volumeVO.setPoolId(storagePool.getId()); + volumeVO.setFormat(getImageFormatByHypervisor(storagePool.getHypervisor())); + logger.info("createAsync: Volume format set to [{}] for hypervisor [{}]", volumeVO.getFormat(), storagePool.getHypervisor()); if (ProtocolType.ISCSI.name().equalsIgnoreCase(details.get(OntapStorageConstants.PROTOCOL))) { String lunName = created != null && created.getLun() != null ? created.getLun().getName() : null; @@ -174,15 +176,11 @@ public void createAsync(DataStore dataStore, DataObject dataObject, AsyncComplet volumeVO.setFolder(created.getLun().getUuid()); } - volumeVO.setFormat(getImageFormatByHypervisor(storagePool.getHypervisor())); - logger.info("createAsync: Volume format set to [{}] for hypervisor [{}] and protocol [{}]", volumeVO.getFormat(), storagePool.getHypervisor(), details.get(OntapStorageConstants.PROTOCOL)); logger.info("createAsync: Created LUN [{}] for volume [{}]. LUN mapping will occur during grantAccess() to per-host igroup.", lunName, volumeVO.getId()); createCmdResult = new CreateCmdResult(lunName, new Answer(null, true, null)); } else if (ProtocolType.NFS3.name().equalsIgnoreCase(details.get(OntapStorageConstants.PROTOCOL))) { - volumeVO.setFormat(getImageFormatByHypervisor(storagePool.getHypervisor())); - logger.info("createAsync: Volume format set to [{}] for hypervisor [{}] and protocol [{}]", volumeVO.getFormat(), storagePool.getHypervisor(), details.get(OntapStorageConstants.PROTOCOL)); createCmdResult = new CreateCmdResult(volInfo.getUuid(), new Answer(null, true, null)); logger.info("createAsync: Managed NFS volume [{}] with path [{}] associated with pool {}", volumeVO.getId(), volInfo.getUuid(), storagePool.getId()); @@ -1011,7 +1009,7 @@ private String buildSnapshotName(String cloudStackSnapshotName, long snapshotId) private Storage.ImageFormat getImageFormatByHypervisor(HypervisorType hypervisorType) { - if (hypervisorType == HypervisorType.KVM) { + if (hypervisorType.equals(HypervisorType.KVM)) { return Storage.ImageFormat.QCOW2; } throw new CloudRuntimeException("Unsupported hypervisor [" + hypervisorType + "] for ONTAP image format resolution"); From 7c7f5a14c6c84723ad22f634553522b72818c968 Mon Sep 17 00:00:00 2001 From: sr73318 Date: Wed, 15 Jul 2026 00:36:40 +0530 Subject: [PATCH 3/5] CSTACKEX-212: format set in volumeapiserviceimpl instead of ontap driver --- .../driver/OntapPrimaryDatastoreDriver.java | 9 --------- .../driver/OntapPrimaryDatastoreDriverTest.java | 3 --- .../com/cloud/storage/VolumeApiServiceImpl.java | 17 ++++++++++++++++- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/driver/OntapPrimaryDatastoreDriver.java b/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/driver/OntapPrimaryDatastoreDriver.java index 94c1e517c6a3..1f2b834eb42c 100644 --- a/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/driver/OntapPrimaryDatastoreDriver.java +++ b/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/driver/OntapPrimaryDatastoreDriver.java @@ -26,7 +26,6 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.host.Host; import com.cloud.host.HostVO; -import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.Storage; import com.cloud.storage.StoragePool; import com.cloud.storage.Volume; @@ -160,8 +159,6 @@ public void createAsync(DataStore dataStore, DataObject dataObject, AsyncComplet volumeVO.setPoolType(storagePool.getPoolType()); volumeVO.setPoolId(storagePool.getId()); - volumeVO.setFormat(getImageFormatByHypervisor(storagePool.getHypervisor())); - logger.info("createAsync: Volume format set to [{}] for hypervisor [{}]", volumeVO.getFormat(), storagePool.getHypervisor()); if (ProtocolType.ISCSI.name().equalsIgnoreCase(details.get(OntapStorageConstants.PROTOCOL))) { String lunName = created != null && created.getLun() != null ? created.getLun().getName() : null; @@ -1008,12 +1005,6 @@ private String buildSnapshotName(String cloudStackSnapshotName, long snapshotId) } - private Storage.ImageFormat getImageFormatByHypervisor(HypervisorType hypervisorType) { - if (hypervisorType.equals(HypervisorType.KVM)) { - return Storage.ImageFormat.QCOW2; - } - throw new CloudRuntimeException("Unsupported hypervisor [" + hypervisorType + "] for ONTAP image format resolution"); - } /** * Persists snapshot metadata in snapshot_details table. * diff --git a/plugins/storage/volume/ontap/src/test/java/org/apache/cloudstack/storage/driver/OntapPrimaryDatastoreDriverTest.java b/plugins/storage/volume/ontap/src/test/java/org/apache/cloudstack/storage/driver/OntapPrimaryDatastoreDriverTest.java index 00765a4fc6f0..571002df2a7f 100644 --- a/plugins/storage/volume/ontap/src/test/java/org/apache/cloudstack/storage/driver/OntapPrimaryDatastoreDriverTest.java +++ b/plugins/storage/volume/ontap/src/test/java/org/apache/cloudstack/storage/driver/OntapPrimaryDatastoreDriverTest.java @@ -21,7 +21,6 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.host.Host; import com.cloud.host.HostVO; -import com.cloud.hypervisor.Hypervisor; import com.cloud.storage.ScopeType; import com.cloud.storage.Storage; import com.cloud.storage.VolumeVO; @@ -168,7 +167,6 @@ void testCreateAsync_VolumeWithISCSI_Success() { when(storagePoolDao.findById(1L)).thenReturn(storagePool); when(storagePool.getId()).thenReturn(1L); when(storagePool.getPoolType()).thenReturn(Storage.StoragePoolType.NetworkFilesystem); - when(storagePool.getHypervisor()).thenReturn(Hypervisor.HypervisorType.KVM); when(storagePoolDetailsDao.listDetailsKeyPairs(1L)).thenReturn(storagePoolDetails); when(volumeDao.findById(100L)).thenReturn(volumeVO); @@ -222,7 +220,6 @@ void testCreateAsync_VolumeWithNFS_Success() { when(storagePoolDao.findById(1L)).thenReturn(storagePool); when(storagePool.getId()).thenReturn(1L); when(storagePool.getPoolType()).thenReturn(Storage.StoragePoolType.NetworkFilesystem); - when(storagePool.getHypervisor()).thenReturn(Hypervisor.HypervisorType.KVM); when(storagePoolDetailsDao.listDetailsKeyPairs(1L)).thenReturn(storagePoolDetails); when(volumeDao.findById(100L)).thenReturn(volumeVO); when(volumeVO.getId()).thenReturn(100L); diff --git a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java index e24d862bb62f..b1f1e94869ac 100644 --- a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java @@ -1099,7 +1099,22 @@ private VolumeVO createVolumeOnStoragePool(Long volumeId, Long storageId) throws if (createVolumeResult.isFailed()) { throw new CloudRuntimeException("Volume creation on storage failed: " + createVolumeResult.getResult()); } - return _volsDao.findById(volumeInfo.getId()); + VolumeVO volVO = _volsDao.findById(volumeInfo.getId()); + if (volVO.getFormat() == null) { + HypervisorType hyperType = storagePool.getHypervisor(); + volVO.setFormat(getSupportedImageFormatForHypervisor(hyperType)); + } + _volsDao.update(volVO.getId(), volVO); + return volVO; + } + + private ImageFormat getSupportedImageFormatForHypervisor(HypervisorType hyperType) { + if (hyperType == HypervisorType.XenServer) return ImageFormat.VHD; + if (hyperType == HypervisorType.KVM) return ImageFormat.QCOW2; + if (hyperType == HypervisorType.VMware) return ImageFormat.OVA; + if (hyperType == HypervisorType.Ovm) return ImageFormat.RAW; + if (hyperType == HypervisorType.Hyperv) return ImageFormat.VHDX; + return null; } @Override From 7c7fa1230331d6f97a906af4fbb9d66e0c7303ad Mon Sep 17 00:00:00 2001 From: sr73318 Date: Wed, 15 Jul 2026 00:40:47 +0530 Subject: [PATCH 4/5] CSTACKEX-212: small fix --- .../cloudstack/storage/driver/OntapPrimaryDatastoreDriver.java | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/driver/OntapPrimaryDatastoreDriver.java b/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/driver/OntapPrimaryDatastoreDriver.java index 1f2b834eb42c..5e7a80b1af7c 100644 --- a/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/driver/OntapPrimaryDatastoreDriver.java +++ b/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/driver/OntapPrimaryDatastoreDriver.java @@ -177,7 +177,6 @@ public void createAsync(DataStore dataStore, DataObject dataObject, AsyncComplet lunName, volumeVO.getId()); createCmdResult = new CreateCmdResult(lunName, new Answer(null, true, null)); } else if (ProtocolType.NFS3.name().equalsIgnoreCase(details.get(OntapStorageConstants.PROTOCOL))) { - createCmdResult = new CreateCmdResult(volInfo.getUuid(), new Answer(null, true, null)); logger.info("createAsync: Managed NFS volume [{}] with path [{}] associated with pool {}", volumeVO.getId(), volInfo.getUuid(), storagePool.getId()); From 2561002477458b26d13c9ad976455cf42dba6845 Mon Sep 17 00:00:00 2001 From: sr73318 Date: Wed, 15 Jul 2026 01:40:35 +0530 Subject: [PATCH 5/5] CSTACKEX-212: resolving copilot comments --- .../cloud/storage/VolumeApiServiceImpl.java | 26 +++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java index b1f1e94869ac..92270e98912e 100644 --- a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java @@ -1102,19 +1102,29 @@ private VolumeVO createVolumeOnStoragePool(Long volumeId, Long storageId) throws VolumeVO volVO = _volsDao.findById(volumeInfo.getId()); if (volVO.getFormat() == null) { HypervisorType hyperType = storagePool.getHypervisor(); - volVO.setFormat(getSupportedImageFormatForHypervisor(hyperType)); + ImageFormat format = getSupportedImageFormatForHypervisor(hyperType); + if (format != null) { + volVO.setFormat(format); + _volsDao.update(volVO.getId(), volVO); + } } - _volsDao.update(volVO.getId(), volVO); return volVO; } private ImageFormat getSupportedImageFormatForHypervisor(HypervisorType hyperType) { - if (hyperType == HypervisorType.XenServer) return ImageFormat.VHD; - if (hyperType == HypervisorType.KVM) return ImageFormat.QCOW2; - if (hyperType == HypervisorType.VMware) return ImageFormat.OVA; - if (hyperType == HypervisorType.Ovm) return ImageFormat.RAW; - if (hyperType == HypervisorType.Hyperv) return ImageFormat.VHDX; - return null; + if (hyperType == HypervisorType.XenServer) { + return ImageFormat.VHD; + } else if (hyperType == HypervisorType.KVM) { + return ImageFormat.QCOW2; + } else if (hyperType == HypervisorType.VMware) { + return ImageFormat.OVA; + } else if (hyperType == HypervisorType.Ovm) { + return ImageFormat.RAW; + } else if (hyperType == HypervisorType.Hyperv) { + return ImageFormat.VHDX; + } else { + return null; + } } @Override