Release reserved storage resources on VM deployment failure (#13048)

This commit is contained in:
Fabricio Duarte 2026-04-30 12:22:35 -03:00 committed by GitHub
parent 92d82989e3
commit 1f5dba9bd2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 13 additions and 17 deletions

View File

@ -18,3 +18,9 @@
--;
-- Schema upgrade cleanup from 4.22.0.0 to 4.22.1.0
--;
-- Entries remaining on `cloud`.`resource_reservation` during the upgrade process are stale, so delete them.
-- This script was added to normalize volume/primary storage reservations that got stuck due to a bug on VM deployment,
-- but it is more interesting to introduce a smarter logic to clean these stale reservations in the future without the need
-- for upgrades (for instance, by having a heartbeat_time column for the reservations and automatically cleaning old entries).
DELETE FROM `cloud`.`resource_reservation`;

View File

@ -4301,9 +4301,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
return resourceLimitService.getResourceLimitStorageTags(diskOfferingVO);
}
private List<CheckedReservation> reserveStorageResourcesForVm(Account owner, Long diskOfferingId, Long diskSize, List<VmDiskInfo> dataDiskInfoList, Long rootDiskOfferingId, ServiceOfferingVO offering, Long rootDiskSize) throws ResourceAllocationException {
List <CheckedReservation> checkedReservations = new ArrayList<>();
private void reserveStorageResourcesForVm(List<Reserver> checkedReservations, Account owner, Long diskOfferingId, Long diskSize, List<VmDiskInfo> dataDiskInfoList, Long rootDiskOfferingId, ServiceOfferingVO offering, Long rootDiskSize) throws ResourceAllocationException {
List<String> rootResourceLimitStorageTags = getResourceLimitStorageTags(rootDiskOfferingId != null ? rootDiskOfferingId : offering.getDiskOfferingId());
CheckedReservation rootVolumeReservation = new CheckedReservation(owner, ResourceType.volume, rootResourceLimitStorageTags, 1L, reservationDao, resourceLimitService);
checkedReservations.add(rootVolumeReservation);
@ -4311,12 +4309,12 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
checkedReservations.add(rootPrimaryStorageReservation);
if (diskOfferingId != null) {
List<String> additionalResourceLimitStorageTags = diskOfferingId != null ? getResourceLimitStorageTags(diskOfferingId) : null;
List<String> additionalResourceLimitStorageTags = getResourceLimitStorageTags(diskOfferingId);
DiskOfferingVO diskOffering = _diskOfferingDao.findById(diskOfferingId);
Long size = verifyAndGetDiskSize(diskOffering, diskSize);
CheckedReservation additionalVolumeReservation = diskOfferingId != null ? new CheckedReservation(owner, ResourceType.volume, additionalResourceLimitStorageTags, 1L, reservationDao, resourceLimitService) : null;
CheckedReservation additionalVolumeReservation = new CheckedReservation(owner, ResourceType.volume, additionalResourceLimitStorageTags, 1L, reservationDao, resourceLimitService);
checkedReservations.add(additionalVolumeReservation);
CheckedReservation additionalPrimaryStorageReservation = diskOfferingId != null ? new CheckedReservation(owner, ResourceType.primary_storage, additionalResourceLimitStorageTags, size, reservationDao, resourceLimitService) : null;
CheckedReservation additionalPrimaryStorageReservation = new CheckedReservation(owner, ResourceType.primary_storage, additionalResourceLimitStorageTags, size, reservationDao, resourceLimitService);
checkedReservations.add(additionalPrimaryStorageReservation);
}
@ -4332,7 +4330,6 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
checkedReservations.add(additionalPrimaryStorageReservation);
}
}
return checkedReservations;
}
private UserVm getUncheckedUserVmResource(DataCenter zone, String hostName, String displayName, Account owner,
@ -4344,10 +4341,10 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
Map<String, String> userVmOVFPropertiesMap, boolean dynamicScalingEnabled, String vmType, VMTemplateVO template,
HypervisorType hypervisorType, long accountId, ServiceOfferingVO offering, boolean isIso,
Long rootDiskOfferingId, long volumesSize, Volume volume, Snapshot snapshot) throws ResourceAllocationException {
List<CheckedReservation> checkedReservations = new ArrayList<>();
List<Reserver> checkedReservations = new ArrayList<>();
try {
checkedReservations = reserveStorageResourcesForVm(owner, diskOfferingId, diskSize, dataDiskInfoList, rootDiskOfferingId, offering, volumesSize);
reserveStorageResourcesForVm(checkedReservations, owner, diskOfferingId, diskSize, dataDiskInfoList, rootDiskOfferingId, offering, volumesSize);
// verify security group ids
if (securityGroupIdList != null) {
@ -4638,14 +4635,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
logger.error("error during resource reservation and allocation", e);
throw new CloudRuntimeException(e);
} finally {
for (CheckedReservation checkedReservation : checkedReservations) {
try {
checkedReservation.close();
} catch (Exception e) {
logger.error("error during resource reservation and allocation", e);
throw new CloudRuntimeException(e);
}
}
ReservationHelper.closeAll(checkedReservations);
}
}