Skip to content

Commit 4480d05

Browse files
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 <[email protected]>
2 parents ee150aa + b73c053 commit 4480d05

File tree

2 files changed

+104
-1
lines changed

2 files changed

+104
-1
lines changed

plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@
9494
import com.vmware.vim25.VirtualMachineRelocateSpec;
9595
import com.vmware.vim25.VirtualMachineRelocateSpecDiskLocator;
9696
import com.vmware.vim25.VirtualMachineRuntimeInfo;
97+
import com.vmware.vim25.VirtualMachineVideoCard;
9798
import com.vmware.vim25.VmwareDistributedVirtualSwitchVlanIdSpec;
9899

99100
import org.apache.cloudstack.storage.command.StorageSubSystemCommand;
@@ -1895,6 +1896,8 @@ protected StartAnswer execute(StartCommand cmd) {
18951896

18961897
postDiskConfigBeforeStart(vmMo, vmSpec, sortedDisks, ideControllerKey, scsiControllerKey, iqnToPath, hyperHost, context);
18971898

1899+
postVideoCardMemoryConfigBeforeStart(vmMo, vmSpec);
1900+
18981901
//
18991902
// Power-on VM
19001903
//
@@ -1943,6 +1946,79 @@ protected StartAnswer execute(StartCommand cmd) {
19431946
}
19441947
}
19451948

1949+
/**
1950+
* Sets video card memory to the one provided in detail svga.vramSize (if provided).
1951+
* 64MB was always set before.
1952+
* Size must be in KB.
1953+
* @param vmMo virtual machine mo
1954+
* @param vmSpec virtual machine specs
1955+
*/
1956+
protected void postVideoCardMemoryConfigBeforeStart(VirtualMachineMO vmMo, VirtualMachineTO vmSpec) {
1957+
String paramVRamSize = "svga.vramSize";
1958+
if (vmSpec.getDetails().containsKey(paramVRamSize)){
1959+
String value = vmSpec.getDetails().get(paramVRamSize);
1960+
try {
1961+
long svgaVmramSize = Long.parseLong(value);
1962+
setNewVRamSizeVmVideoCard(vmMo, svgaVmramSize);
1963+
}
1964+
catch (NumberFormatException e){
1965+
s_logger.error("Unexpected value, cannot parse " + value + " to long due to: " + e.getMessage());
1966+
}
1967+
catch (Exception e){
1968+
s_logger.error("Error while reconfiguring vm due to: " + e.getMessage());
1969+
}
1970+
}
1971+
}
1972+
1973+
/**
1974+
* Search for vm video card iterating through vm device list
1975+
* @param vmMo virtual machine mo
1976+
* @param svgaVmramSize new svga vram size (in KB)
1977+
*/
1978+
private void setNewVRamSizeVmVideoCard(VirtualMachineMO vmMo, long svgaVmramSize) throws Exception {
1979+
for (VirtualDevice device : vmMo.getAllDeviceList()){
1980+
if (device instanceof VirtualMachineVideoCard){
1981+
VirtualMachineVideoCard videoCard = (VirtualMachineVideoCard) device;
1982+
modifyVmVideoCardVRamSize(videoCard, vmMo, svgaVmramSize);
1983+
}
1984+
}
1985+
}
1986+
1987+
/**
1988+
* 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)
1989+
* @param videoCard vm's video card device
1990+
* @param vmMo virtual machine mo
1991+
* @param svgaVmramSize new svga vram size (in KB)
1992+
*/
1993+
private void modifyVmVideoCardVRamSize(VirtualMachineVideoCard videoCard, VirtualMachineMO vmMo, long svgaVmramSize) throws Exception {
1994+
if (videoCard.getVideoRamSizeInKB().longValue() != svgaVmramSize){
1995+
s_logger.info("Video card memory was set " + videoCard.getVideoRamSizeInKB().longValue() + "kb instead of " + svgaVmramSize + "kb");
1996+
VirtualMachineConfigSpec newSizeSpecs = configSpecVideoCardNewVRamSize(videoCard, svgaVmramSize);
1997+
boolean res = vmMo.configureVm(newSizeSpecs);
1998+
if (res) {
1999+
s_logger.info("Video card memory successfully updated to " + svgaVmramSize + "kb");
2000+
}
2001+
}
2002+
}
2003+
2004+
/**
2005+
* Returns a VirtualMachineConfigSpec to edit its svga vram size
2006+
* @param videoCard video card device to edit providing the svga vram size
2007+
* @param svgaVmramSize new svga vram size (in KB)
2008+
*/
2009+
private VirtualMachineConfigSpec configSpecVideoCardNewVRamSize(VirtualMachineVideoCard videoCard, long svgaVmramSize){
2010+
videoCard.setVideoRamSizeInKB(svgaVmramSize);
2011+
videoCard.setUseAutoDetect(false);
2012+
2013+
VirtualDeviceConfigSpec arrayVideoCardConfigSpecs = new VirtualDeviceConfigSpec();
2014+
arrayVideoCardConfigSpecs.setDevice(videoCard);
2015+
arrayVideoCardConfigSpecs.setOperation(VirtualDeviceConfigSpecOperation.EDIT);
2016+
2017+
VirtualMachineConfigSpec changeVideoCardSpecs = new VirtualMachineConfigSpec();
2018+
changeVideoCardSpecs.getDeviceChange().add(arrayVideoCardConfigSpecs);
2019+
return changeVideoCardSpecs;
2020+
}
2021+
19462022
private void tearDownVm(VirtualMachineMO vmMo) throws Exception{
19472023

19482024
if(vmMo == null) return;

plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/resource/VmwareResourceTest.java

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,22 @@
1919
import static org.mockito.Mockito.doReturn;
2020
import static org.mockito.Mockito.verify;
2121
import static org.mockito.Mockito.when;
22+
import static org.mockito.Mockito.mock;
23+
import static org.mockito.Mockito.any;
24+
25+
import java.util.Arrays;
26+
import java.util.HashMap;
27+
import java.util.Map;
2228

2329
import org.junit.Before;
2430
import org.junit.Test;
2531
import org.mockito.Mock;
2632
import org.mockito.MockitoAnnotations;
2733
import org.mockito.Spy;
2834

35+
import com.vmware.vim25.VirtualDevice;
2936
import com.vmware.vim25.VirtualMachineConfigSpec;
30-
37+
import com.vmware.vim25.VirtualMachineVideoCard;
3138
import com.cloud.agent.api.Command;
3239
import com.cloud.agent.api.ScaleVmAnswer;
3340
import com.cloud.agent.api.ScaleVmCommand;
@@ -64,6 +71,10 @@ public VmwareHypervisorHost getHyperHost(VmwareContext context, Command cmd) {
6471
VirtualMachineMO vmMo;
6572
@Mock
6673
VirtualMachineConfigSpec vmConfigSpec;
74+
@Mock
75+
VirtualMachineMO vmMo3dgpu;
76+
@Mock
77+
VirtualMachineTO vmSpec3dgpu;
6778

6879
@Before
6980
public void setup() {
@@ -90,4 +101,20 @@ public void testScaleVMF1() throws Exception {
90101
verify(_resource).execute(cmd);
91102
}
92103

104+
@Test
105+
public void testStartVm3dgpuEnabled() throws Exception{
106+
Map<String, String> specDetails = new HashMap<String, String>();
107+
specDetails.put("svga.vramSize", "131072");
108+
when(vmSpec3dgpu.getDetails()).thenReturn(specDetails);
109+
110+
VirtualMachineVideoCard videoCard = mock(VirtualMachineVideoCard.class);
111+
when(videoCard.getVideoRamSizeInKB()).thenReturn(65536l);
112+
when(vmMo3dgpu.getAllDeviceList()).thenReturn(Arrays.asList((VirtualDevice) videoCard));
113+
114+
when(vmMo3dgpu.configureVm(any(VirtualMachineConfigSpec.class))).thenReturn(true);
115+
116+
_resource.postVideoCardMemoryConfigBeforeStart(vmMo3dgpu, vmSpec3dgpu);
117+
verify(vmMo3dgpu).configureVm(any(VirtualMachineConfigSpec.class));
118+
}
119+
93120
}

0 commit comments

Comments
 (0)