Skip to content

Commit c3812d6

Browse files
committed
Fix resource count discrepancies
1 parent 12dcf5c commit c3812d6

File tree

10 files changed

+107
-13
lines changed

10 files changed

+107
-13
lines changed

engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -881,8 +881,14 @@ public DiskProfile allocateRawVolume(Type type, String name, DiskOffering offeri
881881
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, vol.getAccountId(), vol.getDataCenterId(), vol.getId(), vol.getName(), offering.getId(), null, size,
882882
Volume.class.getName(), vol.getUuid(), vol.isDisplayVolume());
883883

884-
_resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.volume, vol.isDisplayVolume());
885-
_resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.primary_storage, vol.isDisplayVolume(), new Long(vol.getSize()));
884+
VolumeVO finalVol = vol;
885+
Transaction.execute(new TransactionCallbackNoReturn() {
886+
@Override
887+
public void doInTransactionWithoutResult(TransactionStatus status) {
888+
_resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.volume, finalVol.isDisplayVolume());
889+
_resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.primary_storage, finalVol.isDisplayVolume(), new Long(finalVol.getSize()));
890+
}
891+
});
886892
}
887893
DiskProfile diskProfile = toDiskProfile(vol, offering);
888894

@@ -963,9 +969,14 @@ private DiskProfile allocateTemplatedVolume(Type type, String name, DiskOffering
963969

964970
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, vol.getAccountId(), vol.getDataCenterId(), vol.getId(), vol.getName(), offeringId, vol.getTemplateId(), size,
965971
Volume.class.getName(), vol.getUuid(), vol.isDisplayVolume());
966-
967-
_resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.volume, vol.isDisplayVolume());
968-
_resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.primary_storage, vol.isDisplayVolume(), new Long(vol.getSize()));
972+
VolumeVO finalVol = vol;
973+
Transaction.execute(new TransactionCallbackNoReturn() {
974+
@Override
975+
public void doInTransactionWithoutResult(TransactionStatus status) {
976+
_resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.volume, finalVol.isDisplayVolume());
977+
_resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.primary_storage, finalVol.isDisplayVolume(), new Long(finalVol.getSize()));
978+
}
979+
});
969980
}
970981
return toDiskProfile(vol, offering);
971982
}

engine/schema/src/main/java/com/cloud/storage/VolumeVO.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,9 @@ public class VolumeVO implements Volume {
180180
@Column(name = "encrypt_format")
181181
private String encryptFormat;
182182

183+
@Column(name = "resource_reservation_id")
184+
private Long resourceReservationId;
185+
183186
// Real Constructor
184187
public VolumeVO(Type type, String name, long dcId, long domainId,
185188
long accountId, long diskOfferingId, Storage.ProvisioningType provisioningType, long size,
@@ -677,4 +680,12 @@ public void setExternalUuid(String externalUuid) {
677680
public String getEncryptFormat() { return encryptFormat; }
678681

679682
public void setEncryptFormat(String encryptFormat) { this.encryptFormat = encryptFormat; }
683+
684+
public Long getResourceReservationId() {
685+
return resourceReservationId;
686+
}
687+
688+
public void setResourceReservationId(Long resourceReservationId) {
689+
this.resourceReservationId = resourceReservationId;
690+
}
680691
}

engine/schema/src/main/java/com/cloud/storage/dao/VolumeDaoImpl.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626

2727
import javax.inject.Inject;
2828

29+
import com.cloud.configuration.Resource;
30+
import org.apache.cloudstack.context.CallContext;
31+
import org.apache.cloudstack.user.ResourceReservation;
2932
import org.apache.commons.collections.CollectionUtils;
3033
import org.apache.log4j.Logger;
3134
import org.springframework.stereotype.Component;
@@ -443,6 +446,7 @@ public VolumeDaoImpl() {
443446
CountByAccount.and("account", CountByAccount.entity().getAccountId(), SearchCriteria.Op.EQ);
444447
CountByAccount.and("state", CountByAccount.entity().getState(), SearchCriteria.Op.NIN);
445448
CountByAccount.and("displayVolume", CountByAccount.entity().isDisplayVolume(), Op.EQ);
449+
CountByAccount.and("resource_reservation_id", CountByAccount.entity().getResourceReservationId(), SearchCriteria.Op.NULL);
446450
CountByAccount.done();
447451

448452
primaryStorageSearch = createSearchBuilder(SumCount.class);
@@ -454,6 +458,7 @@ public VolumeDaoImpl() {
454458
primaryStorageSearch.and("displayVolume", primaryStorageSearch.entity().isDisplayVolume(), Op.EQ);
455459
primaryStorageSearch.and("isRemoved", primaryStorageSearch.entity().getRemoved(), Op.NULL);
456460
primaryStorageSearch.and("NotCountStates", primaryStorageSearch.entity().getState(), Op.NIN);
461+
primaryStorageSearch.and("resource_reservation_id", primaryStorageSearch.entity().getResourceReservationId(), Op.NULL);
457462
primaryStorageSearch.done();
458463

459464
primaryStorageSearch2 = createSearchBuilder(SumCount.class);
@@ -468,6 +473,7 @@ public VolumeDaoImpl() {
468473
primaryStorageSearch2.and("displayVolume", primaryStorageSearch2.entity().isDisplayVolume(), Op.EQ);
469474
primaryStorageSearch2.and("isRemoved", primaryStorageSearch2.entity().getRemoved(), Op.NULL);
470475
primaryStorageSearch2.and("NotCountStates", primaryStorageSearch2.entity().getState(), Op.NIN);
476+
primaryStorageSearch2.and("resource_reservation_id", primaryStorageSearch2.entity().getResourceReservationId(), Op.NULL);
471477
primaryStorageSearch2.done();
472478

473479
secondaryStorageSearch = createSearchBuilder(SumCount.class);
@@ -811,4 +817,13 @@ public List<VolumeVO> listByIds(List<Long> ids) {
811817
sc.setParameters("idIN", ids.toArray());
812818
return listBy(sc, null);
813819
}
820+
821+
@Override
822+
public VolumeVO persist(VolumeVO entity) {
823+
Object obj = CallContext.current().getContextParameter(String.format("%s-%s", ResourceReservation.class.getSimpleName(), Resource.ResourceType.volume.name()));
824+
if (obj instanceof Long) {
825+
entity.setResourceReservationId((long)obj);
826+
}
827+
return super.persist(entity);
828+
}
814829
}

engine/schema/src/main/java/com/cloud/vm/UserVmVO.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ public class UserVmVO extends VMInstanceVO implements UserVm {
5858
@Column(name = "user_vm_type", updatable = true)
5959
private String userVmType;
6060

61+
@Column(name = "resource_reservation_id")
62+
private Long resourceReservationId;
63+
6164
transient String password;
6265

6366
@Override
@@ -174,4 +177,12 @@ public String getUserDataDetails() {
174177
public void setUserDataDetails(String userDataDetails) {
175178
this.userDataDetails = userDataDetails;
176179
}
180+
181+
public Long getResourceReservationId() {
182+
return resourceReservationId;
183+
}
184+
185+
public void setResourceReservationId(Long resourceReservationId) {
186+
this.resourceReservationId = resourceReservationId;
187+
}
177188
}

engine/schema/src/main/java/com/cloud/vm/dao/UserVmDaoImpl.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@
3030
import javax.annotation.PostConstruct;
3131
import javax.inject.Inject;
3232

33+
import com.cloud.configuration.Resource;
34+
import org.apache.cloudstack.context.CallContext;
35+
import org.apache.cloudstack.user.ResourceReservation;
3336
import org.apache.commons.collections.CollectionUtils;
3437
import org.apache.log4j.Logger;
3538

@@ -200,6 +203,7 @@ void init() {
200203
CountByAccount.and("type", CountByAccount.entity().getType(), SearchCriteria.Op.EQ);
201204
CountByAccount.and("state", CountByAccount.entity().getState(), SearchCriteria.Op.NIN);
202205
CountByAccount.and("displayVm", CountByAccount.entity().isDisplayVm(), SearchCriteria.Op.EQ);
206+
CountByAccount.and("resource_reservation_id", CountByAccount.entity().getResourceReservationId(), SearchCriteria.Op.NULL);
203207
CountByAccount.done();
204208

205209
CountActiveAccount = createSearchBuilder(Long.class);
@@ -794,4 +798,13 @@ public List<UserVmVO> listByIds(List<Long> ids) {
794798
sc.setParameters("ids", ids.toArray());
795799
return listBy(sc);
796800
}
801+
802+
@Override
803+
public UserVmVO persist(UserVmVO entity) {
804+
Object obj = CallContext.current().getContextParameter(String.format("%s-%s", ResourceReservation.class.getSimpleName(), Resource.ResourceType.user_vm.name()));
805+
if (obj instanceof Long) {
806+
entity.setResourceReservationId((long)obj);
807+
}
808+
return super.persist(entity);
809+
}
797810
}

engine/schema/src/main/resources/META-INF/db/schema-41810to41900.sql

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,3 +314,17 @@ CREATE TABLE `cloud_usage`.`bucket_statistics` (
314314
`size` bigint unsigned COMMENT 'total size of bucket objects',
315315
PRIMARY KEY(`id`)
316316
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
317+
318+
-- Add resource reservation columns to user_vm & volumes
319+
320+
ALTER TABLE `cloud`.`user_vm`
321+
ADD COLUMN `resource_reservation_id` bigint unsigned NULL;
322+
ALTER TABLE `cloud`.`user_vm`
323+
ADD CONSTRAINT `fk_user_vm__resource_reservation_id`
324+
FOREIGN KEY (`resource_reservation_id`) REFERENCES `resource_reservation`(`id`) ON DELETE SET NULL;
325+
326+
ALTER TABLE `cloud`.`volumes`
327+
ADD COLUMN `resource_reservation_id` bigint unsigned NULL;
328+
ALTER TABLE `cloud`.`volumes`
329+
ADD CONSTRAINT `fk_volumes__resource_reservation_id`
330+
FOREIGN KEY (`resource_reservation_id`) REFERENCES `resource_reservation`(`id`) ON DELETE SET NULL;

engine/schema/src/main/resources/META-INF/db/views/cloud.user_vm_view.sql

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,8 @@ SELECT
165165
`user_data`.`uuid` AS `user_data_uuid`,
166166
`user_data`.`name` AS `user_data_name`,
167167
`user_vm`.`user_data_details` AS `user_data_details`,
168-
`vm_template`.`user_data_link_policy` AS `user_data_policy`
168+
`vm_template`.`user_data_link_policy` AS `user_data_policy`,
169+
`user_vm`.`resource_reservation_id` AS `resource_reservation_id`
169170
FROM
170171
(((((((((((((((((((((((((((((((((((`user_vm`
171172
JOIN `vm_instance` ON (((`vm_instance`.`id` = `user_vm`.`id`)

server/src/main/java/com/cloud/api/query/vo/UserVmJoinVO.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,9 @@ public class UserVmJoinVO extends BaseViewWithTagInformationVO implements Contro
426426
@Column(name = "dynamically_scalable")
427427
private boolean isDynamicallyScalable;
428428

429+
@Column(name = "resource_reservation_id")
430+
private Long resourceReservationId;
431+
429432

430433
public UserVmJoinVO() {
431434
// Empty constructor
@@ -954,4 +957,7 @@ public String getUserDataDetails() {
954957
return userDataDetails;
955958
}
956959

960+
public Long getResourceReservationId() {
961+
return resourceReservationId;
962+
}
957963
}

server/src/main/java/com/cloud/resourcelimit/ResourceLimitManagerImpl.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1018,6 +1018,7 @@ public long countCpusForAccount(long accountId) {
10181018
userVmSearch.and("accountId", userVmSearch.entity().getAccountId(), Op.EQ);
10191019
userVmSearch.and("state", userVmSearch.entity().getState(), SearchCriteria.Op.NIN);
10201020
userVmSearch.and("displayVm", userVmSearch.entity().isDisplayVm(), Op.EQ);
1021+
userVmSearch.and("resource_reservation_id", userVmSearch.entity().getResourceReservationId(), Op.NULL);
10211022
userVmSearch.groupBy(userVmSearch.entity().getId()); // select distinct
10221023
userVmSearch.done();
10231024

@@ -1042,6 +1043,7 @@ public long calculateMemoryForAccount(long accountId) {
10421043
userVmSearch.and("accountId", userVmSearch.entity().getAccountId(), Op.EQ);
10431044
userVmSearch.and("state", userVmSearch.entity().getState(), SearchCriteria.Op.NIN);
10441045
userVmSearch.and("displayVm", userVmSearch.entity().isDisplayVm(), Op.EQ);
1046+
userVmSearch.and("resource_reservation_id", userVmSearch.entity().getResourceReservationId(), Op.NULL);
10451047
userVmSearch.groupBy(userVmSearch.entity().getId()); // select distinct
10461048
userVmSearch.done();
10471049

server/src/main/java/com/cloud/vm/UserVmManagerImpl.java

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -689,18 +689,28 @@ private void resourceLimitCheck(Account owner, Boolean displayVm, Long cpu, Long
689689
}
690690

691691
protected void resourceCountIncrement(long accountId, Boolean displayVm, Long cpu, Long memory) {
692-
if (! VirtualMachineManager.ResourceCountRunningVMsonly.value()) {
693-
_resourceLimitMgr.incrementResourceCount(accountId, ResourceType.user_vm, displayVm);
694-
_resourceLimitMgr.incrementResourceCount(accountId, ResourceType.cpu, displayVm, cpu);
695-
_resourceLimitMgr.incrementResourceCount(accountId, ResourceType.memory, displayVm, memory);
692+
if (!VirtualMachineManager.ResourceCountRunningVMsonly.value()) {
693+
Transaction.execute(new TransactionCallbackNoReturn() {
694+
@Override
695+
public void doInTransactionWithoutResult(TransactionStatus status) {
696+
_resourceLimitMgr.incrementResourceCount(accountId, ResourceType.user_vm, displayVm);
697+
_resourceLimitMgr.incrementResourceCount(accountId, ResourceType.cpu, displayVm, cpu);
698+
_resourceLimitMgr.incrementResourceCount(accountId, ResourceType.memory, displayVm, memory);
699+
}
700+
});
696701
}
697702
}
698703

699704
protected void resourceCountDecrement(long accountId, Boolean displayVm, Long cpu, Long memory) {
700705
if (! VirtualMachineManager.ResourceCountRunningVMsonly.value()) {
701-
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.user_vm, displayVm);
702-
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.cpu, displayVm, cpu);
703-
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.memory, displayVm, memory);
706+
Transaction.execute(new TransactionCallbackNoReturn() {
707+
@Override
708+
public void doInTransactionWithoutResult(TransactionStatus status) {
709+
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.user_vm, displayVm);
710+
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.cpu, displayVm, cpu);
711+
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.memory, displayVm, memory);
712+
}
713+
});
704714
}
705715
}
706716

0 commit comments

Comments
 (0)