From 8eff66578411974d8aa4f3b17826984588b79c2e Mon Sep 17 00:00:00 2001 From: Sateesh Chodapuneedi Date: Fri, 25 May 2012 18:03:45 +0530 Subject: [PATCH] CS-15073 Nexus vSwitch: Source NAT is being programmed on the wrong nic on the Virtual Router Reviewed-by: Devdeep Conflicts: vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java --- .../vmware/resource/VmwareResource.java | 45 +- .../hypervisor/vmware/mo/DatacenterMO.java | 20 + .../vmware/mo/VirtualMachineMO.java | 707 +++++++++--------- 3 files changed, 410 insertions(+), 362 deletions(-) diff --git a/core/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/core/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 75d2e75d2c1..2eb9998b02e 100755 --- a/core/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/core/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -812,27 +812,32 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa // TODO : probably need to set traffic shaping Pair networkInfo = null; - if(!_nexusVSwitch) { - networkInfo = HypervisorHostHelper.prepareNetwork(this._publicNetworkVSwitchName, "cloud.public", - vmMo.getRunningHost(), vlanId, null, null, this._ops_timeout, true); + if (!_nexusVSwitch) { + networkInfo = HypervisorHostHelper.prepareNetwork(this._publicNetworkVSwitchName, "cloud.public", + vmMo.getRunningHost(), vlanId, null, null, this._ops_timeout, true); + } else { + networkInfo = HypervisorHostHelper.prepareNetwork(this._publicNetworkVSwitchName, "cloud.public", + vmMo.getRunningHost(), vlanId, null, null, this._ops_timeout); } - else { - networkInfo = HypervisorHostHelper.prepareNetwork(this._publicNetworkVSwitchName, "cloud.public", - vmMo.getRunningHost(), vlanId, null, null, this._ops_timeout); - } - + int nicIndex = allocPublicNicIndex(vmMo); - + try { - VirtualDevice[] nicDevices = vmMo.getNicDevices(); - - VirtualEthernetCard device = (VirtualEthernetCard)nicDevices[nicIndex]; - - VirtualEthernetCardNetworkBackingInfo nicBacking = new VirtualEthernetCardNetworkBackingInfo(); - nicBacking.setDeviceName(networkInfo.second()); - nicBacking.setNetwork(networkInfo.first()); - device.setBacking(nicBacking); - + VirtualDevice[] nicDevices = vmMo.getNicDevices(); + + VirtualEthernetCard device = (VirtualEthernetCard) nicDevices[nicIndex]; + + if (!_nexusVSwitch) { + VirtualEthernetCardNetworkBackingInfo nicBacking = new VirtualEthernetCardNetworkBackingInfo(); + nicBacking.setDeviceName(networkInfo.second()); + nicBacking.setNetwork(networkInfo.first()); + device.setBacking(nicBacking); + } else { + HostMO hostMo = vmMo.getRunningHost(); + DatacenterMO dataCenterMo = new DatacenterMO(hostMo.getContext(), hostMo.getHyperHostDatacenter()); + device.setBacking(dataCenterMo.getDvPortBackingInfo(networkInfo)); + } + VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec(); VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[1]; deviceConfigSpecArray[0] = new VirtualDeviceConfigSpec(); @@ -4051,9 +4056,9 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa if (mgr.getPrivateVSwitchTypeGlobalParameter().equalsIgnoreCase("nexus")) _privateNetworkVSwitchName = mgr.getPrivateVSwitchName(Long.parseLong(_dcId), HypervisorType.VMware); if (mgr.getPublicVSwitchTypeGlobalParameter().equalsIgnoreCase("nexus")) - _publicNetworkVSwitchName = mgr.getPublicVSwitchName(Long.parseLong(_dcId), HypervisorType.VMware); + _publicNetworkVSwitchName = mgr.getPublicVSwitchName(Long.parseLong(_dcId), HypervisorType.VMware); if (mgr.getGuestVSwitchTypeGlobalParameter().equalsIgnoreCase("nexus")) - _guestNetworkVSwitchName = mgr.getGuestVSwitchName(Long.parseLong(_dcId), HypervisorType.VMware); + _guestNetworkVSwitchName = mgr.getGuestVSwitchName(Long.parseLong(_dcId), HypervisorType.VMware); } } catch (Exception e) { diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/DatacenterMO.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/DatacenterMO.java index f9127e3304a..f57d6ae8d19 100755 --- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/DatacenterMO.java +++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/DatacenterMO.java @@ -21,6 +21,7 @@ import com.cloud.utils.Pair; import com.vmware.apputils.vim25.ServiceUtil; import com.vmware.vim25.CustomFieldStringValue; import com.vmware.vim25.DVPortgroupConfigInfo; +import com.vmware.vim25.DistributedVirtualSwitchPortConnection; import com.vmware.vim25.DynamicProperty; import com.vmware.vim25.ManagedObjectReference; import com.vmware.vim25.ObjectContent; @@ -29,6 +30,9 @@ import com.vmware.vim25.PropertyFilterSpec; import com.vmware.vim25.PropertySpec; import com.vmware.vim25.SelectionSpec; import com.vmware.vim25.TraversalSpec; +import com.vmware.vim25.VirtualDeviceBackingInfo; +import com.vmware.vim25.VirtualEthernetCardDistributedVirtualPortBackingInfo; +import com.vmware.vim25.VirtualEthernetCardNetworkBackingInfo; public class DatacenterMO extends BaseMO { @@ -445,5 +449,21 @@ public class DatacenterMO extends BaseMO { public String getDvSwitchUuid(ManagedObjectReference dvSwitchMor) throws Exception { assert (dvSwitchMor != null); return (String) _context.getServiceUtil().getDynamicProperty(dvSwitchMor, "uuid"); + } + + public VirtualEthernetCardDistributedVirtualPortBackingInfo getDvPortBackingInfo(Pair networkInfo) + throws Exception { + assert (networkInfo != null); + assert (networkInfo.first() != null && networkInfo.first().getType().equalsIgnoreCase("DistributedVirtualPortgroup")); + final VirtualEthernetCardDistributedVirtualPortBackingInfo dvPortBacking = new VirtualEthernetCardDistributedVirtualPortBackingInfo(); + final DistributedVirtualSwitchPortConnection dvPortConnection = new DistributedVirtualSwitchPortConnection(); + ManagedObjectReference dvsMor = getDvSwitchMor(networkInfo.first()); + String dvSwitchUuid = getDvSwitchUuid(dvsMor); + dvPortConnection.setSwitchUuid(dvSwitchUuid); + dvPortConnection.setPortgroupKey(networkInfo.first().get_value()); + dvPortBacking.setPort(dvPortConnection); + System.out.println("Plugging NIC device into network " + networkInfo.second() + " backed by dvSwitch: " + + dvSwitchUuid); + return dvPortBacking; } } diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java index dade93dd4cc..870fbbd15a0 100644 --- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java +++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java @@ -38,6 +38,7 @@ import com.cloud.utils.script.Script; import com.google.gson.Gson; import com.vmware.vim25.ArrayOfManagedObjectReference; import com.vmware.vim25.CustomFieldStringValue; +import com.vmware.vim25.DistributedVirtualSwitchPortConnection; import com.vmware.vim25.DynamicProperty; import com.vmware.vim25.GuestInfo; import com.vmware.vim25.HttpNfcLeaseDeviceUrl; @@ -72,6 +73,7 @@ import com.vmware.vim25.VirtualDiskSparseVer1BackingInfo; import com.vmware.vim25.VirtualDiskSparseVer2BackingInfo; import com.vmware.vim25.VirtualDiskType; import com.vmware.vim25.VirtualEthernetCard; +import com.vmware.vim25.VirtualEthernetCardDistributedVirtualPortBackingInfo; import com.vmware.vim25.VirtualIDEController; import com.vmware.vim25.VirtualLsiLogicController; import com.vmware.vim25.VirtualMachineCloneSpec; @@ -1695,355 +1697,376 @@ public class VirtualMachineMO extends BaseMO { } } } - - // return pair of VirtualDisk and disk device bus name(ide0:0, etc) - public Pair getDiskDevice(String vmdkDatastorePath, boolean matchExactly) throws Exception { - VirtualDevice[] devices = (VirtualDevice[])_context.getServiceUtil().getDynamicProperty(_mor, "config.hardware.device"); - - s_logger.info("Look for disk device info from volume : " + vmdkDatastorePath); - DatastoreFile dsSrcFile = new DatastoreFile(vmdkDatastorePath); - String srcBaseName = dsSrcFile.getFileBaseName(); - - if(devices != null && devices.length > 0) { - for(VirtualDevice device : devices) { - if(device instanceof VirtualDisk) { - s_logger.info("Test against disk device, controller key: " + device.getControllerKey() + ", unit number: " + device.getUnitNumber()); - - VirtualDeviceBackingInfo backingInfo = ((VirtualDisk)device).getBacking(); - if(backingInfo instanceof VirtualDiskFlatVer2BackingInfo) { - VirtualDiskFlatVer2BackingInfo diskBackingInfo = (VirtualDiskFlatVer2BackingInfo)backingInfo; - do { - s_logger.info("Test against disk backing : " + diskBackingInfo.getFileName()); - - DatastoreFile dsBackingFile = new DatastoreFile(diskBackingInfo.getFileName()); - String backingBaseName = dsBackingFile.getFileBaseName(); - if(matchExactly) { - if(backingBaseName .equalsIgnoreCase(srcBaseName)) { - String deviceNumbering = getDeviceBusName(devices, device); - - s_logger.info("Disk backing : " + diskBackingInfo.getFileName() + " matches ==> " + deviceNumbering); - return new Pair((VirtualDisk)device, deviceNumbering); - } - } else { - if(backingBaseName.contains(srcBaseName)) { - String deviceNumbering = getDeviceBusName(devices, device); - - s_logger.info("Disk backing : " + diskBackingInfo.getFileName() + " matches ==> " + deviceNumbering); - return new Pair((VirtualDisk)device, deviceNumbering); - } - } - - diskBackingInfo = diskBackingInfo.getParent(); - } while(diskBackingInfo != null); - } - } - } - } - - return null; + + // return pair of VirtualDisk and disk device bus name(ide0:0, etc) + public Pair getDiskDevice(String vmdkDatastorePath, boolean matchExactly) throws Exception { + VirtualDevice[] devices = (VirtualDevice[])_context.getServiceUtil().getDynamicProperty(_mor, "config.hardware.device"); + + s_logger.info("Look for disk device info from volume : " + vmdkDatastorePath); + DatastoreFile dsSrcFile = new DatastoreFile(vmdkDatastorePath); + String srcBaseName = dsSrcFile.getFileBaseName(); + + if(devices != null && devices.length > 0) { + for(VirtualDevice device : devices) { + if(device instanceof VirtualDisk) { + s_logger.info("Test against disk device, controller key: " + device.getControllerKey() + ", unit number: " + device.getUnitNumber()); + + VirtualDeviceBackingInfo backingInfo = ((VirtualDisk)device).getBacking(); + if(backingInfo instanceof VirtualDiskFlatVer2BackingInfo) { + VirtualDiskFlatVer2BackingInfo diskBackingInfo = (VirtualDiskFlatVer2BackingInfo)backingInfo; + do { + s_logger.info("Test against disk backing : " + diskBackingInfo.getFileName()); + + DatastoreFile dsBackingFile = new DatastoreFile(diskBackingInfo.getFileName()); + String backingBaseName = dsBackingFile.getFileBaseName(); + if(matchExactly) { + if(backingBaseName .equalsIgnoreCase(srcBaseName)) { + String deviceNumbering = getDeviceBusName(devices, device); + + s_logger.info("Disk backing : " + diskBackingInfo.getFileName() + " matches ==> " + deviceNumbering); + return new Pair((VirtualDisk)device, deviceNumbering); + } + } else { + if(backingBaseName.contains(srcBaseName)) { + String deviceNumbering = getDeviceBusName(devices, device); + + s_logger.info("Disk backing : " + diskBackingInfo.getFileName() + " matches ==> " + deviceNumbering); + return new Pair((VirtualDisk)device, deviceNumbering); + } + } + + diskBackingInfo = diskBackingInfo.getParent(); + } while(diskBackingInfo != null); + } + } + } + } + + return null; } - @Deprecated - public List> getDiskDatastorePathChain(VirtualDisk disk, boolean followChain) throws Exception { - VirtualDeviceBackingInfo backingInfo = disk.getBacking(); - if(!(backingInfo instanceof VirtualDiskFlatVer2BackingInfo)) { - throw new Exception("Unsupported VirtualDeviceBackingInfo"); - } - - List> pathList = new ArrayList>(); - VirtualDiskFlatVer2BackingInfo diskBackingInfo = (VirtualDiskFlatVer2BackingInfo)backingInfo; - - if(!followChain) { - pathList.add(new Pair(diskBackingInfo.getFileName(), diskBackingInfo.getDatastore())); - return pathList; - } - - Pair dcPair = getOwnerDatacenter(); - VirtualMachineFileInfo vmFilesInfo = getFileInfo(); - DatastoreFile snapshotDirFile = new DatastoreFile(vmFilesInfo.getSnapshotDirectory()); - DatastoreFile vmxDirFile = new DatastoreFile(vmFilesInfo.getVmPathName()); - - do { - if(diskBackingInfo.getParent() != null) { - pathList.add(new Pair(diskBackingInfo.getFileName(), diskBackingInfo.getDatastore())); - diskBackingInfo = diskBackingInfo.getParent(); - } else { - // try getting parent info from VMDK file itself - byte[] content = null; - try { - String url = getContext().composeDatastoreBrowseUrl(dcPair.second(), diskBackingInfo.getFileName()); - content = getContext().getResourceContent(url); - if(content == null || content.length == 0) { - break; - } - - pathList.add(new Pair(diskBackingInfo.getFileName(), diskBackingInfo.getDatastore())); - } catch(Exception e) { - // if snapshot directory has been changed to place other than default. VMware has a bug - // that its corresponding disk backing info is not updated correctly. therefore, we will try search - // in snapshot directory one more time - DatastoreFile currentFile = new DatastoreFile(diskBackingInfo.getFileName()); - String vmdkFullDsPath = snapshotDirFile.getCompanionPath(currentFile.getFileName()); - - String url = getContext().composeDatastoreBrowseUrl(dcPair.second(), vmdkFullDsPath); - content = getContext().getResourceContent(url); - if(content == null || content.length == 0) { - break; - } - - pathList.add(new Pair(vmdkFullDsPath, diskBackingInfo.getDatastore())); - } - - VmdkFileDescriptor descriptor = new VmdkFileDescriptor(); - descriptor.parse(content); - if(descriptor.getParentFileName() != null && !descriptor.getParentFileName().isEmpty()) { - // create a fake one - VirtualDiskFlatVer2BackingInfo parentDiskBackingInfo = new VirtualDiskFlatVer2BackingInfo(); - parentDiskBackingInfo.setDatastore(diskBackingInfo.getDatastore()); - - String parentFileName = descriptor.getParentFileName(); - if(parentFileName.startsWith("/")) { - int fileNameStartPos = parentFileName.lastIndexOf("/"); - parentFileName = parentFileName.substring(fileNameStartPos + 1); - parentDiskBackingInfo.setFileName(vmxDirFile.getCompanionPath(parentFileName)); - } else { - parentDiskBackingInfo.setFileName(snapshotDirFile.getCompanionPath(parentFileName)); - } - diskBackingInfo = parentDiskBackingInfo; - } else { - break; - } - } - } while(diskBackingInfo != null); - - return pathList; - } - - private String getDeviceBusName(VirtualDevice[] allDevices, VirtualDevice theDevice) throws Exception { - for(VirtualDevice device : allDevices) { - if(device.getKey() == theDevice.getControllerKey().intValue()) { - if(device instanceof VirtualIDEController) { - return String.format("ide%d:%d", ((VirtualIDEController)device).getBusNumber(), theDevice.getUnitNumber()); - } else if(device instanceof VirtualSCSIController) { - return String.format("scsi%d:%d", ((VirtualSCSIController)device).getBusNumber(), theDevice.getUnitNumber()); - } else { - throw new Exception("Device controller is not supported yet"); - } - } - } - throw new Exception("Unable to find device controller"); - } - - public VirtualDisk[] getAllDiskDevice() throws Exception { - List deviceList = new ArrayList(); - VirtualDevice[] devices = (VirtualDevice[])_context.getServiceUtil().getDynamicProperty(_mor, "config.hardware.device"); - if(devices != null && devices.length > 0) { - for(VirtualDevice device : devices) { - if(device instanceof VirtualDisk) { - deviceList.add((VirtualDisk)device); - } - } - } - - return deviceList.toArray(new VirtualDisk[0]); - } - - public VirtualDisk[] getAllIndependentDiskDevice() throws Exception { - List independentDisks = new ArrayList(); - VirtualDisk[] allDisks = getAllDiskDevice(); - if(allDisks.length > 0) { - for(VirtualDisk disk : allDisks) { - String diskMode = ""; - if(disk.getBacking() instanceof VirtualDiskFlatVer1BackingInfo) { - diskMode = ((VirtualDiskFlatVer1BackingInfo)disk.getBacking()).getDiskMode(); - } else if(disk.getBacking() instanceof VirtualDiskFlatVer2BackingInfo) { - diskMode = ((VirtualDiskFlatVer2BackingInfo)disk.getBacking()).getDiskMode(); - } else if(disk.getBacking() instanceof VirtualDiskRawDiskMappingVer1BackingInfo) { - diskMode = ((VirtualDiskRawDiskMappingVer1BackingInfo)disk.getBacking()).getDiskMode(); - } else if(disk.getBacking() instanceof VirtualDiskSparseVer1BackingInfo) { - diskMode = ((VirtualDiskSparseVer1BackingInfo)disk.getBacking()).getDiskMode(); - } else if(disk.getBacking() instanceof VirtualDiskSparseVer2BackingInfo) { - diskMode = ((VirtualDiskSparseVer2BackingInfo)disk.getBacking()).getDiskMode(); - } - - if(diskMode.indexOf("independent") != -1) { - independentDisks.add(disk); - } - } - } - - return independentDisks.toArray(new VirtualDisk[0]); - } - - public int tryGetIDEDeviceControllerKey() throws Exception { - VirtualDevice[] devices = (VirtualDevice [])_context.getServiceUtil(). - getDynamicProperty(_mor, "config.hardware.device"); - - if(devices != null && devices.length > 0) { - for(VirtualDevice device : devices) { - if(device instanceof VirtualIDEController) { - return ((VirtualIDEController)device).getKey(); - } - } - } - - return -1; - } - - public int getIDEDeviceControllerKey() throws Exception { - VirtualDevice[] devices = (VirtualDevice [])_context.getServiceUtil(). - getDynamicProperty(_mor, "config.hardware.device"); - - if(devices != null && devices.length > 0) { - for(VirtualDevice device : devices) { - if(device instanceof VirtualIDEController) { - return ((VirtualIDEController)device).getKey(); - } - } - } - - assert(false); - throw new Exception("IDE Controller Not Found"); - } - - public int getNextIDEDeviceNumber() throws Exception { - int controllerKey = getIDEDeviceControllerKey(); - return getNextDeviceNumber(controllerKey); - } - - public VirtualDevice getIsoDevice() throws Exception { - VirtualDevice[] devices = (VirtualDevice[])_context.getServiceUtil(). - getDynamicProperty(_mor, "config.hardware.device"); - if(devices != null && devices.length > 0) { - for(VirtualDevice device : devices) { - if(device instanceof VirtualCdrom) { - return device; - } - } - } - return null; - } - - public int getPCIDeviceControllerKey() throws Exception { - VirtualDevice[] devices = (VirtualDevice [])_context.getServiceUtil(). - getDynamicProperty(_mor, "config.hardware.device"); - - if(devices != null && devices.length > 0) { - for(VirtualDevice device : devices) { - if(device instanceof VirtualPCIController) { - return ((VirtualPCIController)device).getKey(); - } - } - } - - assert(false); - throw new Exception("PCI Controller Not Found"); - } - - public int getNextPCIDeviceNumber() throws Exception { - int controllerKey = getPCIDeviceControllerKey(); - return getNextDeviceNumber(controllerKey); - } - - public int getNextDeviceNumber(int controllerKey) throws Exception { - VirtualDevice[] devices = (VirtualDevice[])_context.getServiceUtil(). - getDynamicProperty(_mor, "config.hardware.device"); - - int deviceNumber = -1; - if(devices != null && devices.length > 0) { - for(VirtualDevice device : devices) { - if(device.getControllerKey() != null && device.getControllerKey().intValue() == controllerKey) { - if(device.getUnitNumber() != null && device.getUnitNumber().intValue() > deviceNumber) { - deviceNumber = device.getUnitNumber().intValue(); - } - } - } - } - return ++deviceNumber; - } - - public VirtualDevice[] getNicDevices() throws Exception { - VirtualDevice[] devices = (VirtualDevice[])_context.getServiceUtil(). - getDynamicProperty(_mor, "config.hardware.device"); - - List nics = new ArrayList(); - if(devices != null) { - for(VirtualDevice device : devices) { - if(device instanceof VirtualEthernetCard) { - nics.add(device); - } - } - } - - return nics.toArray(new VirtualDevice[0]); - } - - public Pair getNicDeviceIndex(String networkNamePrefix) throws Exception { - VirtualDevice[] devices = (VirtualDevice[])_context.getServiceUtil(). - getDynamicProperty(_mor, "config.hardware.device"); - - List nics = new ArrayList(); - if(devices != null) { - for(VirtualDevice device : devices) { - if(device instanceof VirtualEthernetCard) { - nics.add(device); - } - } - } - - Collections.sort(nics, new Comparator() { - @Override - public int compare(VirtualDevice arg0, VirtualDevice arg1) { - int unitNumber0 = arg0.getUnitNumber() != null ? arg0.getUnitNumber().intValue() : -1; - int unitNumber1 = arg1.getUnitNumber() != null ? arg1.getUnitNumber().intValue() : -1; - if(unitNumber0 < unitNumber1) - return -1; - else if(unitNumber0 > unitNumber1) - return 1; - return 0; - } + @Deprecated + public List> getDiskDatastorePathChain(VirtualDisk disk, boolean followChain) throws Exception { + VirtualDeviceBackingInfo backingInfo = disk.getBacking(); + if(!(backingInfo instanceof VirtualDiskFlatVer2BackingInfo)) { + throw new Exception("Unsupported VirtualDeviceBackingInfo"); + } + + List> pathList = new ArrayList>(); + VirtualDiskFlatVer2BackingInfo diskBackingInfo = (VirtualDiskFlatVer2BackingInfo)backingInfo; + + if(!followChain) { + pathList.add(new Pair(diskBackingInfo.getFileName(), diskBackingInfo.getDatastore())); + return pathList; + } + + Pair dcPair = getOwnerDatacenter(); + VirtualMachineFileInfo vmFilesInfo = getFileInfo(); + DatastoreFile snapshotDirFile = new DatastoreFile(vmFilesInfo.getSnapshotDirectory()); + DatastoreFile vmxDirFile = new DatastoreFile(vmFilesInfo.getVmPathName()); + + do { + if(diskBackingInfo.getParent() != null) { + pathList.add(new Pair(diskBackingInfo.getFileName(), diskBackingInfo.getDatastore())); + diskBackingInfo = diskBackingInfo.getParent(); + } else { + // try getting parent info from VMDK file itself + byte[] content = null; + try { + String url = getContext().composeDatastoreBrowseUrl(dcPair.second(), diskBackingInfo.getFileName()); + content = getContext().getResourceContent(url); + if(content == null || content.length == 0) { + break; + } + + pathList.add(new Pair(diskBackingInfo.getFileName(), diskBackingInfo.getDatastore())); + } catch(Exception e) { + // if snapshot directory has been changed to place other than default. VMware has a bug + // that its corresponding disk backing info is not updated correctly. therefore, we will try search + // in snapshot directory one more time + DatastoreFile currentFile = new DatastoreFile(diskBackingInfo.getFileName()); + String vmdkFullDsPath = snapshotDirFile.getCompanionPath(currentFile.getFileName()); + + String url = getContext().composeDatastoreBrowseUrl(dcPair.second(), vmdkFullDsPath); + content = getContext().getResourceContent(url); + if(content == null || content.length == 0) { + break; + } + + pathList.add(new Pair(vmdkFullDsPath, diskBackingInfo.getDatastore())); + } + + VmdkFileDescriptor descriptor = new VmdkFileDescriptor(); + descriptor.parse(content); + if(descriptor.getParentFileName() != null && !descriptor.getParentFileName().isEmpty()) { + // create a fake one + VirtualDiskFlatVer2BackingInfo parentDiskBackingInfo = new VirtualDiskFlatVer2BackingInfo(); + parentDiskBackingInfo.setDatastore(diskBackingInfo.getDatastore()); + + String parentFileName = descriptor.getParentFileName(); + if(parentFileName.startsWith("/")) { + int fileNameStartPos = parentFileName.lastIndexOf("/"); + parentFileName = parentFileName.substring(fileNameStartPos + 1); + parentDiskBackingInfo.setFileName(vmxDirFile.getCompanionPath(parentFileName)); + } else { + parentDiskBackingInfo.setFileName(snapshotDirFile.getCompanionPath(parentFileName)); + } + diskBackingInfo = parentDiskBackingInfo; + } else { + break; + } + } + } while(diskBackingInfo != null); + + return pathList; + } + + private String getDeviceBusName(VirtualDevice[] allDevices, VirtualDevice theDevice) throws Exception { + for(VirtualDevice device : allDevices) { + if(device.getKey() == theDevice.getControllerKey().intValue()) { + if(device instanceof VirtualIDEController) { + return String.format("ide%d:%d", ((VirtualIDEController)device).getBusNumber(), theDevice.getUnitNumber()); + } else if(device instanceof VirtualSCSIController) { + return String.format("scsi%d:%d", ((VirtualSCSIController)device).getBusNumber(), theDevice.getUnitNumber()); + } else { + throw new Exception("Device controller is not supported yet"); + } + } + } + throw new Exception("Unable to find device controller"); + } + + public VirtualDisk[] getAllDiskDevice() throws Exception { + List deviceList = new ArrayList(); + VirtualDevice[] devices = (VirtualDevice[])_context.getServiceUtil().getDynamicProperty(_mor, "config.hardware.device"); + if(devices != null && devices.length > 0) { + for(VirtualDevice device : devices) { + if(device instanceof VirtualDisk) { + deviceList.add((VirtualDisk)device); + } + } + } + + return deviceList.toArray(new VirtualDisk[0]); + } + + public VirtualDisk[] getAllIndependentDiskDevice() throws Exception { + List independentDisks = new ArrayList(); + VirtualDisk[] allDisks = getAllDiskDevice(); + if(allDisks.length > 0) { + for(VirtualDisk disk : allDisks) { + String diskMode = ""; + if(disk.getBacking() instanceof VirtualDiskFlatVer1BackingInfo) { + diskMode = ((VirtualDiskFlatVer1BackingInfo)disk.getBacking()).getDiskMode(); + } else if(disk.getBacking() instanceof VirtualDiskFlatVer2BackingInfo) { + diskMode = ((VirtualDiskFlatVer2BackingInfo)disk.getBacking()).getDiskMode(); + } else if(disk.getBacking() instanceof VirtualDiskRawDiskMappingVer1BackingInfo) { + diskMode = ((VirtualDiskRawDiskMappingVer1BackingInfo)disk.getBacking()).getDiskMode(); + } else if(disk.getBacking() instanceof VirtualDiskSparseVer1BackingInfo) { + diskMode = ((VirtualDiskSparseVer1BackingInfo)disk.getBacking()).getDiskMode(); + } else if(disk.getBacking() instanceof VirtualDiskSparseVer2BackingInfo) { + diskMode = ((VirtualDiskSparseVer2BackingInfo)disk.getBacking()).getDiskMode(); + } + + if(diskMode.indexOf("independent") != -1) { + independentDisks.add(disk); + } + } + } + + return independentDisks.toArray(new VirtualDisk[0]); + } + + public int tryGetIDEDeviceControllerKey() throws Exception { + VirtualDevice[] devices = (VirtualDevice [])_context.getServiceUtil(). + getDynamicProperty(_mor, "config.hardware.device"); + + if(devices != null && devices.length > 0) { + for(VirtualDevice device : devices) { + if(device instanceof VirtualIDEController) { + return ((VirtualIDEController)device).getKey(); + } + } + } + + return -1; + } + + public int getIDEDeviceControllerKey() throws Exception { + VirtualDevice[] devices = (VirtualDevice [])_context.getServiceUtil(). + getDynamicProperty(_mor, "config.hardware.device"); + + if(devices != null && devices.length > 0) { + for(VirtualDevice device : devices) { + if(device instanceof VirtualIDEController) { + return ((VirtualIDEController)device).getKey(); + } + } + } + + assert(false); + throw new Exception("IDE Controller Not Found"); + } + + public int getNextIDEDeviceNumber() throws Exception { + int controllerKey = getIDEDeviceControllerKey(); + return getNextDeviceNumber(controllerKey); + } + + public VirtualDevice getIsoDevice() throws Exception { + VirtualDevice[] devices = (VirtualDevice[])_context.getServiceUtil(). + getDynamicProperty(_mor, "config.hardware.device"); + if(devices != null && devices.length > 0) { + for(VirtualDevice device : devices) { + if(device instanceof VirtualCdrom) { + return device; + } + } + } + return null; + } + + public int getPCIDeviceControllerKey() throws Exception { + VirtualDevice[] devices = (VirtualDevice [])_context.getServiceUtil(). + getDynamicProperty(_mor, "config.hardware.device"); + + if(devices != null && devices.length > 0) { + for(VirtualDevice device : devices) { + if(device instanceof VirtualPCIController) { + return ((VirtualPCIController)device).getKey(); + } + } + } + + assert(false); + throw new Exception("PCI Controller Not Found"); + } + + public int getNextPCIDeviceNumber() throws Exception { + int controllerKey = getPCIDeviceControllerKey(); + return getNextDeviceNumber(controllerKey); + } + + public int getNextDeviceNumber(int controllerKey) throws Exception { + VirtualDevice[] devices = (VirtualDevice[])_context.getServiceUtil(). + getDynamicProperty(_mor, "config.hardware.device"); + + int deviceNumber = -1; + if(devices != null && devices.length > 0) { + for(VirtualDevice device : devices) { + if(device.getControllerKey() != null && device.getControllerKey().intValue() == controllerKey) { + if(device.getUnitNumber() != null && device.getUnitNumber().intValue() > deviceNumber) { + deviceNumber = device.getUnitNumber().intValue(); + } + } + } + } + return ++deviceNumber; + } + + public VirtualDevice[] getNicDevices() throws Exception { + VirtualDevice[] devices = (VirtualDevice[])_context.getServiceUtil(). + getDynamicProperty(_mor, "config.hardware.device"); + + List nics = new ArrayList(); + if(devices != null) { + for(VirtualDevice device : devices) { + if(device instanceof VirtualEthernetCard) { + nics.add(device); + } + } + } + + return nics.toArray(new VirtualDevice[0]); + } + + public Pair getNicDeviceIndex(String networkNamePrefix) throws Exception { + VirtualDevice[] devices = (VirtualDevice[])_context.getServiceUtil(). + getDynamicProperty(_mor, "config.hardware.device"); + + List nics = new ArrayList(); + if(devices != null) { + for(VirtualDevice device : devices) { + if(device instanceof VirtualEthernetCard) { + nics.add(device); + } + } + } + + Collections.sort(nics, new Comparator() { + @Override + public int compare(VirtualDevice arg0, VirtualDevice arg1) { + int unitNumber0 = arg0.getUnitNumber() != null ? arg0.getUnitNumber().intValue() : -1; + int unitNumber1 = arg1.getUnitNumber() != null ? arg1.getUnitNumber().intValue() : -1; + if(unitNumber0 < unitNumber1) + return -1; + else if(unitNumber0 > unitNumber1) + return 1; + return 0; + } }); - - int index = 0; - for(VirtualDevice nic : nics) { - if(((VirtualEthernetCard)nic).getDeviceInfo().getSummary().startsWith(networkNamePrefix)) + + int index = 0; + String attachedNetworkSummary; + String dvPortGroupName; + for (VirtualDevice nic : nics) { + attachedNetworkSummary = ((VirtualEthernetCard) nic).getDeviceInfo().getSummary(); + if (attachedNetworkSummary.startsWith(networkNamePrefix)) { return new Pair(new Integer(index), nic); + } else if (attachedNetworkSummary.endsWith("DistributedVirtualPortBackingInfo.summary")) { + dvPortGroupName = getDvPortGroupName((VirtualEthernetCard) nic); + if (dvPortGroupName != null && dvPortGroupName.startsWith(networkNamePrefix)) { + s_logger.debug("Found a dvPortGroup already associated with public NIC."); + return new Pair(new Integer(index), nic); + } + } index++; } return new Pair(new Integer(-1), null); - } - - public VirtualDevice[] getMatchedDevices(Class[] deviceClasses) throws Exception { - assert(deviceClasses != null); - - List returnList = new ArrayList(); - - VirtualDevice[] devices = (VirtualDevice[])_context.getServiceUtil(). - getDynamicProperty(_mor, "config.hardware.device"); - - if(devices != null) { - for(VirtualDevice device : devices) { - for(Class clz : deviceClasses) { - if(clz.isInstance(device)) { - returnList.add(device); - break; - } - } - } - } - - return returnList.toArray(new VirtualDevice[0]); - } - - public void mountToolsInstaller() throws Exception { - _context.getService().mountToolsInstaller(_mor); - } - - public void unmountToolsInstaller() throws Exception { - _context.getService().unmountToolsInstaller(_mor); - } - - public void redoRegistration(ManagedObjectReference morHost) throws Exception { + } + + public String getDvPortGroupName(VirtualEthernetCard nic) throws Exception { + VirtualEthernetCardDistributedVirtualPortBackingInfo dvpBackingInfo = + (VirtualEthernetCardDistributedVirtualPortBackingInfo) ((VirtualEthernetCard) nic).getBacking(); + DistributedVirtualSwitchPortConnection dvsPort = (DistributedVirtualSwitchPortConnection) dvpBackingInfo.getPort(); + String dvPortGroupKey = dvsPort.getPortgroupKey(); + ManagedObjectReference dvPortGroupMor = new ManagedObjectReference(); + dvPortGroupMor.set_value(dvPortGroupKey); + dvPortGroupMor.setType("DistributedVirtualPortgroup"); + return (String) _context.getServiceUtil().getDynamicProperty(dvPortGroupMor, "name"); + } + + public VirtualDevice[] getMatchedDevices(Class[] deviceClasses) throws Exception { + assert(deviceClasses != null); + + List returnList = new ArrayList(); + + VirtualDevice[] devices = (VirtualDevice[])_context.getServiceUtil(). + getDynamicProperty(_mor, "config.hardware.device"); + + if(devices != null) { + for(VirtualDevice device : devices) { + for(Class clz : deviceClasses) { + if(clz.isInstance(device)) { + returnList.add(device); + break; + } + } + } + } + + return returnList.toArray(new VirtualDevice[0]); + } + + public void mountToolsInstaller() throws Exception { + _context.getService().mountToolsInstaller(_mor); + } + + public void unmountToolsInstaller() throws Exception { + _context.getService().unmountToolsInstaller(_mor); + } + + public void redoRegistration(ManagedObjectReference morHost) throws Exception { String vmName = getVmName(); VirtualMachineFileInfo vmFileInfo = getFileInfo(); boolean isTemplate = isTemplate();