From e458a41a40cbf66577474a16833fe8a50ac51fdf Mon Sep 17 00:00:00 2001 From: Suresh Kumar Anaparti Date: Mon, 21 Apr 2025 15:01:47 +0530 Subject: [PATCH 1/5] Consider the clusters with allocation state 'Enabled' for EndPoint selection (in addition to Host state) --- .../cloudstack/storage/endpoint/DefaultEndPointSelector.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/storage/src/main/java/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java index 79be65888995..7e9f65f43b34 100644 --- a/engine/storage/src/main/java/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java +++ b/engine/storage/src/main/java/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java @@ -80,7 +80,7 @@ public class DefaultEndPointSelector implements EndPointSelector { private final String findOneHostOnPrimaryStorage = "select t.id from " + "(select h.id, cd.value, hd.value as " + VOL_ENCRYPT_COLUMN_NAME + " " + "from host h join storage_pool_host_ref s on h.id = s.host_id " - + "join cluster c on c.id=h.cluster_id " + + "join cluster c on c.id=h.cluster_id and c.allocation_state = 'Enabled'" + "left join cluster_details cd on c.id=cd.cluster_id and cd.name='" + CapacityManager.StorageOperationsExcludeCluster.key() + "' " + "left join host_details hd on h.id=hd.host_id and hd.name='" + HOST_VOLUME_ENCRYPTION + "' " + "where h.status = 'Up' and h.type = 'Routing' and h.resource_state = 'Enabled' and s.pool_id = ? "; From 4a9983ec6b3091043528733dd42fc92f8e841ce3 Mon Sep 17 00:00:00 2001 From: Suresh Kumar Anaparti Date: Fri, 25 Apr 2025 09:47:56 +0530 Subject: [PATCH 2/5] Reset the pool id when create volume fails on the allocated pool - the pool id is persisted while creating the volume, when it fails the pool id is not reverted. On next create volume attempt, CloudStack couldn't find any suitable primary storage even there are pools available with enough capacity as the pool is already assigned to volume which is in Allocated state (and storage pool compatibility check fails). Ensure volume is not assigned to any pool if create volume fails (so the next creation job would pick the suitable pool). --- .../cloudstack/storage/volume/VolumeServiceImpl.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index 26bef607c9b2..5085199ae862 100644 --- a/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -328,6 +328,11 @@ protected Void createVolumeCallback(AsyncCallbackDispatcher Date: Tue, 29 Apr 2025 12:26:04 +0530 Subject: [PATCH 3/5] endpoint check for resize --- .../apache/cloudstack/storage/volume/VolumeServiceImpl.java | 6 ++---- .../driver/CloudStackPrimaryDataStoreDriverImpl.java | 6 ++++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index 5085199ae862..848a6a6d27e4 100644 --- a/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -2485,7 +2485,7 @@ public AsyncCallFuture resize(VolumeInfo volume) { try { volume.processEvent(Event.ResizeRequested); } catch (Exception e) { - logger.debug("Failed to change state to resize", e); + logger.debug("Failed to change volume state to resize", e); result.setResult(e.toString()); future.complete(result); return future; @@ -2497,10 +2497,8 @@ public AsyncCallFuture resize(VolumeInfo volume) { try { volume.getDataStore().getDriver().resize(volume, caller); } catch (Exception e) { - logger.debug("Failed to change state to resize", e); - + logger.debug("Failed to resize volume", e); result.setResult(e.toString()); - future.complete(result); } diff --git a/plugins/storage/volume/default/src/main/java/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java b/plugins/storage/volume/default/src/main/java/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java index 8bb9ef1ead8f..a0c3717011f1 100644 --- a/plugins/storage/volume/default/src/main/java/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java +++ b/plugins/storage/volume/default/src/main/java/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java @@ -28,6 +28,7 @@ import com.cloud.agent.api.to.DiskTO; import com.cloud.storage.VolumeVO; +import com.cloud.utils.exception.CloudRuntimeException; import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; @@ -435,6 +436,11 @@ public void resize(DataObject data, AsyncCompletionCallback cal // if hosts are provided, they are where the VM last ran. We can use that. if (endpointsToRunResize == null || endpointsToRunResize.length == 0) { EndPoint ep = epSelector.select(data, encryptionRequired); + if (ep == null) { + String errMsg = String.format(NO_REMOTE_ENDPOINT_WITH_ENCRYPTION, encryptionRequired); + s_logger.error(errMsg); + throw new CloudRuntimeException(errMsg); + } endpointsToRunResize = new long[] {ep.getId()}; } ResizeVolumeCommand resizeCmd = new ResizeVolumeCommand(vol.getPath(), new StorageFilerTO(pool), vol.getSize(), From 96fec773047351c9d37564faf96c0161910090b0 Mon Sep 17 00:00:00 2001 From: Suresh Kumar Anaparti Date: Wed, 30 Apr 2025 13:16:59 +0530 Subject: [PATCH 4/5] update the resize error through callback result instead of exception --- .../cloudstack/storage/volume/VolumeServiceImpl.java | 9 ++------- .../driver/CloudStackPrimaryDataStoreDriverImpl.java | 9 +++++---- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index 848a6a6d27e4..1a352f7351f7 100644 --- a/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -2542,7 +2542,7 @@ protected Void resizeVolumeCallback(AsyncCallbackDispatcher cal boolean encryptionRequired = anyVolumeRequiresEncryption(vol); long [] endpointsToRunResize = resizeParameter.hosts; + CreateCmdResult result = new CreateCmdResult(null, null); + // if hosts are provided, they are where the VM last ran. We can use that. if (endpointsToRunResize == null || endpointsToRunResize.length == 0) { EndPoint ep = epSelector.select(data, encryptionRequired); if (ep == null) { String errMsg = String.format(NO_REMOTE_ENDPOINT_WITH_ENCRYPTION, encryptionRequired); s_logger.error(errMsg); - throw new CloudRuntimeException(errMsg); + result.setResult(errMsg); + callback.complete(result); + return; } endpointsToRunResize = new long[] {ep.getId()}; } @@ -448,7 +451,6 @@ public void resize(DataObject data, AsyncCompletionCallback cal if (pool.getParent() != 0) { resizeCmd.setContextParam(DiskTO.PROTOCOL_TYPE, Storage.StoragePoolType.DatastoreCluster.toString()); } - CreateCmdResult result = new CreateCmdResult(null, null); try { ResizeVolumeAnswer answer = (ResizeVolumeAnswer) storageMgr.sendToPool(pool, endpointsToRunResize, resizeCmd); if (answer != null && answer.getResult()) { @@ -465,7 +467,6 @@ public void resize(DataObject data, AsyncCompletionCallback cal logger.debug("return a null answer, mark it as failed for unknown reason"); result.setResult("return a null answer, mark it as failed for unknown reason"); } - } catch (Exception e) { logger.debug("sending resize command failed", e); result.setResult(e.toString()); From 89fe76e9a17ecb145d2eb7b97b8bf5c4d112ba00 Mon Sep 17 00:00:00 2001 From: Suresh Kumar Anaparti Date: Mon, 12 May 2025 15:55:30 +0530 Subject: [PATCH 5/5] logger fix --- .../datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/storage/volume/default/src/main/java/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java b/plugins/storage/volume/default/src/main/java/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java index b959c89e7f03..3603589f4ad3 100644 --- a/plugins/storage/volume/default/src/main/java/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java +++ b/plugins/storage/volume/default/src/main/java/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java @@ -439,7 +439,7 @@ public void resize(DataObject data, AsyncCompletionCallback cal EndPoint ep = epSelector.select(data, encryptionRequired); if (ep == null) { String errMsg = String.format(NO_REMOTE_ENDPOINT_WITH_ENCRYPTION, encryptionRequired); - s_logger.error(errMsg); + logger.error(errMsg); result.setResult(errMsg); callback.complete(result); return;