CSTACKEX-212: fix for snapshot failure for attached cs volumes nfs an…#77
Conversation
There was a problem hiding this comment.
Pull request overview
Fixes snapshot failures for ONTAP-backed volumes that are created-and-attached to running VMs in a single step by ensuring the volume’s image format is set consistently (KVM → QCOW2) during ONTAP volume creation.
Changes:
- Set
VolumeVO.formatduringcreateAsync()for both iSCSI and NFS3 ONTAP-managed volumes based on the pool hypervisor. - Add unit-test stubbing for
StoragePool.getHypervisor()to support the new format-resolution logic.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/driver/OntapPrimaryDatastoreDriver.java | Set volume format during creation and add hypervisor→image-format resolution helper. |
| plugins/storage/volume/ontap/src/test/java/org/apache/cloudstack/storage/driver/OntapPrimaryDatastoreDriverTest.java | Update tests to provide pool hypervisor needed by the new format-setting logic. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
sandeeplocharla
left a comment
There was a problem hiding this comment.
Awesome work!!!
8856437
| 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; |
| HypervisorType hyperType = storagePool.getHypervisor(); | ||
| ImageFormat format = getSupportedImageFormatForHypervisor(hyperType); | ||
| if (format != null) { |
| private ImageFormat getSupportedImageFormatForHypervisor(HypervisorType hyperType) { | ||
| 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; | ||
| } |
sandeeplocharla
left a comment
There was a problem hiding this comment.
'DefaultPrimary' plugin currently supports multiple hypervisors and storage protocols. It has snapshot capabilities for a long time. Can you check if even it has the same issue as our plugin and if these changes fix it?
If it works without these changes, maybe we need to understand how its handling it.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (1)
plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/driver/OntapPrimaryDatastoreDriver.java:1014
- getImageFormatByHypervisor can throw a NullPointerException when storagePool.getHypervisor() returns null because it calls hypervisorType.equals(...). Since StoragePoolVO.getHypervisor() can be null, this can break volume creation with an NPE instead of a controlled failure. Guard against null and compare enums with == (or call equals on the constant).
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");
suryag1201
left a comment
There was a problem hiding this comment.
also add assertion to check the format is set or not after createAsync
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (1)
plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/driver/OntapPrimaryDatastoreDriver.java:1015
- getImageFormatByHypervisor uses hypervisorType.equals(...), which will throw a NullPointerException if StoragePool.getHypervisor() returns null. Since this method is used during createAsync, that would fail volume creation with an unhelpful NPE. Prefer enum-safe comparisons (==) and explicitly handle null with a clearer exception message.
if (hypervisorType.equals(HypervisorType.KVM)) {
return Storage.ImageFormat.QCOW2;
}
throw new CloudRuntimeException("Unsupported hypervisor [" + hypervisorType + "] for ONTAP image format resolution");
}
| 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()); |
Description
Fix snapshot failure for CloudStack volumes attached to running VMs on ONTAP primary storage (both NFS3 and iSCSI protocols).
This PR...
When a volume was created and attached to a running VM in a single step,by enabling create on storage and choose the storage pool tag the volume format was not being set correctly. The format is now determined by the hypervisor type (KVM → QCOW2) in ontapdriver via [getImageFormatByHypervisor(HypervisorType] mirroring the [getSupportedImageFormatForCluster] in VolumeOrchestrator file.
Types of changes
Feature/Enhancement Scale or Bug Severity
Feature/Enhancement Scale
Bug Severity
How Has This Been Tested?
Tested on a dev setup against these scenarios:
Scenario A — Attach data disk to running VM, then snapshot
Scenario B — Attach volume to root-disk-only VM, then snapshot
scenarios-C-create a volume on storage pool but not attach to any vm
Screenshots (if appropriate):
snapshots for when cs volume is attached to NFS and ISCSI instance that has both root and data disk and create on storage enabled:


verifying on ontap and db:



snapshots for when cs volume is attached to NFS and ISCSI instance that has only root and also case when they are not attached to any instance and create on storage enabled:


How did you try to break this feature and the system with this change?