From 7b562550817d6d955d73218e4d3a4afa6b720e3d Mon Sep 17 00:00:00 2001 From: "Srivastava, Piyush" Date: Tue, 12 May 2026 19:55:53 +0530 Subject: [PATCH 1/3] bugfix/CSTACKEX-155: Fix cancel maintain for vm provisioning --- .../OntapPrimaryDatastoreLifecycle.java | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/lifecycle/OntapPrimaryDatastoreLifecycle.java b/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/lifecycle/OntapPrimaryDatastoreLifecycle.java index b055dad425a8..070c77805bd7 100755 --- a/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/lifecycle/OntapPrimaryDatastoreLifecycle.java +++ b/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/lifecycle/OntapPrimaryDatastoreLifecycle.java @@ -450,8 +450,31 @@ public boolean maintain(DataStore store) { @Override public boolean cancelMaintain(DataStore store) { logger.info("Cancelling storage pool maintenance for {}", store); + + // Save capacity before the generic cancelMaintain path overwrites it. + // The generic flow sends ModifyStoragePoolCommand to agents. For managed iSCSI pools, + // IscsiAdmStoragePool returns capacityBytes=0 (it doesn't track real ONTAP capacity), + // which causes updateStoragePoolHostVOAndBytes to overwrite the real capacity set during + // pool initialization. With capacity=0, the deployment planner's checkPoolforSpace + // divides by zero and rejects the pool ("No destination found"). + StoragePoolVO poolVO = storagePoolDao.findById(store.getId()); + long savedCapacityBytes = poolVO.getCapacityBytes(); + long savedUsedBytes = poolVO.getUsedBytes(); + if (_dataStoreHelper.cancelMaintain(store)) { - return _storagePoolAutomation.cancelMaintain(store); + boolean result = _storagePoolAutomation.cancelMaintain(store); + + // Restore capacity if the generic path zeroed it out + poolVO = storagePoolDao.findById(store.getId()); + if (poolVO.getCapacityBytes() == 0 && savedCapacityBytes > 0) { + logger.info("Restoring storage pool {} capacity to {} bytes (agent returned 0 during cancelMaintain)", + poolVO.getName(), savedCapacityBytes); + poolVO.setCapacityBytes(savedCapacityBytes); + poolVO.setUsedBytes(savedUsedBytes); + storagePoolDao.update(poolVO.getId(), poolVO); + } + + return result; } else { return false; } From 6e94d3403dfd7aadea692cd14c129d47b9aa7405 Mon Sep 17 00:00:00 2001 From: "Srivastava, Piyush" Date: Tue, 12 May 2026 20:16:34 +0530 Subject: [PATCH 2/3] bugfix/CSTACKEX-155: Fix cancel maintain for vm provisioning update comments --- .../lifecycle/OntapPrimaryDatastoreLifecycle.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/lifecycle/OntapPrimaryDatastoreLifecycle.java b/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/lifecycle/OntapPrimaryDatastoreLifecycle.java index 070c77805bd7..e9ba46a4333e 100755 --- a/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/lifecycle/OntapPrimaryDatastoreLifecycle.java +++ b/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/lifecycle/OntapPrimaryDatastoreLifecycle.java @@ -453,10 +453,8 @@ public boolean cancelMaintain(DataStore store) { // Save capacity before the generic cancelMaintain path overwrites it. // The generic flow sends ModifyStoragePoolCommand to agents. For managed iSCSI pools, - // IscsiAdmStoragePool returns capacityBytes=0 (it doesn't track real ONTAP capacity), - // which causes updateStoragePoolHostVOAndBytes to overwrite the real capacity set during - // pool initialization. With capacity=0, the deployment planner's checkPoolforSpace - // divides by zero and rejects the pool ("No destination found"). + // IscsiAdmStoragePool returns capacityBytes=0 , With capacity=0, + // the deployment planner's checkPoolforSpace rejects the pool ("No destination found"). StoragePoolVO poolVO = storagePoolDao.findById(store.getId()); long savedCapacityBytes = poolVO.getCapacityBytes(); long savedUsedBytes = poolVO.getUsedBytes(); @@ -464,10 +462,10 @@ public boolean cancelMaintain(DataStore store) { if (_dataStoreHelper.cancelMaintain(store)) { boolean result = _storagePoolAutomation.cancelMaintain(store); - // Restore capacity if the generic path zeroed it out + // Restore capacity poolVO = storagePoolDao.findById(store.getId()); if (poolVO.getCapacityBytes() == 0 && savedCapacityBytes > 0) { - logger.info("Restoring storage pool {} capacity to {} bytes (agent returned 0 during cancelMaintain)", + logger.info("Restoring storage pool {} capacity to {} bytes", poolVO.getName(), savedCapacityBytes); poolVO.setCapacityBytes(savedCapacityBytes); poolVO.setUsedBytes(savedUsedBytes); From c894d9a357b02dbf2f24f4398f60199d562028aa Mon Sep 17 00:00:00 2001 From: "Srivastava, Piyush" Date: Fri, 15 May 2026 11:54:03 +0530 Subject: [PATCH 3/3] bugfix/CSTACKEX-155: Fix cancel maintain for vm provisioning 1 --- .../OntapPrimaryDatastoreLifecycle.java | 23 +------------------ .../com/cloud/storage/StorageManagerImpl.java | 2 +- 2 files changed, 2 insertions(+), 23 deletions(-) diff --git a/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/lifecycle/OntapPrimaryDatastoreLifecycle.java b/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/lifecycle/OntapPrimaryDatastoreLifecycle.java index f9f681bccf23..1e44ef3aaa83 100755 --- a/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/lifecycle/OntapPrimaryDatastoreLifecycle.java +++ b/plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/lifecycle/OntapPrimaryDatastoreLifecycle.java @@ -452,29 +452,8 @@ public boolean maintain(DataStore store) { @Override public boolean cancelMaintain(DataStore store) { logger.info("Cancelling storage pool maintenance for {}", store); - - // Save capacity before the generic cancelMaintain path overwrites it. - // The generic flow sends ModifyStoragePoolCommand to agents. For managed iSCSI pools, - // IscsiAdmStoragePool returns capacityBytes=0 , With capacity=0, - // the deployment planner's checkPoolforSpace rejects the pool ("No destination found"). - StoragePoolVO poolVO = storagePoolDao.findById(store.getId()); - long savedCapacityBytes = poolVO.getCapacityBytes(); - long savedUsedBytes = poolVO.getUsedBytes(); - if (_dataStoreHelper.cancelMaintain(store)) { - boolean result = _storagePoolAutomation.cancelMaintain(store); - - // Restore capacity - poolVO = storagePoolDao.findById(store.getId()); - if (poolVO.getCapacityBytes() == 0 && savedCapacityBytes > 0) { - logger.info("Restoring storage pool {} capacity to {} bytes", - poolVO.getName(), savedCapacityBytes); - poolVO.setCapacityBytes(savedCapacityBytes); - poolVO.setUsedBytes(savedUsedBytes); - storagePoolDao.update(poolVO.getId(), poolVO); - } - - return result; + return _storagePoolAutomation.cancelMaintain(store); } else { return false; } diff --git a/server/src/main/java/com/cloud/storage/StorageManagerImpl.java b/server/src/main/java/com/cloud/storage/StorageManagerImpl.java index 7c501c78beeb..289451b440cc 100644 --- a/server/src/main/java/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/main/java/com/cloud/storage/StorageManagerImpl.java @@ -3109,7 +3109,7 @@ public void updateStoragePoolHostVOAndBytes(StoragePool pool, long hostId, Modif } StoragePoolVO poolVO = _storagePoolDao.findById(pool.getId()); - if (!Storage.StoragePoolType.StorPool.equals(poolVO.getPoolType())) { + if (!Storage.StoragePoolType.StorPool.equals(poolVO.getPoolType()) && !poolVO.getStorageProviderName().equals(DataStoreProvider.ONTAP_PLUGIN_NAME) ) { poolVO.setUsedBytes(mspAnswer.getPoolInfo().getCapacityBytes() - mspAnswer.getPoolInfo().getAvailableBytes()); poolVO.setCapacityBytes(mspAnswer.getPoolInfo().getCapacityBytes()); }