Bug-ID: CLOUDSTACK-8880: calculate free memory on host before deploying Vm. free memory = total memory - (all vm memory)

This commit is contained in:
Kishan Kavala 2017-02-20 11:31:45 +05:30
parent 8bd33d3db6
commit 9a021904af
3 changed files with 96 additions and 3 deletions

View File

@ -268,6 +268,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
protected int _rngRateBytes = 2048;
private File _qemuSocketsPath;
private final String _qemuGuestAgentSocketName = "org.qemu.guest_agent.0";
private long _totalMemory;
private final Map <String, String> _pifs = new HashMap<String, String>();
private final Map<String, VmStats> _vmStats = new ConcurrentHashMap<String, VmStats>();
@ -2453,6 +2454,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
public StartupCommand[] initialize() {
final List<Object> info = getHostInfo();
_totalMemory = (Long)info.get(2);
final StartupRoutingCommand cmd =
new StartupRoutingCommand((Integer)info.get(0), (Long)info.get(1), (Long)info.get(2), (Long)info.get(4), (String)info.get(3), _hypervisorType,
@ -3586,4 +3588,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
}
}
}
public long getTotalMemory() {
return _totalMemory;
}
}

View File

@ -24,6 +24,7 @@ import java.util.List;
import org.apache.log4j.Logger;
import org.libvirt.Connect;
import org.libvirt.Domain;
import org.libvirt.DomainInfo.DomainState;
import org.libvirt.LibvirtException;
@ -60,6 +61,17 @@ public final class LibvirtStartCommandWrapper extends CommandWrapper<StartComman
final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();
Connect conn = null;
try {
vm = libvirtComputingResource.createVMFromSpec(vmSpec);
conn = libvirtUtilitiesHelper.getConnectionByType(vm.getHvsType());
Long remainingMem = getFreeMemory(conn, libvirtComputingResource);
if (remainingMem == null){
return new StartAnswer(command, "failed to get free memory");
} else if (remainingMem < vmSpec.getMinRam()) {
return new StartAnswer(command, "Not enough memory on the host, remaining: " + remainingMem + ", asking: " + vmSpec.getMinRam());
}
final NicTO[] nics = vmSpec.getNics();
for (final NicTO nic : nics) {
@ -68,8 +80,6 @@ public final class LibvirtStartCommandWrapper extends CommandWrapper<StartComman
}
}
vm = libvirtComputingResource.createVMFromSpec(vmSpec);
conn = libvirtUtilitiesHelper.getConnectionByType(vm.getHvsType());
libvirtComputingResource.createVbd(conn, vmSpec, vmName, vm);
if (!storagePoolMgr.connectPhysicalDisksViaVmSpec(vmSpec)) {
@ -150,4 +160,22 @@ public final class LibvirtStartCommandWrapper extends CommandWrapper<StartComman
}
}
}
}
private Long getFreeMemory(final Connect conn, final LibvirtComputingResource libvirtComputingResource){
try {
long allocatedMem = 0;
int[] ids = conn.listDomains();
for(int id :ids) {
Domain dm = conn.domainLookupByID(id);
allocatedMem += dm.getMaxMemory() * 1024L;
s_logger.debug("vm: " + dm.getName() + " mem: " + dm.getMaxMemory() * 1024L);
}
Long remainingMem = libvirtComputingResource.getTotalMemory() - allocatedMem;
s_logger.debug("remaining mem" + remainingMem);
return remainingMem;
} catch (Exception e) {
s_logger.debug("failed to get free memory", e);
return null;
}
}
}

View File

@ -4855,6 +4855,7 @@ public class LibvirtComputingResourceTest {
final NicTO nic = Mockito.mock(NicTO.class);
final NicTO[] nics = new NicTO[]{nic};
final int[] vms = new int[0];
final String vmName = "Test";
final String controlIp = "127.0.0.1";
@ -4868,6 +4869,7 @@ public class LibvirtComputingResourceTest {
when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
try {
when(libvirtUtilitiesHelper.getConnectionByType(vmDef.getHvsType())).thenReturn(conn);
when(conn.listDomains()).thenReturn(vms);
doNothing().when(libvirtComputingResource).createVbd(conn, vmSpec, vmName, vmDef);
} catch (final LibvirtException e) {
fail(e.getMessage());
@ -4927,6 +4929,7 @@ public class LibvirtComputingResourceTest {
final NicTO nic = Mockito.mock(NicTO.class);
final NicTO[] nics = new NicTO[]{nic};
final int[] vms = new int[0];
final String vmName = "Test";
final String controlIp = "127.0.0.1";
@ -4940,6 +4943,7 @@ public class LibvirtComputingResourceTest {
when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
try {
when(libvirtUtilitiesHelper.getConnectionByType(vmDef.getHvsType())).thenReturn(conn);
when(conn.listDomains()).thenReturn(vms);
doNothing().when(libvirtComputingResource).createVbd(conn, vmSpec, vmName, vmDef);
} catch (final LibvirtException e) {
fail(e.getMessage());
@ -4989,6 +4993,61 @@ public class LibvirtComputingResourceTest {
}
}
@Test
public void testStartCommandHostMemory() {
final VirtualMachineTO vmSpec = Mockito.mock(VirtualMachineTO.class);
final com.cloud.host.Host host = Mockito.mock(com.cloud.host.Host.class);
final boolean executeInSequence = false;
final StartCommand command = new StartCommand(vmSpec, host, executeInSequence);
final KVMStoragePoolManager storagePoolMgr = Mockito.mock(KVMStoragePoolManager.class);
final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
final Connect conn = Mockito.mock(Connect.class);
final LibvirtVMDef vmDef = Mockito.mock(LibvirtVMDef.class);
final NicTO nic = Mockito.mock(NicTO.class);
final NicTO[] nics = new NicTO[]{nic};
int vmId = 1;
final int[] vms = new int[]{vmId};
final Domain dm = Mockito.mock(Domain.class);
final String vmName = "Test";
when(libvirtComputingResource.getStoragePoolMgr()).thenReturn(storagePoolMgr);
when(vmSpec.getNics()).thenReturn(nics);
when(vmSpec.getType()).thenReturn(VirtualMachine.Type.User);
when(vmSpec.getName()).thenReturn(vmName);
when(vmSpec.getMaxRam()).thenReturn(512L);
when(libvirtComputingResource.createVMFromSpec(vmSpec)).thenReturn(vmDef);
when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
try {
when(libvirtUtilitiesHelper.getConnectionByType(vmDef.getHvsType())).thenReturn(conn);
when(conn.listDomains()).thenReturn(vms);
when(conn.domainLookupByID(vmId)).thenReturn(dm);
when(dm.getMaxMemory()).thenReturn(1024L);
when(dm.getName()).thenReturn(vmName);
when(libvirtComputingResource.getTotalMemory()).thenReturn(2048*1024L);
doNothing().when(libvirtComputingResource).createVbd(conn, vmSpec, vmName, vmDef);
} catch (final LibvirtException e) {
fail(e.getMessage());
} catch (final InternalErrorException e) {
fail(e.getMessage());
} catch (final URISyntaxException e) {
fail(e.getMessage());
}
when(storagePoolMgr.connectPhysicalDisksViaVmSpec(vmSpec)).thenReturn(true);
final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
assertNotNull(wrapper);
final Answer answer = wrapper.execute(command, libvirtComputingResource);
assertTrue(answer.getResult());
}
@Test
public void testUpdateHostPasswordCommand() {
final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);