Skip to content

Commit 52d9860

Browse files
Updated Endpoint Selector to pick the Cluster in Enabled state (in addition to Host state) (#10757)
* Consider the clusters with allocation state 'Enabled' for EndPoint selection (in addition to Host state) * 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). * endpoint check for resize * update the resize error through callback result instead of exception * logger fix
1 parent 95489b8 commit 52d9860

File tree

3 files changed

+23
-14
lines changed

3 files changed

+23
-14
lines changed

engine/storage/src/main/java/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ public class DefaultEndPointSelector implements EndPointSelector {
8080
private final String findOneHostOnPrimaryStorage = "select t.id from "
8181
+ "(select h.id, cd.value, hd.value as " + VOL_ENCRYPT_COLUMN_NAME + " "
8282
+ "from host h join storage_pool_host_ref s on h.id = s.host_id "
83-
+ "join cluster c on c.id=h.cluster_id "
83+
+ "join cluster c on c.id=h.cluster_id and c.allocation_state = 'Enabled'"
8484
+ "left join cluster_details cd on c.id=cd.cluster_id and cd.name='" + CapacityManager.StorageOperationsExcludeCluster.key() + "' "
8585
+ "left join host_details hd on h.id=hd.host_id and hd.name='" + HOST_VOLUME_ENCRYPTION + "' "
8686
+ "where h.status = 'Up' and h.type = 'Routing' and h.resource_state = 'Enabled' and s.pool_id = ? ";

engine/storage/volume/src/main/java/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,11 @@ protected Void createVolumeCallback(AsyncCallbackDispatcher<VolumeServiceImpl, C
328328
} else {
329329
vo.processEvent(Event.OperationFailed);
330330
errMsg = result.getResult();
331+
VolumeVO volume = volDao.findById(vo.getId());
332+
if (volume != null && volume.getState() == State.Allocated && volume.getPodId() != null) {
333+
volume.setPoolId(null);
334+
volDao.update(volume.getId(), volume);
335+
}
331336
}
332337
VolumeApiResult volResult = new VolumeApiResult((VolumeObject)vo);
333338
if (errMsg != null) {
@@ -1237,6 +1242,10 @@ private void destroyAndReallocateManagedVolume(VolumeInfo volumeInfo) {
12371242
}
12381243

12391244
if (volume.getState() == State.Allocated) { // Possible states here: Allocated, Ready & Creating
1245+
if (volume.getPodId() != null) {
1246+
volume.setPoolId(null);
1247+
volDao.update(volume.getId(), volume);
1248+
}
12401249
return;
12411250
}
12421251

@@ -2476,7 +2485,7 @@ public AsyncCallFuture<VolumeApiResult> resize(VolumeInfo volume) {
24762485
try {
24772486
volume.processEvent(Event.ResizeRequested);
24782487
} catch (Exception e) {
2479-
logger.debug("Failed to change state to resize", e);
2488+
logger.debug("Failed to change volume state to resize", e);
24802489
result.setResult(e.toString());
24812490
future.complete(result);
24822491
return future;
@@ -2488,10 +2497,8 @@ public AsyncCallFuture<VolumeApiResult> resize(VolumeInfo volume) {
24882497
try {
24892498
volume.getDataStore().getDriver().resize(volume, caller);
24902499
} catch (Exception e) {
2491-
logger.debug("Failed to change state to resize", e);
2492-
2500+
logger.debug("Failed to resize volume", e);
24932501
result.setResult(e.toString());
2494-
24952502
future.complete(result);
24962503
}
24972504

@@ -2535,7 +2542,7 @@ protected Void resizeVolumeCallback(AsyncCallbackDispatcher<VolumeServiceImpl, C
25352542
try {
25362543
volume.processEvent(Event.OperationFailed);
25372544
} catch (Exception e) {
2538-
logger.debug("Failed to change state", e);
2545+
logger.debug("Failed to change volume state (after resize failure)", e);
25392546
}
25402547
VolumeApiResult res = new VolumeApiResult(volume);
25412548
res.setResult(result.getResult());
@@ -2546,13 +2553,8 @@ protected Void resizeVolumeCallback(AsyncCallbackDispatcher<VolumeServiceImpl, C
25462553
try {
25472554
volume.processEvent(Event.OperationSuccessed);
25482555
} catch (Exception e) {
2549-
logger.debug("Failed to change state", e);
2550-
VolumeApiResult res = new VolumeApiResult(volume);
2551-
res.setResult(result.getResult());
2552-
future.complete(res);
2553-
return null;
2556+
logger.debug("Failed to change volume state (after resize success)", e);
25542557
}
2555-
25562558
VolumeApiResult res = new VolumeApiResult(volume);
25572559
future.complete(res);
25582560

plugins/storage/volume/default/src/main/java/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -432,17 +432,25 @@ public void resize(DataObject data, AsyncCompletionCallback<CreateCmdResult> cal
432432
boolean encryptionRequired = anyVolumeRequiresEncryption(vol);
433433
long [] endpointsToRunResize = resizeParameter.hosts;
434434

435+
CreateCmdResult result = new CreateCmdResult(null, null);
436+
435437
// if hosts are provided, they are where the VM last ran. We can use that.
436438
if (endpointsToRunResize == null || endpointsToRunResize.length == 0) {
437439
EndPoint ep = epSelector.select(data, encryptionRequired);
440+
if (ep == null) {
441+
String errMsg = String.format(NO_REMOTE_ENDPOINT_WITH_ENCRYPTION, encryptionRequired);
442+
logger.error(errMsg);
443+
result.setResult(errMsg);
444+
callback.complete(result);
445+
return;
446+
}
438447
endpointsToRunResize = new long[] {ep.getId()};
439448
}
440449
ResizeVolumeCommand resizeCmd = new ResizeVolumeCommand(vol.getPath(), new StorageFilerTO(pool), vol.getSize(),
441450
resizeParameter.newSize, resizeParameter.shrinkOk, resizeParameter.instanceName, vol.getChainInfo(), vol.getPassphrase(), vol.getEncryptFormat());
442451
if (pool.getParent() != 0) {
443452
resizeCmd.setContextParam(DiskTO.PROTOCOL_TYPE, Storage.StoragePoolType.DatastoreCluster.toString());
444453
}
445-
CreateCmdResult result = new CreateCmdResult(null, null);
446454
try {
447455
ResizeVolumeAnswer answer = (ResizeVolumeAnswer) storageMgr.sendToPool(pool, endpointsToRunResize, resizeCmd);
448456
if (answer != null && answer.getResult()) {
@@ -459,7 +467,6 @@ public void resize(DataObject data, AsyncCompletionCallback<CreateCmdResult> cal
459467
logger.debug("return a null answer, mark it as failed for unknown reason");
460468
result.setResult("return a null answer, mark it as failed for unknown reason");
461469
}
462-
463470
} catch (Exception e) {
464471
logger.debug("sending resize command failed", e);
465472
result.setResult(e.toString());

0 commit comments

Comments
 (0)