Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public class VirtualMachineTO {

private long minRam;
private long maxRam;
private long requestedRam;
private String hostName;
private String arch;
private String os;
Expand Down Expand Up @@ -207,15 +208,20 @@ public long getMinRam() {
return minRam;
}

public void setRam(long minRam, long maxRam) {
public void setRam(long minRam, long maxRam, long requestedRam) {
this.minRam = minRam;
this.maxRam = maxRam;
this.requestedRam = requestedRam;
}

public long getMaxRam() {
return maxRam;
}

public long getRequestedRam() {
return requestedRam;
}

public String getHostName() {
return hostName;
}
Expand Down
9 changes: 8 additions & 1 deletion core/src/main/java/com/cloud/agent/api/ScaleVmCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public class ScaleVmCommand extends Command {
Integer maxSpeed;
long minRam;
long maxRam;
private boolean limitCpuUseChange;

public VirtualMachineTO getVm() {
return vm;
Expand All @@ -43,7 +44,7 @@ public int getCpus() {
return cpus;
}

public ScaleVmCommand(String vmName, int cpus, Integer minSpeed, Integer maxSpeed, long minRam, long maxRam, boolean limitCpuUse) {
public ScaleVmCommand(String vmName, int cpus, Integer minSpeed, Integer maxSpeed, long minRam, long maxRam, boolean limitCpuUse, Double cpuQuotaPercentage, boolean limitCpuUseChange) {
super();
this.vmName = vmName;
this.cpus = cpus;
Expand All @@ -52,6 +53,8 @@ public ScaleVmCommand(String vmName, int cpus, Integer minSpeed, Integer maxSpee
this.minRam = minRam;
this.maxRam = maxRam;
this.vm = new VirtualMachineTO(1L, vmName, null, cpus, minSpeed, maxSpeed, minRam, maxRam, null, null, false, limitCpuUse, null);
this.vm.setCpuQuotaPercentage(cpuQuotaPercentage);
this.limitCpuUseChange = limitCpuUseChange;
}

public void setCpus(int cpus) {
Expand Down Expand Up @@ -102,6 +105,10 @@ public VirtualMachineTO getVirtualMachine() {
return vm;
}

public boolean getLimitCpuUseChange() {
return limitCpuUseChange;
}

@Override
public boolean executeInSequence() {
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,20 @@ public interface CapacityManager {
"capacity.calculate.workers", "1",
"Number of worker threads to be used for capacities calculation", true);

ConfigKey<Integer> KvmMemoryDynamicScalingCapacity = new ConfigKey<>(ConfigKey.CATEGORY_ADVANCED,
Integer.class, "kvm.memory.dynamic.scaling.capacity", "0",
"Defines the maximum memory capacity in MiB for which VMs can be dynamically scaled to with KVM. " +
"The 'kvm.memory.dynamic.scaling.capacity' setting's value will be used to define the value of the " +
"'<maxMemory />' element of domain XMLs. If it is set to a value less than or equal to '0', then the host's memory capacity will be considered.",
true, ConfigKey.Scope.Cluster);

ConfigKey<Integer> KvmCpuDynamicScalingCapacity = new ConfigKey<>(ConfigKey.CATEGORY_ADVANCED,
Integer.class, "kvm.cpu.dynamic.scaling.capacity", "0",
"Defines the maximum vCPU capacity for which VMs can be dynamically scaled to with KVM. " +
"The 'kvm.cpu.dynamic.scaling.capacity' setting's value will be used to define the value of the " +
"'<vcpu />' element of domain XMLs. If it is set to a value less than or equal to '0', then the host's CPU cores capacity will be considered.",
true, ConfigKey.Scope.Cluster);

public boolean releaseVmCapacity(VirtualMachine vm, boolean moveFromReserved, boolean moveToReservered, Long hostId);

void allocateVmCapacity(VirtualMachine vm, boolean fromLastHost);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
import javax.persistence.EntityExistsException;


import com.cloud.hypervisor.KVMGuru;
import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
import org.apache.cloudstack.annotation.AnnotationService;
import org.apache.cloudstack.annotation.dao.AnnotationDao;
Expand Down Expand Up @@ -5183,7 +5184,7 @@ public VMInstanceVO reConfigureVm(final String vmUuid, final ServiceOffering old
try {
result = retrieveResultFromJobOutcomeAndThrowExceptionIfNeeded(outcome);
} catch (Exception ex) {
throw new RuntimeException("Unhandled exception", ex);
throw new RuntimeException("Unable to reconfigure VM.", ex);
}

if (result != null) {
Expand All @@ -5196,22 +5197,29 @@ public VMInstanceVO reConfigureVm(final String vmUuid, final ServiceOffering old

private VMInstanceVO orchestrateReConfigureVm(String vmUuid, ServiceOffering oldServiceOffering, ServiceOffering newServiceOffering,
boolean reconfiguringOnExistingHost) throws ResourceUnavailableException, ConcurrentOperationException {
final VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
VMInstanceVO vm = _vmDao.findByUuid(vmUuid);

HostVO hostVo = _hostDao.findById(vm.getHostId());

Long clustedId = hostVo.getClusterId();
Float memoryOvercommitRatio = CapacityManager.MemOverprovisioningFactor.valueIn(clustedId);
Float cpuOvercommitRatio = CapacityManager.CpuOverprovisioningFactor.valueIn(clustedId);
boolean divideMemoryByOverprovisioning = HypervisorGuruBase.VmMinMemoryEqualsMemoryDividedByMemOverprovisioningFactor.valueIn(clustedId);
boolean divideCpuByOverprovisioning = HypervisorGuruBase.VmMinCpuSpeedEqualsCpuSpeedDividedByCpuOverprovisioningFactor.valueIn(clustedId);
Long clusterId = hostVo.getClusterId();
Float memoryOvercommitRatio = CapacityManager.MemOverprovisioningFactor.valueIn(clusterId);
Float cpuOvercommitRatio = CapacityManager.CpuOverprovisioningFactor.valueIn(clusterId);
boolean divideMemoryByOverprovisioning = HypervisorGuruBase.VmMinMemoryEqualsMemoryDividedByMemOverprovisioningFactor.valueIn(clusterId);
boolean divideCpuByOverprovisioning = HypervisorGuruBase.VmMinCpuSpeedEqualsCpuSpeedDividedByCpuOverprovisioningFactor.valueIn(clusterId);

int minMemory = (int)(newServiceOffering.getRamSize() / (divideMemoryByOverprovisioning ? memoryOvercommitRatio : 1));
int minSpeed = (int)(newServiceOffering.getSpeed() / (divideCpuByOverprovisioning ? cpuOvercommitRatio : 1));

ScaleVmCommand scaleVmCommand =
new ScaleVmCommand(vm.getInstanceName(), newServiceOffering.getCpu(), minSpeed,
newServiceOffering.getSpeed(), minMemory * 1024L * 1024L, newServiceOffering.getRamSize() * 1024L * 1024L, newServiceOffering.getLimitCpuUse());
Double cpuQuotaPercentage = null;
if (newServiceOffering.getLimitCpuUse() && vm.getHypervisorType().equals(HypervisorType.KVM)) {
KVMGuru kvmGuru = (KVMGuru) _hvGuruMgr.getGuru(vm.getHypervisorType());
cpuQuotaPercentage = kvmGuru.getCpuQuotaPercentage(minSpeed, hostVo.getSpeed());
}

boolean limitCpuUseChange = oldServiceOffering.getLimitCpuUse() != newServiceOffering.getLimitCpuUse();
ScaleVmCommand scaleVmCommand = new ScaleVmCommand(vm.getInstanceName(), newServiceOffering.getCpu(), minSpeed, newServiceOffering.getSpeed(),
minMemory * 1024L * 1024L, newServiceOffering.getRamSize() * 1024L * 1024L,
newServiceOffering.getLimitCpuUse(), cpuQuotaPercentage, limitCpuUseChange);

scaleVmCommand.getVirtualMachine().setId(vm.getId());
scaleVmCommand.getVirtualMachine().setUuid(vm.getUuid());
Expand Down Expand Up @@ -5240,16 +5248,20 @@ private VMInstanceVO orchestrateReConfigureVm(String vmUuid, ServiceOffering old
throw new CloudRuntimeException("Unable to scale vm due to " + (reconfigureAnswer == null ? "" : reconfigureAnswer.getDetails()));
}

upgradeVmDb(vm.getId(), newServiceOffering, oldServiceOffering);
if (reconfiguringOnExistingHost) {
_capacityMgr.releaseVmCapacity(vm, false, false, vm.getHostId());
}

boolean vmUpgraded = upgradeVmDb(vm.getId(), newServiceOffering, oldServiceOffering);
if (vmUpgraded) {
vm = _vmDao.findById(vm.getId());
}

if (vm.getType().equals(VirtualMachine.Type.User)) {
_userVmMgr.generateUsageEvent(vm, vm.isDisplayVm(), EventTypes.EVENT_VM_DYNAMIC_SCALE);
}

if (reconfiguringOnExistingHost) {
vm.setServiceOfferingId(oldServiceOffering.getId());
_capacityMgr.releaseVmCapacity(vm, false, false, vm.getHostId());
vm.setServiceOfferingId(newServiceOffering.getId());
_capacityMgr.allocateVmCapacity(vm, false);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,3 +117,21 @@ CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.vpc_offerings','conserve_mode', 'tin

--- Disable/enable NICs
CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.nics','enabled', 'TINYINT(1) NOT NULL DEFAULT 1 COMMENT ''Indicates whether the NIC is enabled or not'' ');

-- Creates the 'kvm.memory.dynamic.scaling.capacity' and, for already active ACS environments,
-- initializes it with the value of the setting 'vm.serviceoffering.ram.size.max'
INSERT INTO `cloud`.`configuration` (`category`, `instance`, `component`, `name`, `value`, `default_value`, `updated`, `scope`, `is_dynamic`, `group_id`, `subgroup_id`, `display_text`, `description`)
SELECT 'Advanced', 'DEFAULT', 'CapacityManager', 'kvm.memory.dynamic.scaling.capacity', `cfg`.`value`, 0, NULL, 4, 1, 6, 27,
'KVM memory dynamic scaling capacity', 'Defines the maximum memory capacity in MiB for which VMs can be dynamically scaled to with KVM. The ''kvm.memory.dynamic.scaling.capacity'' setting''s value will be used to define the value of the ''<maxMemory />'' element of domain XMLs. If it is set to a value less than or equal to ''0'', then the host''s memory capacity will be considered.'
FROM `cloud`.`configuration` `cfg`
WHERE NOT EXISTS (SELECT 1 FROM `cloud`.`configuration` WHERE `name` = 'kvm.memory.dynamic.scaling.capacity')
AND `cfg`.`name` = 'vm.serviceoffering.ram.size.max';

-- Creates the 'kvm.cpu.dynamic.scaling.capacity' and, for already active ACS environments,
-- initializes it with the value of the setting 'vm.serviceoffering.cpu.cores.max'
INSERT INTO `cloud`.`configuration` (`category`, `instance`, `component`, `name`, `value`, `default_value`, `updated`, `scope`, `is_dynamic`, `group_id`, `subgroup_id`, `display_text`, `description`)
SELECT 'Advanced', 'DEFAULT', 'CapacityManager', 'kvm.cpu.dynamic.scaling.capacity', `cfg`.`value`, 0, NULL, 4, 1, 6, 27,
'KVM CPU dynamic scaling capacity', 'Defines the maximum vCPU capacity for which VMs can be dynamically scaled to with KVM. The ''kvm.cpu.dynamic.scaling.capacity'' setting''s value will be used to define the value of the ''<vcpu />'' element of domain XMLs. If it is set to a value less than or equal to ''0'', then the host''s CPU cores capacity will be considered.'
FROM `cloud`.`configuration` `cfg`
WHERE NOT EXISTS (SELECT 1 FROM `cloud`.`configuration` WHERE `name` = 'kvm.cpu.dynamic.scaling.capacity')
AND `cfg`.`name` = 'vm.serviceoffering.cpu.cores.max';
Loading
Loading