Skip to content

Commit a178ff1

Browse files
author
SadiJr
committed
Merge branch 'kvm-live-scaling-vms-with-fixed-offerings' into '4.20.0.0-scclouds'
Escalonamento dinâmico de VMs com ofertas de serviço fixas com o KVM Closes #301 and #3080 See merge request scclouds/scclouds!1269
2 parents d3c5345 + 3d4f555 commit a178ff1

18 files changed

Lines changed: 219 additions & 224 deletions

File tree

api/src/main/java/com/cloud/agent/api/to/VirtualMachineTO.java

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ public class VirtualMachineTO {
4949

5050
private long minRam;
5151
private long maxRam;
52+
private long requestedRam;
5253
private String hostName;
5354
private String arch;
5455
private String os;
@@ -199,15 +200,20 @@ public long getMinRam() {
199200
return minRam;
200201
}
201202

202-
public void setRam(long minRam, long maxRam) {
203+
public void setRam(long minRam, long maxRam, long requestedRam) {
203204
this.minRam = minRam;
204205
this.maxRam = maxRam;
206+
this.requestedRam = requestedRam;
205207
}
206208

207209
public long getMaxRam() {
208210
return maxRam;
209211
}
210212

213+
public long getRequestedRam() {
214+
return requestedRam;
215+
}
216+
211217
public String getHostName() {
212218
return hostName;
213219
}
@@ -467,14 +473,6 @@ public void setMaxSpeed(Integer maxSpeed) {
467473
this.maxSpeed = maxSpeed;
468474
}
469475

470-
public void setMinRam(long minRam) {
471-
this.minRam = minRam;
472-
}
473-
474-
public void setMaxRam(long maxRam) {
475-
this.maxRam = maxRam;
476-
}
477-
478476
public boolean isLimitCpuUse() {
479477
return limitCpuUse;
480478
}

engine/components-api/src/main/java/com/cloud/capacity/CapacityManager.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,20 @@ public interface CapacityManager {
118118
"Percentage (as a value between 0 and 1) of secondary storage capacity threshold.",
119119
true);
120120

121+
ConfigKey<Integer> KVMMemoryDynamicScalingCapacity = new ConfigKey<>(ConfigKey.CATEGORY_ADVANCED,
122+
Integer.class, "kvm.memory.dynamic.scaling.capacity", "0",
123+
"Defines the maximum memory capacity in MiB for which VMs can be dynamically scaled to with KVM. " +
124+
"The 'kvm.memory.dynamic.scaling.capacity' setting's value will be used to define the value of the " +
125+
"'<maxMemory />' element of domain XMLs. If it is set to '0', then the host's memory capacity will be considered.",
126+
true, ConfigKey.Scope.Cluster);
127+
128+
ConfigKey<Integer> KVMCPUDynamicScalingCapacity = new ConfigKey<>(ConfigKey.CATEGORY_ADVANCED,
129+
Integer.class, "kvm.cpu.dynamic.scaling.capacity", "0",
130+
"Defines the maximum vCPU capacity for which VMs can be dynamically scaled to with KVM. " +
131+
"The 'kvm.cpu.dynamic.scaling.capacity' setting's value will be used to define the value of the " +
132+
"'<vcpu />' element of domain XMLs. If it is set to '0', then the host's CPU cores capacity will be considered.",
133+
true, ConfigKey.Scope.Cluster);
134+
121135
public boolean releaseVmCapacity(VirtualMachine vm, boolean moveFromReserved, boolean moveToReservered, Long hostId);
122136

123137
void allocateVmCapacity(VirtualMachine vm, boolean fromLastHost);

engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4709,7 +4709,7 @@ public VMInstanceVO reConfigureVm(final String vmUuid, final ServiceOffering old
47094709
try {
47104710
result = retrieveResultFromJobOutcomeAndThrowExceptionIfNeeded(outcome);
47114711
} catch (Exception ex) {
4712-
throw new RuntimeException("Unhandled exception", ex);
4712+
throw new RuntimeException("Unable to reconfigure VM.", ex);
47134713
}
47144714

47154715
if (result != null) {
@@ -4722,15 +4722,15 @@ public VMInstanceVO reConfigureVm(final String vmUuid, final ServiceOffering old
47224722

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

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

4729-
Long clustedId = hostVo.getClusterId();
4730-
Float memoryOvercommitRatio = CapacityManager.MemOverprovisioningFactor.valueIn(clustedId);
4731-
Float cpuOvercommitRatio = CapacityManager.CpuOverprovisioningFactor.valueIn(clustedId);
4732-
boolean divideMemoryByOverprovisioning = HypervisorGuruBase.VmMinMemoryEqualsMemoryDividedByMemOverprovisioningFactor.valueIn(clustedId);
4733-
boolean divideCpuByOverprovisioning = HypervisorGuruBase.VmMinCpuSpeedEqualsCpuSpeedDividedByCpuOverprovisioningFactor.valueIn(clustedId);
4729+
Long clusterId = hostVo.getClusterId();
4730+
Float memoryOvercommitRatio = CapacityManager.MemOverprovisioningFactor.valueIn(clusterId);
4731+
Float cpuOvercommitRatio = CapacityManager.CpuOverprovisioningFactor.valueIn(clusterId);
4732+
boolean divideMemoryByOverprovisioning = HypervisorGuruBase.VmMinMemoryEqualsMemoryDividedByMemOverprovisioningFactor.valueIn(clusterId);
4733+
boolean divideCpuByOverprovisioning = HypervisorGuruBase.VmMinCpuSpeedEqualsCpuSpeedDividedByCpuOverprovisioningFactor.valueIn(clusterId);
47344734

47354735
int minMemory = (int)(newServiceOffering.getRamSize() / (divideMemoryByOverprovisioning ? memoryOvercommitRatio : 1));
47364736
int minSpeed = (int)(newServiceOffering.getSpeed() / (divideCpuByOverprovisioning ? cpuOvercommitRatio : 1));
@@ -4766,7 +4766,10 @@ private VMInstanceVO orchestrateReConfigureVm(String vmUuid, ServiceOffering old
47664766
throw new CloudRuntimeException("Unable to scale vm due to " + (reconfigureAnswer == null ? "" : reconfigureAnswer.getDetails()));
47674767
}
47684768

4769-
upgradeVmDb(vm.getId(), newServiceOffering, oldServiceOffering);
4769+
boolean vmUpgraded = upgradeVmDb(vm.getId(), newServiceOffering, oldServiceOffering);
4770+
if (vmUpgraded) {
4771+
vm = _vmDao.findById(vm.getId());
4772+
}
47704773

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

engine/schema/src/main/resources/META-INF/db/schema-42005to42006.sql

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,17 @@ UPDATE `cloud_usage`.`account` account SET account.`type` = 'READ_ONLY_ADMIN' WH
4848
UPDATE `cloud_usage`.`account` account SET account.`type` = 'PROJECT' WHERE account.`type` = '5';
4949

5050
CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.backup_schedule', 'isolated', 'TINYINT(1) NOT NULL DEFAULT 0 COMMENT "Whether the scheduled backups will be isolated or not."');
51+
52+
INSERT INTO `cloud`.`configuration` (`category`, `instance`, `component`, `name`, `value`, `default_value`, `updated`, `scope`, `is_dynamic`, `group_id`, `subgroup_id`, `display_text`, `description`)
53+
SELECT 'Advanced', 'DEFAULT', 'CapacityManager', 'kvm.memory.dynamic.scaling.capacity', `cfg`.`value`,0, NULL, 'Cluster', 1, 6, 27,
54+
'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 ''0'', then the host''s memory capacity will be considered.'
55+
FROM `cloud`.`configuration` `cfg`
56+
WHERE NOT EXISTS (SELECT 1 FROM `cloud`.`configuration` WHERE `name` = 'kvm.memory.dynamic.scaling.capacity')
57+
AND `cfg`.`name` = 'vm.serviceoffering.ram.size.max';
58+
59+
INSERT INTO `cloud`.`configuration` (`category`, `instance`, `component`, `name`, `value`, `default_value`, `updated`, `scope`, `is_dynamic`, `group_id`, `subgroup_id`, `display_text`, `description`)
60+
SELECT 'Advanced', 'DEFAULT', 'CapacityManager', 'kvm.cpu.dynamic.scaling.capacity', `cfg`.`value`,0, NULL, 'Cluster', 1, 6, 27,
61+
'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 ''0'', then the host''s CPU cores capacity will be considered.'
62+
FROM `cloud`.`configuration` `cfg`
63+
WHERE NOT EXISTS (SELECT 1 FROM `cloud`.`configuration` WHERE `name` = 'kvm.cpu.dynamic.scaling.capacity')
64+
AND `cfg`.`name` = 'vm.serviceoffering.cpu.cores.max';

plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2971,10 +2971,11 @@ protected GuestResourceDef createGuestResourceDef(VirtualMachineTO vmTO){
29712971

29722972
grd.setMemBalloning(!noMemBalloon);
29732973

2974-
Long maxRam = ByteScaleUtils.bytesToKibibytes(vmTO.getMaxRam());
2975-
2976-
grd.setMemorySize(maxRam);
2977-
grd.setCurrentMem(getCurrentMemAccordingToMemBallooning(vmTO, maxRam));
2974+
long requestedRam = ByteScaleUtils.bytesToKibibytes(vmTO.getRequestedRam());
2975+
long minRam = ByteScaleUtils.bytesToKibibytes(vmTO.getMinRam());
2976+
grd.setMemorySize(requestedRam);
2977+
grd.setCurrentMem(getCurrentMemAccordingToMemBallooning(vmTO, requestedRam, minRam));
2978+
grd.setMaxMemory(ByteScaleUtils.bytesToKibibytes(vmTO.getMaxRam()));
29782979

29792980
int vcpus = vmTO.getCpus();
29802981
Integer maxVcpus = vmTO.getVcpuMaxLimit();
@@ -2985,18 +2986,19 @@ protected GuestResourceDef createGuestResourceDef(VirtualMachineTO vmTO){
29852986
return grd;
29862987
}
29872988

2988-
protected long getCurrentMemAccordingToMemBallooning(VirtualMachineTO vmTO, long maxRam) {
2989-
long retVal = maxRam;
2989+
protected long getCurrentMemAccordingToMemBallooning(VirtualMachineTO vmTO, long requestedRam, long minRam) {
29902990
if (noMemBalloon) {
2991-
LOGGER.warn(String.format("Setting VM's [%s] current memory as max memory [%s] due to memory ballooning is disabled. If you are using a custom service offering, verify if memory ballooning really should be disabled.", vmTO.toString(), maxRam));
2992-
} else if (vmTO != null && vmTO.getType() != VirtualMachine.Type.User) {
2993-
LOGGER.warn(String.format("Setting System VM's [%s] current memory as max memory [%s].", vmTO.toString(), maxRam));
2994-
} else {
2995-
long minRam = ByteScaleUtils.bytesToKibibytes(vmTO.getMinRam());
2996-
logger.debug(String.format("Setting VM's [%s] current memory as min memory [%s] due to memory ballooning is enabled.", vmTO.toString(), minRam));
2997-
retVal = minRam;
2991+
LOGGER.warn("Setting VM's [{}] current memory as requested memory [{}] due to memory ballooning is disabled.", vmTO.toString(), requestedRam);
2992+
return requestedRam;
29982993
}
2999-
return retVal;
2994+
2995+
if (vmTO != null && vmTO.getType() != VirtualMachine.Type.User) {
2996+
LOGGER.warn("Setting System VM's [{}] current memory as requested memory [{}].", vmTO.toString(), requestedRam);
2997+
return requestedRam;
2998+
}
2999+
3000+
LOGGER.debug("Setting VM's [{}] current memory as min memory [{}] due to memory ballooning is enabled.", vmTO.toString(), minRam);
3001+
return minRam;
30003002
}
30013003

30023004
/**

plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ public String toString() {
270270
public static class GuestResourceDef {
271271
private long memory;
272272
private long currentMemory = -1;
273+
private long maxMemory;
273274
private int vcpu = -1;
274275
private int maxVcpu = -1;
275276
private boolean memoryBalloning = false;
@@ -283,6 +284,10 @@ public void setCurrentMem(long currMem) {
283284
this.currentMemory = currMem;
284285
}
285286

287+
public void setMaxMemory(long maxMemory) {
288+
this.maxMemory = maxMemory;
289+
}
290+
286291
public void setVcpuNum(int vcpu) {
287292
this.vcpu = vcpu;
288293
}
@@ -306,12 +311,12 @@ public void setMemBalloning(boolean memoryBalloning) {
306311
@Override
307312
public String toString() {
308313
StringBuilder response = new StringBuilder();
309-
response.append(String.format("<memory>%s</memory>\n", this.currentMemory));
314+
response.append(String.format("<memory>%s</memory>\n", this.memory));
310315
response.append(String.format("<currentMemory>%s</currentMemory>\n", this.currentMemory));
311316

312-
if (this.memory > this.currentMemory) {
313-
response.append(String.format("<maxMemory slots='16' unit='KiB'>%s</maxMemory>\n", this.memory));
314-
response.append(String.format("<cpu> <numa> <cell id='0' cpus='0-%s' memory='%s' unit='KiB'/> </numa> </cpu>\n", this.maxVcpu - 1, this.currentMemory));
317+
if (this.maxMemory > this.memory) {
318+
response.append(String.format("<maxMemory slots='16' unit='KiB'>%s</maxMemory>\n", this.maxMemory));
319+
response.append(String.format("<cpu> <numa> <cell id='0' cpus='0-%s' memory='%s' unit='KiB'/> </numa> </cpu>\n", this.maxVcpu - 1, this.memory));
315320
}
316321

317322
MemBalloonDef memBalloonDef = new MemBalloonDef();

0 commit comments

Comments
 (0)