Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion api/src/main/java/com/cloud/vm/UserVmService.java
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ UserVm createAdvancedVirtualMachine(DataCenter zone, ServiceOffering serviceOffe
* @throws ResourceUnavailableException
* if the resources required the deploy the VM is not currently available.
*/
UserVm startVirtualMachine(DeployVMCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException;
UserVm startVirtualMachine(DeployVMCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, ResourceAllocationException;

/**
* Creates a vm group.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,9 @@ public void execute() {
} catch (ResourceUnavailableException ex) {
s_logger.warn("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
} catch (ResourceAllocationException ex) {
s_logger.warn("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.RESOURCE_ALLOCATION_ERROR, ex.getMessage());
} catch (ConcurrentOperationException ex) {
s_logger.warn("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ public Long getInstanceId() {
}

@Override
public void execute() throws ResourceUnavailableException, ResourceAllocationException {
public void execute() {
try {
CallContext.current().setEventDetails("Vm Id: " + this._uuidMgr.getUuid(VirtualMachine.class, getId()));

Expand All @@ -177,6 +177,12 @@ public void execute() throws ResourceUnavailableException, ResourceAllocationExc
} catch (ExecutionException ex) {
s_logger.warn("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
} catch (ResourceUnavailableException ex) {
s_logger.warn("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
} catch (ResourceAllocationException ex) {
s_logger.warn("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.RESOURCE_ALLOCATION_ERROR, ex.getMessage());
} catch (InsufficientCapacityException ex) {
StringBuilder message = new StringBuilder(ex.getMessage());
if (ex instanceof InsufficientServerCapacityException) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ public interface VirtualMachineManager extends Manager {
ConfigKey<Boolean> VmConfigDriveOnPrimaryPool = new ConfigKey<>("Advanced", Boolean.class, "vm.configdrive.primarypool.enabled", "false",
"If config drive need to be created and hosted on primary storage pool. Currently only supported for KVM.", true);

ConfigKey<Boolean> ResoureCountRunningVMsonly = new ConfigKey<Boolean>("Advanced", Boolean.class, "resource.count.running.vms.only", "false",
"Count the resources of only running VMs in resource limitation.", true);

interface Topics {
String VM_POWER_STATE = "vm.powerstate";
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@
import com.cloud.agent.manager.allocator.HostAllocator;
import com.cloud.alert.AlertManager;
import com.cloud.capacity.CapacityManager;
import com.cloud.configuration.Resource.ResourceType;
import com.cloud.dc.ClusterDetailsDao;
import com.cloud.dc.ClusterDetailsVO;
import com.cloud.dc.DataCenter;
Expand Down Expand Up @@ -191,6 +192,7 @@
import com.cloud.storage.dao.VolumeDao;
import com.cloud.template.VirtualMachineTemplate;
import com.cloud.user.Account;
import com.cloud.user.ResourceLimitService;
import com.cloud.user.User;
import com.cloud.utils.DateUtil;
import com.cloud.utils.Journal;
Expand Down Expand Up @@ -302,6 +304,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
@Inject
private ResourceManager _resourceMgr;
@Inject
private ResourceLimitService _resourceLimitMgr;
@Inject
private VMSnapshotManager _vmSnapshotMgr;
@Inject
private ClusterDetailsDao _clusterDetailsDao;
Expand Down Expand Up @@ -970,6 +974,12 @@ public void orchestrateStart(final String vmUuid, final Map<VirtualMachineProfil

final HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vm.getHypervisorType());

// check resource count if ResoureCountRunningVMsonly.value() = true
final Account owner = _entityMgr.findById(Account.class, vm.getAccountId());
if (VirtualMachine.Type.User.equals(vm.type) && ResoureCountRunningVMsonly.value()) {
resourceCountIncrement(owner.getAccountId(),new Long(offering.getCpu()), new Long(offering.getRamSize()));
}

boolean canRetry = true;
ExcludeList avoids = null;
try {
Expand Down Expand Up @@ -1045,7 +1055,6 @@ public void orchestrateStart(final String vmUuid, final Map<VirtualMachineProfil
}
}

final Account owner = _entityMgr.findById(Account.class, vm.getAccountId());
final VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vm, template, offering, owner, params);
DeployDestination dest = null;
try {
Expand Down Expand Up @@ -1272,6 +1281,9 @@ public void orchestrateStart(final String vmUuid, final Map<VirtualMachineProfil
}
} finally {
if (startedVm == null) {
if (VirtualMachine.Type.User.equals(vm.type) && ResoureCountRunningVMsonly.value()) {
resourceCountDecrement(owner.getAccountId(),new Long(offering.getCpu()), new Long(offering.getRamSize()));
}
if (canRetry) {
try {
changeState(vm, Event.OperationFailed, null, work, Step.Done);
Expand Down Expand Up @@ -1817,7 +1829,14 @@ private void advanceStop(final VMInstanceVO vm, final boolean cleanUpEvenIfUnabl
_workDao.update(work.getId(), work);
}

if (!stateTransitTo(vm, Event.OperationSucceeded, null)) {
boolean result = stateTransitTo(vm, Event.OperationSucceeded, null);
if (result) {
if (VirtualMachine.Type.User.equals(vm.type) && ResoureCountRunningVMsonly.value()) {
//update resource count if stop successfully
ServiceOfferingVO offering = _offeringDao.findById(vm.getId(), vm.getServiceOfferingId());
resourceCountDecrement(vm.getAccountId(),new Long(offering.getCpu()), new Long(offering.getRamSize()));
}
} else {
throw new CloudRuntimeException("unable to stop " + vm);
}
} catch (final NoTransitionException e) {
Expand Down Expand Up @@ -4218,7 +4237,8 @@ public String getConfigComponentName() {
public ConfigKey<?>[] getConfigKeys() {
return new ConfigKey<?>[] {ClusterDeltaSyncInterval, StartRetry, VmDestroyForcestop, VmOpCancelInterval, VmOpCleanupInterval, VmOpCleanupWait,
VmOpLockStateRetry,
VmOpWaitInterval, ExecuteInSequence, VmJobCheckInterval, VmJobTimeout, VmJobStateReportInterval, VmConfigDriveLabel, VmConfigDriveOnPrimaryPool, HaVmRestartHostUp};
VmOpWaitInterval, ExecuteInSequence, VmJobCheckInterval, VmJobTimeout, VmJobStateReportInterval, VmConfigDriveLabel, VmConfigDriveOnPrimaryPool, HaVmRestartHostUp,
ResoureCountRunningVMsonly };
}

public List<StoragePoolAllocator> getStoragePoolAllocators() {
Expand Down Expand Up @@ -5338,4 +5358,17 @@ private VmWorkJobVO createPlaceHolderWork(final long instanceId) {

return workJob;
}

protected void resourceCountIncrement (long accountId, Long cpu, Long memory) {
_resourceLimitMgr.incrementResourceCount(accountId, ResourceType.user_vm);
_resourceLimitMgr.incrementResourceCount(accountId, ResourceType.cpu, cpu);
_resourceLimitMgr.incrementResourceCount(accountId, ResourceType.memory, memory);
}

protected void resourceCountDecrement (long accountId, Long cpu, Long memory) {
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.user_vm);
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.cpu, cpu);
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.memory, memory);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public interface UserVmDao extends GenericDao<UserVmVO, Long> {

List<Long> listPodIdsHavingVmsforAccount(long zoneId, long accountId);

public Long countAllocatedVMsForAccount(long accountId);
public Long countAllocatedVMsForAccount(long accountId, boolean runningVMsonly);

Hashtable<Long, UserVmData> listVmDetails(Hashtable<Long, UserVmData> userVmData);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -635,11 +635,14 @@ public String getQueryBatchAppender(int count) {
}

@Override
public Long countAllocatedVMsForAccount(long accountId) {
public Long countAllocatedVMsForAccount(long accountId, boolean runningVMsonly) {
SearchCriteria<Long> sc = CountByAccount.create();
sc.setParameters("account", accountId);
sc.setParameters("type", VirtualMachine.Type.User);
sc.setParameters("state", new Object[] {State.Destroyed, State.Error, State.Expunging});
if (runningVMsonly)
sc.setParameters("state", new Object[] {State.Destroyed, State.Error, State.Expunging, State.Stopped});
else
sc.setParameters("state", new Object[] {State.Destroyed, State.Error, State.Expunging});
sc.setParameters("displayVm", 1);
return customSearch(sc, null).get(0);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1376,6 +1376,9 @@ private boolean startNewVM(long vmId) {
} catch (final ResourceUnavailableException ex) {
s_logger.warn("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
} catch (ResourceAllocationException ex) {
s_logger.warn("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.RESOURCE_ALLOCATION_ERROR, ex.getMessage());
} catch (ConcurrentOperationException ex) {
s_logger.warn("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@
import org.springframework.stereotype.Component;

import com.cloud.alert.AlertManager;
import com.cloud.api.query.dao.UserVmJoinDao;
import com.cloud.api.query.vo.UserVmJoinVO;
import com.cloud.configuration.Config;
import com.cloud.configuration.Resource;
import com.cloud.configuration.Resource.ResourceOwnerType;
Expand Down Expand Up @@ -100,6 +102,8 @@
import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn;
import com.cloud.utils.db.TransactionStatus;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.VirtualMachineManager;
import com.cloud.vm.VirtualMachine.State;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.VMInstanceDao;

Expand Down Expand Up @@ -151,6 +155,8 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
private VlanDao _vlanDao;
@Inject
private SnapshotDataStoreDao _snapshotDataStoreDao;
@Inject
private UserVmJoinDao _userVmJoinDao;

protected GenericSearchBuilder<TemplateDataStoreVO, SumCount> templateSizeSearch;
protected GenericSearchBuilder<SnapshotDataStoreVO, SumCount> snapshotSizeSearch;
Expand Down Expand Up @@ -872,7 +878,7 @@ public Long doInTransaction(TransactionStatus status) {
protected long recalculateAccountResourceCount(final long accountId, final ResourceType type) {
final Long newCount;
if (type == Resource.ResourceType.user_vm) {
newCount = _userVmDao.countAllocatedVMsForAccount(accountId);
newCount = _userVmDao.countAllocatedVMsForAccount(accountId, VirtualMachineManager.ResoureCountRunningVMsonly.value());
} else if (type == Resource.ResourceType.volume) {
long virtualRouterCount = _vmDao.findIdsOfAllocatedVirtualRoutersForAccount(accountId).size();
newCount = _volumeDao.countAllocatedVolumesForAccount(accountId) - virtualRouterCount; // don't count the volumes of virtual router
Expand Down Expand Up @@ -929,11 +935,51 @@ public void doInTransactionWithoutResult(TransactionStatus status) {
}

public long countCpusForAccount(long accountId) {
return _resourceCountDao.countCpuNumberAllocatedToAccount(accountId);
long cputotal = 0;
// user vms
SearchBuilder<UserVmJoinVO> userVmSearch = _userVmJoinDao.createSearchBuilder();
userVmSearch.and("accountId", userVmSearch.entity().getAccountId(), Op.EQ);
userVmSearch.and("state", userVmSearch.entity().getState(), SearchCriteria.Op.NIN);
userVmSearch.and("displayVm", userVmSearch.entity().isDisplayVm(), Op.EQ);
userVmSearch.groupBy(userVmSearch.entity().getId()); // select distinct
userVmSearch.done();

SearchCriteria<UserVmJoinVO> sc1 = userVmSearch.create();
sc1.setParameters("accountId", accountId);
if (VirtualMachineManager.ResoureCountRunningVMsonly.value())
sc1.setParameters("state", new Object[] {State.Destroyed, State.Error, State.Expunging, State.Stopped});
else
sc1.setParameters("state", new Object[] {State.Destroyed, State.Error, State.Expunging});
sc1.setParameters("displayVm", 1);
List<UserVmJoinVO> userVms = _userVmJoinDao.search(sc1,null);
for (UserVmJoinVO vm : userVms) {
cputotal += Long.valueOf(vm.getCpu());
}
return cputotal;
}

public long calculateMemoryForAccount(long accountId) {
return _resourceCountDao.countMemoryAllocatedToAccount(accountId);
long ramtotal = 0;
// user vms
SearchBuilder<UserVmJoinVO> userVmSearch = _userVmJoinDao.createSearchBuilder();
userVmSearch.and("accountId", userVmSearch.entity().getAccountId(), Op.EQ);
userVmSearch.and("state", userVmSearch.entity().getState(), SearchCriteria.Op.NIN);
userVmSearch.and("displayVm", userVmSearch.entity().isDisplayVm(), Op.EQ);
userVmSearch.groupBy(userVmSearch.entity().getId()); // select distinct
userVmSearch.done();

SearchCriteria<UserVmJoinVO> sc1 = userVmSearch.create();
sc1.setParameters("accountId", accountId);
if (VirtualMachineManager.ResoureCountRunningVMsonly.value())
sc1.setParameters("state", new Object[] {State.Destroyed, State.Error, State.Expunging, State.Stopped});
else
sc1.setParameters("state", new Object[] {State.Destroyed, State.Error, State.Expunging});
sc1.setParameters("displayVm", 1);
List<UserVmJoinVO> userVms = _userVmJoinDao.search(sc1,null);
for (UserVmJoinVO vm : userVms) {
ramtotal += Long.valueOf(vm.getRamSize());
}
return ramtotal;
}

public long calculateSecondaryStorageForAccount(long accountId) {
Expand Down
5 changes: 3 additions & 2 deletions server/src/main/java/com/cloud/vm/UserVmManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.ManagementServerException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.exception.VirtualMachineMigrationException;
import com.cloud.offering.ServiceOffering;
Expand Down Expand Up @@ -99,10 +100,10 @@ public interface UserVmManager extends UserVmService {
boolean expunge(UserVmVO vm, long callerUserId, Account caller);

Pair<UserVmVO, Map<VirtualMachineProfile.Param, Object>> startVirtualMachine(long vmId, Long hostId, Map<VirtualMachineProfile.Param, Object> additionalParams, String deploymentPlannerToUse)
throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException;
throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException;

Pair<UserVmVO, Map<VirtualMachineProfile.Param, Object>> startVirtualMachine(long vmId, Long podId, Long clusterId, Long hostId, Map<VirtualMachineProfile.Param, Object> additionalParams, String deploymentPlannerToUse)
throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException;
throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException, ResourceAllocationException;

boolean upgradeVirtualMachine(Long id, Long serviceOfferingId, Map<String, String> customParameters) throws ResourceUnavailableException,
ConcurrentOperationException, ManagementServerException,
Expand Down
Loading