diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java index 02cf872d927..0f8e9edb9f2 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java @@ -52,15 +52,17 @@ import org.apache.cloudstack.utils.linux.MemStat; import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; +import org.apache.commons.lang.ArrayUtils; +import org.apache.commons.lang.math.NumberUtils; import org.apache.log4j.Logger; import org.libvirt.Connect; import org.libvirt.Domain; import org.libvirt.DomainBlockStats; import org.libvirt.DomainInfo; -import org.libvirt.MemoryStatistic; import org.libvirt.DomainInfo.DomainState; import org.libvirt.DomainInterfaceStats; import org.libvirt.LibvirtException; +import org.libvirt.MemoryStatistic; import org.libvirt.NodeInfo; import com.cloud.agent.api.Answer; @@ -189,7 +191,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv private String _clusterId; private long _hvVersion; - private long _kernelVersion; private int _timeout; private static final int NUMMEMSTATS =2; @@ -958,13 +959,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv storageProcessor.configure(name, params); storageHandler = new StorageSubsystemCommandHandlerBase(storageProcessor); - final String unameKernelVersion = Script.runSimpleBashScript("uname -r"); - final String[] kernelVersions = unameKernelVersion.split("[\\.\\-]"); - _kernelVersion = Integer.parseInt(kernelVersions[0]) * 1000 * 1000 + (long)Integer.parseInt(kernelVersions[1]) * 1000 + Integer.parseInt(kernelVersions[2]); - - /* Disable this, the code using this is pretty bad and non portable - * getOsVersion(); - */ return true; } @@ -3020,9 +3014,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv long _ioWrote; long _bytesRead; long _bytesWrote; - long _intmemfree; - long _memory; - long _maxmemory; Calendar _timestamp; } @@ -3030,9 +3021,10 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv Domain dm = null; try { dm = getDomain(conn, vmName); - final DomainInfo info = dm.getInfo(); - final MemoryStatistic[] mems = dm.memoryStats(NUMMEMSTATS); //number of memory statistics required. - + if (dm == null) { + return null; + } + DomainInfo info = dm.getInfo(); final VmStatsEntry stats = new VmStatsEntry(); stats.setNumCPUs(info.nrVirtCpu); @@ -3040,7 +3032,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv stats.setMemoryKBs(info.maxMem); stats.setTargetMemoryKBs(info.memory); - stats.setIntFreeMemoryKBs((double) mems[0].getValue()); + stats.setIntFreeMemoryKBs(getMemoryFreeInKBs(dm)); + /* get cpu utilization */ VmStats oldStats = null; @@ -3125,9 +3118,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv newStat._bytesRead = bytes_rd; newStat._bytesWrote = bytes_wr; newStat._timestamp = now; - newStat._intmemfree = mems[0].getValue(); - newStat._memory = info.memory; - newStat._maxmemory = info.maxMem; _vmStats.put(vmName, newStat); return stats; } finally { @@ -3137,6 +3127,21 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv } } + /** + * This method retrieves the memory statistics from the domain given as parameters. + * If no memory statistic is found, it will return {@link NumberUtils#LONG_ZERO} as the value of free memory in the domain. + * If it can retrieve the domain memory statistics, it will return the free memory statistic; that means, it returns the value at the first position of the array returned by {@link Domain#memoryStats(int)}. + * + * @return the amount of free memory in KBs + */ + protected long getMemoryFreeInKBs(Domain dm) throws LibvirtException { + MemoryStatistic[] mems = dm.memoryStats(NUMMEMSTATS); + if (ArrayUtils.isEmpty(mems)) { + return NumberUtils.LONG_ZERO; + } + return mems[0].getValue(); + } + private boolean canBridgeFirewall(final String prvNic) { final Script cmd = new Script(_securityGroupPath, _timeout, s_logger); cmd.add("can_bridge_firewall"); diff --git a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java b/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java index 391313e191f..488325ea811 100644 --- a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java +++ b/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java @@ -65,10 +65,10 @@ import org.libvirt.DomainInfo; import org.libvirt.DomainInfo.DomainState; import org.libvirt.DomainInterfaceStats; import org.libvirt.LibvirtException; +import org.libvirt.MemoryStatistic; import org.libvirt.NodeInfo; import org.libvirt.StorageVol; -import org.libvirt.MemoryStatistic; - +import org.libvirt.jna.virDomainMemoryStats; import org.mockito.Matchers; import org.mockito.Mock; import org.mockito.Mockito; @@ -182,8 +182,8 @@ public class LibvirtComputingResourceTest { @Mock private LibvirtComputingResource libvirtComputingResource; - String _hyperVisorType = "kvm"; - Random _random = new Random(); + String hyperVisorType = "kvm"; + Random random = new Random(); /** This test tests if the Agent can handle a vmSpec coming @@ -194,10 +194,10 @@ public class LibvirtComputingResourceTest { */ @Test public void testCreateVMFromSpecLegacy() { - final int id = _random.nextInt(65534); + final int id = random.nextInt(65534); final String name = "test-instance-1"; - final int cpus = _random.nextInt(2) + 1; + final int cpus = random.nextInt(2) + 1; final int speed = 1024; final int minRam = 256 * 1024; final int maxRam = 512 * 1024; @@ -213,7 +213,7 @@ public class LibvirtComputingResourceTest { to.setUuid("b0f0a72d-7efb-3cad-a8ff-70ebf30b3af9"); final LibvirtVMDef vm = lcr.createVMFromSpec(to); - vm.setHvsType(_hyperVisorType); + vm.setHvsType(hyperVisorType); verifyVm(to, vm); } @@ -223,7 +223,7 @@ public class LibvirtComputingResourceTest { */ @Test public void testCreateVMFromSpecWithTopology6() { - final int id = _random.nextInt(65534); + final int id = random.nextInt(65534); final String name = "test-instance-1"; final int cpus = 12; @@ -243,7 +243,7 @@ public class LibvirtComputingResourceTest { to.setUuid("b0f0a72d-7efb-3cad-a8ff-70ebf30b3af9"); final LibvirtVMDef vm = lcr.createVMFromSpec(to); - vm.setHvsType(_hyperVisorType); + vm.setHvsType(hyperVisorType); verifyVm(to, vm); } @@ -253,7 +253,7 @@ public class LibvirtComputingResourceTest { */ @Test public void testCreateVMFromSpecWithTopology4() { - final int id = _random.nextInt(65534); + final int id = random.nextInt(65534); final String name = "test-instance-1"; final int cpus = 8; @@ -273,7 +273,7 @@ public class LibvirtComputingResourceTest { to.setUuid("b0f0a72d-7efb-3cad-a8ff-70ebf30b3af9"); final LibvirtVMDef vm = lcr.createVMFromSpec(to); - vm.setHvsType(_hyperVisorType); + vm.setHvsType(hyperVisorType); verifyVm(to, vm); } @@ -287,10 +287,10 @@ public class LibvirtComputingResourceTest { */ @Test public void testCreateVMFromSpec() { - final int id = _random.nextInt(65534); + final int id = random.nextInt(65534); final String name = "test-instance-1"; - final int cpus = _random.nextInt(2) + 1; + final int cpus = random.nextInt(2) + 1; final int minSpeed = 1024; final int maxSpeed = 2048; final int minRam = 256 * 1024; @@ -308,7 +308,7 @@ public class LibvirtComputingResourceTest { to.setUuid("b0f0a72d-7efb-3cad-a8ff-70ebf30b3af9"); final LibvirtVMDef vm = lcr.createVMFromSpec(to); - vm.setHvsType(_hyperVisorType); + vm.setHvsType(hyperVisorType); verifyVm(to, vm); } @@ -718,10 +718,9 @@ public class LibvirtComputingResourceTest { } } - @SuppressWarnings("unchecked") @Test + @SuppressWarnings("unchecked") public void testGetVmDiskStatsCommandException() { - Mockito.mock(Connect.class); final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class); final String vmName = "Test"; @@ -941,7 +940,6 @@ public class LibvirtComputingResourceTest { public void testGetHostStatsCommand() { // A bit difficult to test due to the logger being passed and the parser itself relying on the connection. // Have to spend some more time afterwards in order to refactor the wrapper itself. - Mockito.mock(LibvirtUtilitiesHelper.class); final CPUStat cpuStat = Mockito.mock(CPUStat.class); final MemStat memStat = Mockito.mock(MemStat.class); @@ -3531,7 +3529,6 @@ public class LibvirtComputingResourceTest { verify(libvirtComputingResource, times(1)).configureVPCNetworkUsage(command.getPrivateIP(), command.getGatewayIP(), command.getOption(), command.getVpcCIDR()); } - @SuppressWarnings("unchecked") @Test public void testCreatePrivateTemplateFromVolumeCommand() { //Simple test used to make sure the flow (LibvirtComputingResource => Request => CommandWrapper) is working. @@ -5040,4 +5037,40 @@ public class LibvirtComputingResourceTest { } } } + + @Test + public void testMemoryFreeInKBsDomainReturningOfSomeMemoryStatistics() throws LibvirtException { + LibvirtComputingResource libvirtComputingResource = new LibvirtComputingResource(); + + MemoryStatistic[] mem = createMemoryStatisticFreeMemory100(); + Domain domainMock = getDomainConfiguredToReturnMemoryStatistic(mem); + long memoryFreeInKBs = libvirtComputingResource.getMemoryFreeInKBs(domainMock); + + Assert.assertEquals(100, memoryFreeInKBs); + } + + @Test + public void testMemoryFreeInKBsDomainReturningNoMemoryStatistics() throws LibvirtException { + LibvirtComputingResource libvirtComputingResource = new LibvirtComputingResource(); + + Domain domainMock = getDomainConfiguredToReturnMemoryStatistic(null); + long memoryFreeInKBs = libvirtComputingResource.getMemoryFreeInKBs(domainMock); + + Assert.assertEquals(0, memoryFreeInKBs); + } + + private MemoryStatistic[] createMemoryStatisticFreeMemory100() { + virDomainMemoryStats stat = new virDomainMemoryStats(); + stat.val = 100; + + MemoryStatistic[] mem = new MemoryStatistic[2]; + mem[0] = new MemoryStatistic(stat); + return mem; + } + + private Domain getDomainConfiguredToReturnMemoryStatistic(MemoryStatistic[] mem) throws LibvirtException { + Domain domainMock = Mockito.mock(Domain.class); + when(domainMock.memoryStats(2)).thenReturn(mem); + return domainMock; + } } diff --git a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java index 6da2c7b02a3..efc3f81ed19 100644 --- a/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java @@ -184,6 +184,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } } + private final static int BASE_TO_CONVERT_BYTES_INTO_KILOBYTES = 1024; + protected static final XenServerConnectionPool ConnPool = XenServerConnectionPool.getInstance(); // static min values for guests on xenserver private static final long mem_128m = 134217728L; @@ -3323,19 +3325,19 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe vmStatsAnswer.setNumCPUs(vmStatsAnswer.getNumCPUs() + 1); vmStatsAnswer.setCPUUtilization(vmStatsAnswer.getCPUUtilization() + getDataAverage(dataNode, col, numRows)); } else if (param.matches("vif_\\d*_rx")) { - vmStatsAnswer.setNetworkReadKBs(vmStatsAnswer.getNetworkReadKBs() + getDataAverage(dataNode, col, numRows) / 1000); + vmStatsAnswer.setNetworkReadKBs(vmStatsAnswer.getNetworkReadKBs() + getDataAverage(dataNode, col, numRows) / BASE_TO_CONVERT_BYTES_INTO_KILOBYTES); } else if (param.matches("vif_\\d*_tx")) { - vmStatsAnswer.setNetworkWriteKBs(vmStatsAnswer.getNetworkWriteKBs() + getDataAverage(dataNode, col, numRows) / 1000); + vmStatsAnswer.setNetworkWriteKBs(vmStatsAnswer.getNetworkWriteKBs() + getDataAverage(dataNode, col, numRows) / BASE_TO_CONVERT_BYTES_INTO_KILOBYTES); } else if (param.matches("vbd_.*_read")) { - vmStatsAnswer.setDiskReadKBs(vmStatsAnswer.getDiskReadKBs() + getDataAverage(dataNode, col, numRows) / 1000); + vmStatsAnswer.setDiskReadKBs(vmStatsAnswer.getDiskReadKBs() + getDataAverage(dataNode, col, numRows) / BASE_TO_CONVERT_BYTES_INTO_KILOBYTES); } else if (param.matches("vbd_.*_write")) { - vmStatsAnswer.setDiskWriteKBs(vmStatsAnswer.getDiskWriteKBs() + getDataAverage(dataNode, col, numRows) / 1000); + vmStatsAnswer.setDiskWriteKBs(vmStatsAnswer.getDiskWriteKBs() + getDataAverage(dataNode, col, numRows) / BASE_TO_CONVERT_BYTES_INTO_KILOBYTES); } else if (param.contains("memory_internal_free")) { - vmStatsAnswer.setIntFreeMemoryKBs(vmStatsAnswer.getIntFreeMemoryKBs() + getDataAverage(dataNode, col, numRows) / 1024); + vmStatsAnswer.setIntFreeMemoryKBs(vmStatsAnswer.getIntFreeMemoryKBs() + getDataAverage(dataNode, col, numRows) / BASE_TO_CONVERT_BYTES_INTO_KILOBYTES); } else if (param.contains("memory_target")) { - vmStatsAnswer.setTargetMemoryKBs(vmStatsAnswer.getTargetMemoryKBs() + getDataAverage(dataNode, col, numRows) / 1024); + vmStatsAnswer.setTargetMemoryKBs(vmStatsAnswer.getTargetMemoryKBs() + getDataAverage(dataNode, col, numRows) / BASE_TO_CONVERT_BYTES_INTO_KILOBYTES); } else if (param.contains("memory")) { - vmStatsAnswer.setMemoryKBs(vmStatsAnswer.getMemoryKBs() + getDataAverage(dataNode, col, numRows) / 1024); + vmStatsAnswer.setMemoryKBs(vmStatsAnswer.getMemoryKBs() + getDataAverage(dataNode, col, numRows) / BASE_TO_CONVERT_BYTES_INTO_KILOBYTES); } }