Skip to content

Commit 37e3657

Browse files
GutoVeroneziDaan Hoogland
authored andcommitted
[22.0] resource allocation
1 parent 71f47d6 commit 37e3657

10 files changed

Lines changed: 104 additions & 60 deletions

File tree

api/src/main/java/com/cloud/user/ResourceLimitService.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ public interface ResourceLimitService {
191191
*/
192192
public void checkResourceLimit(Account account, ResourceCount.ResourceType type, long... count) throws ResourceAllocationException;
193193
public void checkResourceLimitWithTag(Account account, ResourceCount.ResourceType type, String tag, long... count) throws ResourceAllocationException;
194+
public void checkResourceLimitWithTag(Account account, Long domainId, boolean considerSystemAccount, ResourceCount.ResourceType type, String tag, long... count) throws ResourceAllocationException;
194195

195196
/**
196197
* Gets the count of resources for a resource type and account
@@ -294,4 +295,5 @@ void checkVmResourceLimitsForTemplateChange(Account owner, Boolean display, Serv
294295
void incrementVmGpuResourceCount(long accountId, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, Long gpu);
295296
void decrementVmGpuResourceCount(long accountId, Boolean display, ServiceOffering serviceOffering, VirtualMachineTemplate template, Long gpu);
296297

298+
long recalculateDomainResourceCount(final long domainId, final ResourceType type, String tag);
297299
}

engine/api/src/main/java/org/apache/cloudstack/engine/orchestration/service/NetworkOrchestrationService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ void implementNetworkElementsAndResources(DeployDestination dest, ReservationCon
310310

311311
void removeDhcpServiceInSubnet(Nic nic);
312312

313-
boolean resourceCountNeedsUpdate(NetworkOffering ntwkOff, ACLType aclType);
313+
boolean isResourceCountUpdateNeeded(NetworkOffering networkOffering);
314314

315315
void prepareAllNicsForMigration(VirtualMachineProfile vm, DeployDestination dest);
316316

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

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
5959
import org.apache.cloudstack.network.RoutedIpv4Manager;
6060
import org.apache.cloudstack.network.dao.NetworkPermissionDao;
61+
import org.apache.cloudstack.reservation.dao.ReservationDao;
6162
import org.apache.commons.collections.CollectionUtils;
6263
import org.apache.commons.lang3.BooleanUtils;
6364
import org.apache.commons.lang3.ObjectUtils;
@@ -86,6 +87,7 @@
8687
import com.cloud.api.query.vo.DomainRouterJoinVO;
8788
import com.cloud.bgp.BGPService;
8889
import com.cloud.configuration.ConfigurationManager;
90+
import com.cloud.configuration.Resource;
8991
import com.cloud.configuration.Resource.ResourceType;
9092
import com.cloud.dc.ASNumberVO;
9193
import com.cloud.dc.ClusterVO;
@@ -214,6 +216,7 @@
214216
import com.cloud.offerings.dao.NetworkOfferingDetailsDao;
215217
import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
216218
import com.cloud.resource.ResourceManager;
219+
import com.cloud.resourcelimit.CheckedReservation;
217220
import com.cloud.server.ManagementServer;
218221
import com.cloud.user.Account;
219222
import com.cloud.user.ResourceLimitService;
@@ -447,6 +450,8 @@ public void setDhcpProviders(final List<DhcpServiceProvider> dhcpProviders) {
447450
ClusterDao clusterDao;
448451
@Inject
449452
RoutedIpv4Manager routedIpv4Manager;
453+
@Inject
454+
private ReservationDao reservationDao;
450455

451456
protected StateMachine2<Network.State, Network.Event, Network> _stateMachine;
452457
ScheduledExecutorService _executor;
@@ -2747,12 +2752,6 @@ private Network createGuestNetwork(final long networkOfferingId, final String na
27472752
return null;
27482753
}
27492754

2750-
final boolean updateResourceCount = resourceCountNeedsUpdate(ntwkOff, aclType);
2751-
//check resource limits
2752-
if (updateResourceCount) {
2753-
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.network, isDisplayNetworkEnabled);
2754-
}
2755-
27562755
// Validate network offering
27572756
if (ntwkOff.getState() != NetworkOffering.State.Enabled) {
27582757
// see NetworkOfferingVO
@@ -2771,6 +2770,8 @@ private Network createGuestNetwork(final long networkOfferingId, final String na
27712770

27722771
boolean ipv6 = false;
27732772

2773+
try (CheckedReservation networkReservation = new CheckedReservation(owner, domainId, Resource.ResourceType.network, null, null, 1L, reservationDao, _resourceLimitMgr)) {
2774+
27742775
if (StringUtils.isNoneBlank(ip6Gateway, ip6Cidr)) {
27752776
ipv6 = true;
27762777
}
@@ -3110,8 +3111,8 @@ public Network doInTransaction(final TransactionStatus status) {
31103111
}
31113112
}
31123113

3113-
if (updateResourceCount) {
3114-
_resourceLimitMgr.incrementResourceCount(owner.getId(), ResourceType.network, isDisplayNetworkEnabled);
3114+
if (isResourceCountUpdateNeeded(ntwkOff)) {
3115+
changeAccountResourceCountOrRecalculateDomainResourceCount(owner.getAccountId(), domainId, isDisplayNetworkEnabled, true);
31153116
}
31163117
UsageEventUtils.publishNetworkCreation(network);
31173118

@@ -3122,6 +3123,10 @@ public Network doInTransaction(final TransactionStatus status) {
31223123
CallContext.current().setEventDetails("Network Id: " + network.getId());
31233124
CallContext.current().putContextParameter(Network.class, network.getUuid());
31243125
return network;
3126+
} catch (Exception e) {
3127+
logger.error(e);
3128+
throw new RuntimeException(e);
3129+
}
31253130
}
31263131

31273132
@Override
@@ -3487,9 +3492,8 @@ public List<VlanVO> doInTransaction(TransactionStatus status) {
34873492
}
34883493

34893494
final NetworkOffering ntwkOff = _entityMgr.findById(NetworkOffering.class, networkFinal.getNetworkOfferingId());
3490-
final boolean updateResourceCount = resourceCountNeedsUpdate(ntwkOff, networkFinal.getAclType());
3491-
if (updateResourceCount) {
3492-
_resourceLimitMgr.decrementResourceCount(networkFinal.getAccountId(), ResourceType.network, networkFinal.getDisplayNetwork());
3495+
if (isResourceCountUpdateNeeded(ntwkOff)) {
3496+
changeAccountResourceCountOrRecalculateDomainResourceCount(networkFinal.getAccountId(), networkFinal.getDomainId(), networkFinal.getDisplayNetwork(), false);
34933497
}
34943498
}
34953499
return deletedVlans.second();
@@ -3512,6 +3516,23 @@ public List<VlanVO> doInTransaction(TransactionStatus status) {
35123516
return success;
35133517
}
35143518

3519+
/**
3520+
* If it is a shared network with {@link ACLType#Domain}, it will belong to account {@link Account#ACCOUNT_ID_SYSTEM} and the resources will be not incremented for the
3521+
* domain. Therefore, we force the recalculation of the domain's resource count in this case. Otherwise, it will change the count for the account owner.
3522+
* @param incrementAccountResourceCount If true, the account resource count will be incremented by 1; otherwise, it will decremented by 1.
3523+
*/
3524+
private void changeAccountResourceCountOrRecalculateDomainResourceCount(Long accountId, Long domainId, boolean displayNetwork, boolean incrementAccountResourceCount) {
3525+
if (Account.ACCOUNT_ID_SYSTEM == accountId && ObjectUtils.isNotEmpty(domainId)) {
3526+
_resourceLimitMgr.recalculateDomainResourceCount(domainId, ResourceType.network, null);
3527+
} else {
3528+
if (incrementAccountResourceCount) {
3529+
_resourceLimitMgr.incrementResourceCount(accountId, ResourceType.network, displayNetwork);
3530+
} else {
3531+
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.network, displayNetwork);
3532+
}
3533+
}
3534+
}
3535+
35153536
private void publishDeletedVlanRanges(List<VlanVO> deletedVlanRangeToPublish) {
35163537
if (CollectionUtils.isNotEmpty(deletedVlanRangeToPublish)) {
35173538
for (VlanVO vlan : deletedVlanRangeToPublish) {
@@ -3521,10 +3542,8 @@ private void publishDeletedVlanRanges(List<VlanVO> deletedVlanRangeToPublish) {
35213542
}
35223543

35233544
@Override
3524-
public boolean resourceCountNeedsUpdate(final NetworkOffering ntwkOff, final ACLType aclType) {
3525-
//Update resource count only for Isolated account specific non-system networks
3526-
final boolean updateResourceCount = ntwkOff.getGuestType() == GuestType.Isolated && !ntwkOff.isSystemOnly() && aclType == ACLType.Account;
3527-
return updateResourceCount;
3545+
public boolean isResourceCountUpdateNeeded(NetworkOffering networkOffering) {
3546+
return !networkOffering.isSystemOnly();
35283547
}
35293548

35303549
protected Pair<Boolean, List<VlanVO>> deleteVlansInNetwork(final NetworkVO network, final long userId, final Account callerAccount) {

server/src/main/java/com/cloud/network/NetworkServiceImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3197,7 +3197,7 @@ public Network updateGuestNetwork(final UpdateNetworkCmd cmd) {
31973197
if (displayNetwork != null && displayNetwork != network.getDisplayNetwork()) {
31983198
// Update resource count if it needs to be updated
31993199
NetworkOffering networkOffering = _networkOfferingDao.findById(network.getNetworkOfferingId());
3200-
if (_networkMgr.resourceCountNeedsUpdate(networkOffering, network.getAclType())) {
3200+
if (_networkMgr.isResourceCountUpdateNeeded(networkOffering)) {
32013201
_resourceLimitMgr.changeResourceCount(network.getAccountId(), Resource.ResourceType.network, displayNetwork);
32023202
}
32033203

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

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ public class CheckedReservation implements AutoCloseable {
4949

5050
ResourceLimitService resourceLimitService;
5151
private final Account account;
52+
private Long domainId;
5253
private final ResourceType resourceType;
5354
private Long amount;
5455
private List<ResourceReservation> reservations;
@@ -73,12 +74,12 @@ private void removeAllReservations() {
7374
this.reservations = null;
7475
}
7576

76-
protected void checkLimitAndPersistReservations(Account account, ResourceType resourceType, Long resourceId, List<String> resourceLimitTags, Long amount) throws ResourceAllocationException {
77+
protected void checkLimitAndPersistReservations(Account account, Long domainId, ResourceType resourceType, Long resourceId, List<String> resourceLimitTags, Long amount) throws ResourceAllocationException {
7778
try {
78-
checkLimitAndPersistReservation(account, resourceType, resourceId, null, amount);
79+
checkLimitAndPersistReservation(account, domainId, resourceType, resourceId, null, amount);
7980
if (CollectionUtils.isNotEmpty(resourceLimitTags)) {
8081
for (String tag : resourceLimitTags) {
81-
checkLimitAndPersistReservation(account, resourceType, resourceId, tag, amount);
82+
checkLimitAndPersistReservation(account, domainId, resourceType, resourceId, tag, amount);
8283
}
8384
}
8485
} catch (ResourceAllocationException rae) {
@@ -87,11 +88,11 @@ protected void checkLimitAndPersistReservations(Account account, ResourceType re
8788
}
8889
}
8990

90-
protected void checkLimitAndPersistReservation(Account account, ResourceType resourceType, Long resourceId, String tag, Long amount) throws ResourceAllocationException {
91+
protected void checkLimitAndPersistReservation(Account account, Long domainId, ResourceType resourceType, Long resourceId, String tag, Long amount) throws ResourceAllocationException {
9192
if (amount > 0) {
92-
resourceLimitService.checkResourceLimitWithTag(account, resourceType, tag, amount);
93+
resourceLimitService.checkResourceLimitWithTag(account, domainId, true, resourceType, tag, amount);
9394
}
94-
ReservationVO reservationVO = new ReservationVO(account.getAccountId(), account.getDomainId(), resourceType, tag, amount);
95+
ReservationVO reservationVO = new ReservationVO(account.getAccountId(), domainId, resourceType, tag, amount);
9596
if (resourceId != null) {
9697
reservationVO.setResourceId(resourceId);
9798
}
@@ -114,9 +115,20 @@ public CheckedReservation(Account account, ResourceType resourceType, List<Strin
114115
*/
115116
public CheckedReservation(Account account, ResourceType resourceType, Long resourceId, List<String> resourceLimitTags, Long amount,
116117
ReservationDao reservationDao, ResourceLimitService resourceLimitService) throws ResourceAllocationException {
118+
this(account, account.getDomainId(), resourceType, resourceId, resourceLimitTags, amount, reservationDao, resourceLimitService);
119+
}
120+
121+
public CheckedReservation(Account account, Long domainId, ResourceType resourceType, Long resourceId, List<String> resourceLimitTags, Long amount,
122+
ReservationDao reservationDao, ResourceLimitService resourceLimitService) throws ResourceAllocationException {
117123
this.reservationDao = reservationDao;
118124
this.resourceLimitService = resourceLimitService;
119125
this.account = account;
126+
127+
this.domainId = domainId;
128+
if (domainId == null) {
129+
this.domainId = account.getDomainId();
130+
}
131+
120132
this.resourceType = resourceType;
121133
this.amount = amount;
122134
this.reservations = new ArrayList<>();
@@ -127,7 +139,7 @@ public CheckedReservation(Account account, ResourceType resourceType, Long resou
127139
setGlobalLock();
128140
if (quotaLimitLock.lock(TRY_TO_GET_LOCK_TIME)) {
129141
try {
130-
checkLimitAndPersistReservations(account, resourceType, resourceId, resourceLimitTags, amount);
142+
checkLimitAndPersistReservations(account, this.domainId, resourceType, resourceId, resourceLimitTags, amount);
131143
CallContext.current().putContextParameter(getContextParameterKey(), getIds());
132144
} catch (NullPointerException npe) {
133145
throw new CloudRuntimeException("not enough means to check limits", npe);
@@ -138,11 +150,11 @@ public CheckedReservation(Account account, ResourceType resourceType, Long resou
138150
throw new ResourceAllocationException(String.format("unable to acquire resource reservation \"%s\"", quotaLimitLock.getName()), resourceType);
139151
}
140152
} else {
141-
checkLimitAndPersistReservations(account, resourceType, resourceId, resourceLimitTags, amount);
153+
checkLimitAndPersistReservations(account, this.domainId, resourceType, resourceId, resourceLimitTags, amount);
142154
}
143155
} else {
144156
logger.debug("not reserving any amount of resources for {} in domain {}, type: {}, tag: {}",
145-
account.getAccountName(), account.getDomainId(), resourceType, getResourceLimitTagsAsString());
157+
account.getAccountName(), this.domainId, resourceType, getResourceLimitTagsAsString());
146158
}
147159
}
148160

@@ -153,7 +165,7 @@ public CheckedReservation(Account account, ResourceType resourceType, Long amoun
153165

154166
@NotNull
155167
private void setGlobalLock() {
156-
String lockName = String.format("CheckedReservation-%s/%d", account.getDomainId(), resourceType.getOrdinal());
168+
String lockName = String.format("CheckedReservation-%s/%d", this.domainId, resourceType.getOrdinal());
157169
setQuotaLimitLock(GlobalLock.getInternLock(lockName));
158170
}
159171

0 commit comments

Comments
 (0)