Merge release branch 4.18 to main

* 4.18:
  Allow KVM overcommit to work without reducing minimum VM memory when vm ballooning is disabled (#7810)
This commit is contained in:
Daan Hoogland 2023-08-06 10:41:00 +02:00
commit eb31e3d795
4 changed files with 24 additions and 22 deletions

View File

@ -2791,15 +2791,10 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
grd.setMemBalloning(!_noMemBalloon); grd.setMemBalloning(!_noMemBalloon);
long maxRam = ByteScaleUtils.bytesToKibibytes(vmTO.getMaxRam()); Long maxRam = ByteScaleUtils.bytesToKibibytes(vmTO.getMaxRam());
long currRam = vmTO.getType() == VirtualMachine.Type.User ? getCurrentMemAccordingToMemBallooning(vmTO, maxRam) : maxRam;
if (s_logger.isTraceEnabled()) {
s_logger.trace(String.format("memory values for VM %s are %d/%d",vmTO.getName(),maxRam, currRam));
}
grd.setMemorySize(maxRam); grd.setMemorySize(maxRam);
grd.setCurrentMem(currRam); grd.setCurrentMem(getCurrentMemAccordingToMemBallooning(vmTO, maxRam));
int vcpus = vmTO.getCpus(); int vcpus = vmTO.getCpus();
Integer maxVcpus = vmTO.getVcpuMaxLimit(); Integer maxVcpus = vmTO.getVcpuMaxLimit();
@ -2811,12 +2806,17 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
} }
protected long getCurrentMemAccordingToMemBallooning(VirtualMachineTO vmTO, long maxRam) { protected long getCurrentMemAccordingToMemBallooning(VirtualMachineTO vmTO, long maxRam) {
long retVal = maxRam;
if (_noMemBalloon) { if (_noMemBalloon) {
s_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)); s_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));
return maxRam; } else if (vmTO != null && vmTO.getType() != VirtualMachine.Type.User) {
s_logger.warn(String.format("Setting System VM's [%s] current memory as max memory [%s].", vmTO.toString(), maxRam));
} else { } else {
return ByteScaleUtils.bytesToKibibytes(vmTO.getMinRam()); long minRam = ByteScaleUtils.bytesToKibibytes(vmTO.getMinRam());
s_logger.debug(String.format("Setting VM's [%s] current memory as min memory [%s] due to memory ballooning is enabled.", vmTO.toString(), minRam));
retVal = minRam;
} }
return retVal;
} }
/** /**

View File

@ -282,7 +282,7 @@ public class LibvirtVMDef {
@Override @Override
public String toString() { public String toString() {
StringBuilder response = new StringBuilder(); StringBuilder response = new StringBuilder();
response.append(String.format("<memory>%s</memory>\n", this.memory)); response.append(String.format("<memory>%s</memory>\n", this.currentMemory));
response.append(String.format("<currentMemory>%s</currentMemory>\n", this.currentMemory)); response.append(String.format("<currentMemory>%s</currentMemory>\n", this.currentMemory));
if (this.memory > this.currentMemory) { if (this.memory > this.currentMemory) {
@ -1238,7 +1238,7 @@ public class LibvirtVMDef {
@Override @Override
public String toString() { public String toString() {
StringBuilder memBalloonBuilder = new StringBuilder(); StringBuilder memBalloonBuilder = new StringBuilder();
memBalloonBuilder.append("<memballoon model='" + memBalloonModel + "' autodeflate='on'>\n"); memBalloonBuilder.append("<memballoon model='" + memBalloonModel + "'>\n");
if (StringUtils.isNotBlank(memBalloonStatsPeriod)) { if (StringUtils.isNotBlank(memBalloonStatsPeriod)) {
memBalloonBuilder.append("<stats period='" + memBalloonStatsPeriod +"'/>\n"); memBalloonBuilder.append("<stats period='" + memBalloonStatsPeriod +"'/>\n");
} }

View File

@ -760,7 +760,7 @@ public class LibvirtComputingResourceTest {
private void verifyMemory(VirtualMachineTO to, Document domainDoc, String minRam) { private void verifyMemory(VirtualMachineTO to, Document domainDoc, String minRam) {
assertXpath(domainDoc, "/domain/maxMemory/text()", String.valueOf( to.getMaxRam() / 1024 )); assertXpath(domainDoc, "/domain/maxMemory/text()", String.valueOf( to.getMaxRam() / 1024 ));
assertXpath(domainDoc, "/domain/currentMemory/text()",minRam); assertXpath(domainDoc, "/domain/memory/text()",minRam);
assertXpath(domainDoc, "/domain/cpu/numa/cell/@memory", minRam); assertXpath(domainDoc, "/domain/cpu/numa/cell/@memory", minRam);
assertXpath(domainDoc, "/domain/currentMemory/text()", minRam); assertXpath(domainDoc, "/domain/currentMemory/text()", minRam);
} }
@ -5762,6 +5762,7 @@ public class LibvirtComputingResourceTest {
public void validateGetCurrentMemAccordingToMemBallooningWithoutMemBalooning(){ public void validateGetCurrentMemAccordingToMemBallooningWithoutMemBalooning(){
VirtualMachineTO vmTo = Mockito.mock(VirtualMachineTO.class); VirtualMachineTO vmTo = Mockito.mock(VirtualMachineTO.class);
Mockito.when(vmTo.getType()).thenReturn(Type.User);
LibvirtComputingResource libvirtComputingResource = new LibvirtComputingResource(); LibvirtComputingResource libvirtComputingResource = new LibvirtComputingResource();
libvirtComputingResource._noMemBalloon = true; libvirtComputingResource._noMemBalloon = true;
long maxMemory = 2048; long maxMemory = 2048;
@ -5780,6 +5781,7 @@ public class LibvirtComputingResourceTest {
long minMemory = ByteScaleUtils.mebibytesToBytes(64); long minMemory = ByteScaleUtils.mebibytesToBytes(64);
VirtualMachineTO vmTo = Mockito.mock(VirtualMachineTO.class); VirtualMachineTO vmTo = Mockito.mock(VirtualMachineTO.class);
Mockito.when(vmTo.getType()).thenReturn(Type.User);
Mockito.when(vmTo.getMinRam()).thenReturn(minMemory); Mockito.when(vmTo.getMinRam()).thenReturn(minMemory);
long currentMemory = libvirtComputingResource.getCurrentMemAccordingToMemBallooning(vmTo, maxMemory); long currentMemory = libvirtComputingResource.getCurrentMemAccordingToMemBallooning(vmTo, maxMemory);

View File

@ -266,11 +266,11 @@ public class LibvirtVMDefTest extends TestCase {
assertEquals(bus, disk.getBusType()); assertEquals(bus, disk.getBusType());
assertEquals(DiskDef.DeviceType.DISK, disk.getDeviceType()); assertEquals(DiskDef.DeviceType.DISK, disk.getDeviceType());
String resultingXml = disk.toString(); String xmlDef = disk.toString();
String expectedXml = "<disk device='disk' type='file'>\n<driver name='qemu' type='" + type.toString() + "' cache='" + cacheMode.toString() + "' />\n" + String expectedXml = "<disk device='disk' type='file'>\n<driver name='qemu' type='" + type.toString() + "' cache='" + cacheMode.toString() + "' />\n" +
"<source file='" + filePath + "'/>\n<target dev='" + diskLabel + "' bus='" + bus.toString() + "'/>\n</disk>\n"; "<source file='" + filePath + "'/>\n<target dev='" + diskLabel + "' bus='" + bus.toString() + "'/>\n</disk>\n";
assertEquals(expectedXml, resultingXml); assertEquals(expectedXml, xmlDef);
} }
@Test @Test
@ -398,7 +398,7 @@ public class LibvirtVMDefTest extends TestCase {
LibvirtVMDef.setGlobalQemuVersion(2006000L); LibvirtVMDef.setGlobalQemuVersion(2006000L);
LibvirtVMDef.setGlobalLibvirtVersion(9008L); LibvirtVMDef.setGlobalLibvirtVersion(9008L);
String resultingXml = disk.toString(); String xmlDef = disk.toString();
String expectedXml = "<disk device='disk' type='file'>\n<driver name='qemu' type='" + type.toString() + "' cache='none' />\n" + String expectedXml = "<disk device='disk' type='file'>\n<driver name='qemu' type='" + type.toString() + "' cache='none' />\n" +
"<source file='" + filePath + "'/>\n<target dev='" + diskLabel + "' bus='" + bus.toString() + "'/>\n" + "<source file='" + filePath + "'/>\n<target dev='" + diskLabel + "' bus='" + bus.toString() + "'/>\n" +
"<iotune>\n<read_bytes_sec>"+bytesReadRate+"</read_bytes_sec>\n<write_bytes_sec>"+bytesWriteRate+"</write_bytes_sec>\n" + "<iotune>\n<read_bytes_sec>"+bytesReadRate+"</read_bytes_sec>\n<write_bytes_sec>"+bytesWriteRate+"</write_bytes_sec>\n" +
@ -408,29 +408,29 @@ public class LibvirtVMDefTest extends TestCase {
"<read_bytes_sec_max_length>"+bytesReadRateMaxLength+"</read_bytes_sec_max_length>\n<write_bytes_sec_max_length>"+bytesWriteRateMaxLength+"</write_bytes_sec_max_length>\n" + "<read_bytes_sec_max_length>"+bytesReadRateMaxLength+"</read_bytes_sec_max_length>\n<write_bytes_sec_max_length>"+bytesWriteRateMaxLength+"</write_bytes_sec_max_length>\n" +
"<read_iops_sec_max_length>"+iopsReadRateMaxLength+"</read_iops_sec_max_length>\n<write_iops_sec_max_length>"+iopsWriteRateMaxLength+"</write_iops_sec_max_length>\n</iotune>\n</disk>\n"; "<read_iops_sec_max_length>"+iopsReadRateMaxLength+"</read_iops_sec_max_length>\n<write_iops_sec_max_length>"+iopsWriteRateMaxLength+"</write_iops_sec_max_length>\n</iotune>\n</disk>\n";
assertEquals(expectedXml, resultingXml); assertEquals(expectedXml, xmlDef);
} }
@Test @Test
public void memBalloonDefTestNone() { public void memBalloonDefTestNone() {
String expectedXml = "<memballoon model='none' autodeflate='on'>\n</memballoon>"; String expectedXml = "<memballoon model='none'>\n</memballoon>";
MemBalloonDef memBalloonDef = new MemBalloonDef(); MemBalloonDef memBalloonDef = new MemBalloonDef();
memBalloonDef.defNoneMemBalloon(); memBalloonDef.defNoneMemBalloon();
String resultingXml = memBalloonDef.toString(); String xmlDef = memBalloonDef.toString();
assertEquals(expectedXml, resultingXml); assertEquals(expectedXml, xmlDef);
} }
@Test @Test
public void memBalloonDefTestVirtio() { public void memBalloonDefTestVirtio() {
String expectedXml = "<memballoon model='virtio' autodeflate='on'>\n<stats period='60'/>\n</memballoon>"; String expectedXml = "<memballoon model='virtio'>\n<stats period='60'/>\n</memballoon>";
MemBalloonDef memBalloonDef = new MemBalloonDef(); MemBalloonDef memBalloonDef = new MemBalloonDef();
memBalloonDef.defVirtioMemBalloon("60"); memBalloonDef.defVirtioMemBalloon("60");
String resultingXml = memBalloonDef.toString(); String xmlDef = memBalloonDef.toString();
assertEquals(expectedXml, resultingXml); assertEquals(expectedXml, xmlDef);
} }
@Test @Test