Reset the pool id when create volume fails on the allocated pool, and update the resize error when no endpoint exists (#10777)

* 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
This commit is contained in:
Suresh Kumar Anaparti 2025-05-16 13:56:28 +05:30 committed by GitHub
parent c183fc9859
commit 112dfddd40
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 22 additions and 13 deletions

View File

@ -324,6 +324,11 @@ public class VolumeServiceImpl implements VolumeService {
} else {
vo.processEvent(Event.OperationFailed);
errMsg = result.getResult();
VolumeVO volume = volDao.findById(vo.getId());
if (volume != null && volume.getState() == State.Allocated && volume.getPodId() != null) {
volume.setPoolId(null);
volDao.update(volume.getId(), volume);
}
}
VolumeApiResult volResult = new VolumeApiResult((VolumeObject)vo);
if (errMsg != null) {
@ -1238,6 +1243,10 @@ public class VolumeServiceImpl implements VolumeService {
}
if (volume.getState() == State.Allocated) { // Possible states here: Allocated, Ready & Creating
if (volume.getPodId() != null) {
volume.setPoolId(null);
volDao.update(volume.getId(), volume);
}
return;
}
@ -2482,7 +2491,7 @@ public class VolumeServiceImpl implements VolumeService {
try {
volume.processEvent(Event.ResizeRequested);
} catch (Exception e) {
s_logger.debug("Failed to change state to resize", e);
s_logger.debug("Failed to change volume state to resize", e);
result.setResult(e.toString());
future.complete(result);
return future;
@ -2494,10 +2503,8 @@ public class VolumeServiceImpl implements VolumeService {
try {
volume.getDataStore().getDriver().resize(volume, caller);
} catch (Exception e) {
s_logger.debug("Failed to change state to resize", e);
s_logger.debug("Failed to resize volume", e);
result.setResult(e.toString());
future.complete(result);
}
@ -2541,7 +2548,7 @@ public class VolumeServiceImpl implements VolumeService {
try {
volume.processEvent(Event.OperationFailed);
} catch (Exception e) {
s_logger.debug("Failed to change state", e);
s_logger.debug("Failed to change volume state (after resize failure)", e);
}
VolumeApiResult res = new VolumeApiResult(volume);
res.setResult(result.getResult());
@ -2552,13 +2559,8 @@ public class VolumeServiceImpl implements VolumeService {
try {
volume.processEvent(Event.OperationSuccessed);
} catch (Exception e) {
s_logger.debug("Failed to change state", e);
VolumeApiResult res = new VolumeApiResult(volume);
res.setResult(result.getResult());
future.complete(res);
return null;
s_logger.debug("Failed to change volume state (after resize success)", e);
}
VolumeApiResult res = new VolumeApiResult(volume);
future.complete(res);

View File

@ -429,9 +429,18 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri
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);
result.setResult(errMsg);
callback.complete(result);
return;
}
endpointsToRunResize = new long[] {ep.getId()};
}
ResizeVolumeCommand resizeCmd = new ResizeVolumeCommand(vol.getPath(), new StorageFilerTO(pool), vol.getSize(),
@ -439,7 +448,6 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri
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()) {
@ -456,7 +464,6 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri
s_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) {
s_logger.debug("sending resize command failed", e);
result.setResult(e.toString());