Merge pull request #1310 from nvazquez/3dgpu

CLOUDSTACK-9211: Support passing vRAM size to support 3D GPU on VmwareJIRA TICKET:
https://issues.apache.org/jira/browse/CLOUDSTACK-9211

CS support passing hypervisor options by creating entries in <code>vm_template_details</code> or <code>user_vm_details</code>

To enable software 3D GPU 4 options needs to be added:

| name| value |
|:-------------:|:-------------:|
|mks.enable3d|true|
|mks.use3dRenderer|automatic|
|svga.autodetect|false|
|svga.vramSize|(size in KB) e.g. 131072|

Currently all options except <code>svga.vramSize</code> works, VMs always get configured with default 64Mb videoRAM instead of the one provided on the option.

* pr/1310:
  CLOUDSTACK-9211: Unit test for 3dgpu support
  CLOUDSTACK-9211: Refactor vm vram size setter method
  CLOUDSTACK-9211: Add javadoc and refactor method
  CLOUDSTACK-9211: Support passing vRAM size to support 3D GPU on Vmware

Signed-off-by: Rafael Weingärtner <rafael@apache.org>
This commit is contained in:
Rafael Weingärtner 2016-02-23 20:35:56 -03:00
commit 4480d05151
2 changed files with 104 additions and 1 deletions

View File

@ -94,6 +94,7 @@ import com.vmware.vim25.VirtualMachinePowerState;
import com.vmware.vim25.VirtualMachineRelocateSpec;
import com.vmware.vim25.VirtualMachineRelocateSpecDiskLocator;
import com.vmware.vim25.VirtualMachineRuntimeInfo;
import com.vmware.vim25.VirtualMachineVideoCard;
import com.vmware.vim25.VmwareDistributedVirtualSwitchVlanIdSpec;
import org.apache.cloudstack.storage.command.StorageSubSystemCommand;
@ -1895,6 +1896,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
postDiskConfigBeforeStart(vmMo, vmSpec, sortedDisks, ideControllerKey, scsiControllerKey, iqnToPath, hyperHost, context);
postVideoCardMemoryConfigBeforeStart(vmMo, vmSpec);
//
// Power-on VM
//
@ -1943,6 +1946,79 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
}
}
/**
* Sets video card memory to the one provided in detail svga.vramSize (if provided).
* 64MB was always set before.
* Size must be in KB.
* @param vmMo virtual machine mo
* @param vmSpec virtual machine specs
*/
protected void postVideoCardMemoryConfigBeforeStart(VirtualMachineMO vmMo, VirtualMachineTO vmSpec) {
String paramVRamSize = "svga.vramSize";
if (vmSpec.getDetails().containsKey(paramVRamSize)){
String value = vmSpec.getDetails().get(paramVRamSize);
try {
long svgaVmramSize = Long.parseLong(value);
setNewVRamSizeVmVideoCard(vmMo, svgaVmramSize);
}
catch (NumberFormatException e){
s_logger.error("Unexpected value, cannot parse " + value + " to long due to: " + e.getMessage());
}
catch (Exception e){
s_logger.error("Error while reconfiguring vm due to: " + e.getMessage());
}
}
}
/**
* Search for vm video card iterating through vm device list
* @param vmMo virtual machine mo
* @param svgaVmramSize new svga vram size (in KB)
*/
private void setNewVRamSizeVmVideoCard(VirtualMachineMO vmMo, long svgaVmramSize) throws Exception {
for (VirtualDevice device : vmMo.getAllDeviceList()){
if (device instanceof VirtualMachineVideoCard){
VirtualMachineVideoCard videoCard = (VirtualMachineVideoCard) device;
modifyVmVideoCardVRamSize(videoCard, vmMo, svgaVmramSize);
}
}
}
/**
* Modifies vm vram size if it was set to a different size to the one provided in svga.vramSize (user_vm_details or template_vm_details)
* @param videoCard vm's video card device
* @param vmMo virtual machine mo
* @param svgaVmramSize new svga vram size (in KB)
*/
private void modifyVmVideoCardVRamSize(VirtualMachineVideoCard videoCard, VirtualMachineMO vmMo, long svgaVmramSize) throws Exception {
if (videoCard.getVideoRamSizeInKB().longValue() != svgaVmramSize){
s_logger.info("Video card memory was set " + videoCard.getVideoRamSizeInKB().longValue() + "kb instead of " + svgaVmramSize + "kb");
VirtualMachineConfigSpec newSizeSpecs = configSpecVideoCardNewVRamSize(videoCard, svgaVmramSize);
boolean res = vmMo.configureVm(newSizeSpecs);
if (res) {
s_logger.info("Video card memory successfully updated to " + svgaVmramSize + "kb");
}
}
}
/**
* Returns a VirtualMachineConfigSpec to edit its svga vram size
* @param videoCard video card device to edit providing the svga vram size
* @param svgaVmramSize new svga vram size (in KB)
*/
private VirtualMachineConfigSpec configSpecVideoCardNewVRamSize(VirtualMachineVideoCard videoCard, long svgaVmramSize){
videoCard.setVideoRamSizeInKB(svgaVmramSize);
videoCard.setUseAutoDetect(false);
VirtualDeviceConfigSpec arrayVideoCardConfigSpecs = new VirtualDeviceConfigSpec();
arrayVideoCardConfigSpecs.setDevice(videoCard);
arrayVideoCardConfigSpecs.setOperation(VirtualDeviceConfigSpecOperation.EDIT);
VirtualMachineConfigSpec changeVideoCardSpecs = new VirtualMachineConfigSpec();
changeVideoCardSpecs.getDeviceChange().add(arrayVideoCardConfigSpecs);
return changeVideoCardSpecs;
}
private void tearDownVm(VirtualMachineMO vmMo) throws Exception{
if(vmMo == null) return;

View File

@ -19,6 +19,12 @@ package com.cloud.hypervisor.vmware.resource;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.any;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
@ -26,8 +32,9 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
import com.vmware.vim25.VirtualDevice;
import com.vmware.vim25.VirtualMachineConfigSpec;
import com.vmware.vim25.VirtualMachineVideoCard;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.ScaleVmAnswer;
import com.cloud.agent.api.ScaleVmCommand;
@ -64,6 +71,10 @@ public class VmwareResourceTest {
VirtualMachineMO vmMo;
@Mock
VirtualMachineConfigSpec vmConfigSpec;
@Mock
VirtualMachineMO vmMo3dgpu;
@Mock
VirtualMachineTO vmSpec3dgpu;
@Before
public void setup() {
@ -90,4 +101,20 @@ public class VmwareResourceTest {
verify(_resource).execute(cmd);
}
@Test
public void testStartVm3dgpuEnabled() throws Exception{
Map<String, String> specDetails = new HashMap<String, String>();
specDetails.put("svga.vramSize", "131072");
when(vmSpec3dgpu.getDetails()).thenReturn(specDetails);
VirtualMachineVideoCard videoCard = mock(VirtualMachineVideoCard.class);
when(videoCard.getVideoRamSizeInKB()).thenReturn(65536l);
when(vmMo3dgpu.getAllDeviceList()).thenReturn(Arrays.asList((VirtualDevice) videoCard));
when(vmMo3dgpu.configureVm(any(VirtualMachineConfigSpec.class))).thenReturn(true);
_resource.postVideoCardMemoryConfigBeforeStart(vmMo3dgpu, vmSpec3dgpu);
verify(vmMo3dgpu).configureVm(any(VirtualMachineConfigSpec.class));
}
}