diff --git a/core/src/com/cloud/vm/VmDetailConstants.java b/core/src/com/cloud/vm/VmDetailConstants.java index 90068d1b72b..5ff3ce02fe4 100644 --- a/core/src/com/cloud/vm/VmDetailConstants.java +++ b/core/src/com/cloud/vm/VmDetailConstants.java @@ -20,4 +20,5 @@ public interface VmDetailConstants { public static final String KEYBOARD = "keyboard"; public static final String NIC_ADAPTER = "nicAdapter"; public static final String ROOK_DISK_CONTROLLER = "rootDiskController"; + public static final String NESTED_VIRTUALIZATION_FLAG = "nestedVirtualizationFlag"; } diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java index 20146970daa..f6f0923c7ae 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java @@ -27,6 +27,7 @@ import java.util.Map; import javax.ejb.Local; import javax.inject.Inject; +import org.apache.cloudstack.api.ApiConstants.VMDetails; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -40,6 +41,8 @@ import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand; import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.cluster.ClusterManager; +import com.cloud.configuration.Config; +import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; @@ -84,6 +87,7 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru { @Inject VmwareManager _vmwareMgr; @Inject SecondaryStorageVmManager _secStorageMgr; @Inject NetworkModel _networkMgr; + @Inject ConfigurationDao _configDao; protected VMwareGuru() { super(); @@ -212,8 +216,21 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru { sbMacSequence.deleteCharAt(sbMacSequence.length() - 1); String bootArgs = to.getBootArgs(); to.setBootArgs(bootArgs + " nic_macs=" + sbMacSequence.toString()); + + } + + // Don't do this if the virtual machine is one of the special types + // Should only be done on user machines + if(!(vm.getVirtualMachine() instanceof DomainRouterVO || vm.getVirtualMachine() instanceof ConsoleProxyVO + || vm.getVirtualMachine() instanceof SecondaryStorageVmVO)) { + String nestedVirt = _configDao.getValue(Config.VmwareEnableNestedVirtualization.key()); + if (nestedVirt != null) { + s_logger.debug("Nested virtualization requested, adding flag to vm configuration"); + details.put(VmDetailConstants.NESTED_VIRTUALIZATION_FLAG, nestedVirt); + to.setDetails(details); + + } } - // Determine the VM's OS description GuestOSVO guestOS = _guestOsDao.findById(vm.getVirtualMachine().getGuestOSId()); to.setOs(guestOS.getDisplayName()); diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 634827b6468..f569595b8b0 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -232,6 +232,7 @@ import com.vmware.vim25.ClusterDasConfigInfo; import com.vmware.vim25.ComputeResourceSummary; import com.vmware.vim25.DatastoreSummary; import com.vmware.vim25.DynamicProperty; +import com.vmware.vim25.HostCapability; import com.vmware.vim25.HostFirewallInfo; import com.vmware.vim25.HostFirewallRuleset; import com.vmware.vim25.HostNetworkTrafficShapingPolicy; @@ -2147,6 +2148,23 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa VmwareHelper.setBasicVmConfig(vmConfigSpec, vmSpec.getCpus(), vmSpec.getMaxSpeed(), vmSpec.getMinSpeed(),(int) (vmSpec.getMaxRam()/(1024*1024)), ramMb, translateGuestOsIdentifier(vmSpec.getArch(), vmSpec.getOs()).value(), vmSpec.getLimitCpuUse()); + + if ("true".equals(vmSpec.getDetails().get(VmDetailConstants.NESTED_VIRTUALIZATION_FLAG))) { + s_logger.debug("Nested Virtualization enabled in configuration, checking hypervisor capability"); + ManagedObjectReference hostMor = vmMo.getRunningHost().getMor(); + ManagedObjectReference computeMor = context.getVimClient().getMoRefProp(hostMor, "parent"); + ManagedObjectReference environmentBrowser = + context.getVimClient().getMoRefProp(computeMor, "environmentBrowser"); + HostCapability hostCapability = context.getService().queryTargetCapabilities(environmentBrowser, hostMor); + if (hostCapability.isNestedHVSupported()) { + s_logger.debug("Hypervisor supports nested virtualization, enabling for VM " + vmSpec.getName()); + vmConfigSpec.setNestedHVEnabled(true); + } + else { + s_logger.warn("Hypervisor doesn't support nested virtualization, unable to set config for VM " +vmSpec.getName()); + vmConfigSpec.setNestedHVEnabled(false); + } + } VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[totalChangeDevices]; int i = 0; diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java index 2137c003912..e3e305350b1 100755 --- a/server/src/com/cloud/configuration/Config.java +++ b/server/src/com/cloud/configuration/Config.java @@ -276,6 +276,7 @@ public enum Config { VmwareRootDiskControllerType("Advanced", ManagementServer.class, String.class, "vmware.root.disk.controller", "ide", "Specify the default disk controller for root volumes, valid values are scsi, ide", null), VmwareSystemVmNicDeviceType("Advanced", ManagementServer.class, String.class, "vmware.systemvm.nic.device.type", "E1000", "Specify the default network device type for system VMs, valid values are E1000, PCNet32, Vmxnet2, Vmxnet3", null), VmwareRecycleHungWorker("Advanced", ManagementServer.class, Boolean.class, "vmware.recycle.hung.wokervm", "false", "Specify whether or not to recycle hung worker VMs", null), + VmwareEnableNestedVirtualization("Advanced", ManagementServer.class, Boolean.class, "vmware.nested.virtualization", "false", "When set to true this will enable nested virtualization when this is supported by the hypervisor", null), // Midonet MidoNetAPIServerAddress("Network", ManagementServer.class, String.class, "midonet.apiserver.address", "http://localhost:8081", "Specify the address at which the Midonet API server can be contacted (if using Midonet)", null),