cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From d...@apache.org
Subject [1/4] git commit: updated refs/heads/4.6 to 8c78f89
Date Sat, 12 Dec 2015 13:39:24 GMT
Repository: cloudstack
Updated Branches:
  refs/heads/4.6 65bf2edfa -> 8c78f89c9


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6a9956e0/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java
----------------------------------------------------------------------
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 c3a04b68..eeb0b4d 100644
--- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java
+++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java
@@ -55,12 +55,15 @@ import com.vmware.vim25.OptionValue;
 import com.vmware.vim25.OvfCreateDescriptorParams;
 import com.vmware.vim25.OvfCreateDescriptorResult;
 import com.vmware.vim25.OvfFile;
+import com.vmware.vim25.ParaVirtualSCSIController;
 import com.vmware.vim25.PropertyFilterSpec;
 import com.vmware.vim25.PropertySpec;
 import com.vmware.vim25.TraversalSpec;
+import com.vmware.vim25.VirtualBusLogicController;
 import com.vmware.vim25.VirtualCdrom;
 import com.vmware.vim25.VirtualCdromIsoBackingInfo;
 import com.vmware.vim25.VirtualCdromRemotePassthroughBackingInfo;
+import com.vmware.vim25.VirtualController;
 import com.vmware.vim25.VirtualDevice;
 import com.vmware.vim25.VirtualDeviceBackingInfo;
 import com.vmware.vim25.VirtualDeviceConfigSpec;
@@ -80,6 +83,7 @@ import com.vmware.vim25.VirtualEthernetCardDistributedVirtualPortBackingInfo;
 import com.vmware.vim25.VirtualHardwareOption;
 import com.vmware.vim25.VirtualIDEController;
 import com.vmware.vim25.VirtualLsiLogicController;
+import com.vmware.vim25.VirtualLsiLogicSASController;
 import com.vmware.vim25.VirtualMachineCloneSpec;
 import com.vmware.vim25.VirtualMachineConfigInfo;
 import com.vmware.vim25.VirtualMachineConfigOption;
@@ -97,7 +101,6 @@ import com.vmware.vim25.VirtualMachineRelocateSpecDiskLocator;
 import com.vmware.vim25.VirtualMachineRuntimeInfo;
 import com.vmware.vim25.VirtualMachineSnapshotInfo;
 import com.vmware.vim25.VirtualMachineSnapshotTree;
-import com.vmware.vim25.VirtualPCIController;
 import com.vmware.vim25.VirtualSCSIController;
 import com.vmware.vim25.VirtualSCSISharing;
 
@@ -1091,6 +1094,130 @@ public class VirtualMachineMO extends BaseMO {
             s_logger.trace("vCenter API trace - createDisk() done(successfully)");
     }
 
+    public void updateVmdkAdapter(String vmdkFileName, String newAdapterType) throws Exception
{
+        Pair<VmdkFileDescriptor, byte[]> vmdkInfo = getVmdkFileInfo(vmdkFileName);
+        VmdkFileDescriptor vmdkFileDescriptor = vmdkInfo.first();
+        boolean isVmfsSparseFile = vmdkFileDescriptor.isVmfsSparseFile();
+        if (!isVmfsSparseFile) {
+            String currentAdapterType = vmdkFileDescriptor.getAdapterType();
+            if (!currentAdapterType.equalsIgnoreCase(newAdapterType)) {
+                s_logger.info("Updating adapter type to " + newAdapterType + " for VMDK file
" + vmdkFileName);
+                Pair<DatacenterMO, String> dcInfo = getOwnerDatacenter();
+                byte[] newVmdkContent = vmdkFileDescriptor.changeVmdkAdapterType(vmdkInfo.second(),
newAdapterType);
+                String vmdkUploadUrl = getContext().composeDatastoreBrowseUrl(dcInfo.first().getName(),
vmdkFileName);
+                getContext().uploadResourceContent(vmdkUploadUrl, newVmdkContent);
+                s_logger.info("Updated VMDK file " + vmdkFileName);
+            }
+        }
+    }
+
+    public void updateAdapterTypeIfRequired(String vmdkFileName) throws Exception {
+        // Validate existing adapter type of VMDK file. Update it with a supported adapter
type if validation fails.
+        Pair<VmdkFileDescriptor, byte[]> vmdkInfo = getVmdkFileInfo(vmdkFileName);
+        VmdkFileDescriptor vmdkFileDescriptor = vmdkInfo.first();
+
+        boolean isVmfsSparseFile = vmdkFileDescriptor.isVmfsSparseFile();
+        if (!isVmfsSparseFile) {
+            String currentAdapterTypeStr = vmdkFileDescriptor.getAdapterType();
+            if (s_logger.isTraceEnabled()) {
+                s_logger.trace("Detected adapter type  " + currentAdapterTypeStr + " for
VMDK file " + vmdkFileName);
+            }
+            VmdkAdapterType currentAdapterType = VmdkAdapterType.getType(currentAdapterTypeStr);
+            if (currentAdapterType == VmdkAdapterType.none) {
+                // Value of currentAdapterType can be VmdkAdapterType.none only if adapter
type of vmdk is set to either
+                // lsisas1068 (SAS controller) or pvscsi (Vmware Paravirtual) only. Valid
adapter type for those controllers is lsilogic.
+                // Hence use adapter type lsilogic. Other adapter types ide, lsilogic, buslogic
are valid and does not need to be modified.
+                VmdkAdapterType newAdapterType = VmdkAdapterType.lsilogic;
+                s_logger.debug("Updating adapter type to " + newAdapterType + " from " +
currentAdapterTypeStr + " for VMDK file " + vmdkFileName);
+                Pair<DatacenterMO, String> dcInfo = getOwnerDatacenter();
+                byte[] newVmdkContent = vmdkFileDescriptor.changeVmdkAdapterType(vmdkInfo.second(),
newAdapterType.toString());
+                String vmdkUploadUrl = getContext().composeDatastoreBrowseUrl(dcInfo.first().getName(),
vmdkFileName);
+
+                getContext().uploadResourceContent(vmdkUploadUrl, newVmdkContent);
+                s_logger.debug("Updated VMDK file " + vmdkFileName);
+            }
+        }
+    }
+
+    public void attachDisk(String[] vmdkDatastorePathChain, ManagedObjectReference morDs,
String diskController) throws Exception {
+
+        if(s_logger.isTraceEnabled())
+            s_logger.trace("vCenter API trace - attachDisk(). target MOR: " + _mor.getValue()
+ ", vmdkDatastorePath: "
+                            + new Gson().toJson(vmdkDatastorePathChain) + ", datastore: "
+ morDs.getValue());
+        int controllerKey = 0;
+        int unitNumber = 0;
+
+        if (DiskControllerType.getType(diskController) == DiskControllerType.ide) {
+            // IDE virtual disk cannot be added if VM is running
+            if (getPowerState() == VirtualMachinePowerState.POWERED_ON) {
+                throw new Exception("Adding a virtual disk over IDE controller is not supported
while VM is running in VMware hypervisor. Please re-try when VM is not running.");
+            }
+            // Get next available unit number and controller key
+            int ideDeviceCount = getNumberOfIDEDevices();
+            if (ideDeviceCount >= VmwareHelper.MAX_IDE_CONTROLLER_COUNT * VmwareHelper.MAX_ALLOWED_DEVICES_IDE_CONTROLLER)
{
+                throw new Exception("Maximum limit of  devices supported on IDE controllers
[" + VmwareHelper.MAX_IDE_CONTROLLER_COUNT
+                        * VmwareHelper.MAX_ALLOWED_DEVICES_IDE_CONTROLLER + "] is reached.");
+            }
+            controllerKey = getIDEControllerKey(ideDeviceCount);
+            unitNumber = getFreeUnitNumberOnIDEController(controllerKey);
+        } else {
+            controllerKey = getScsiDiskControllerKey(diskController);
+            unitNumber = -1;
+        }
+        synchronized (_mor.getValue().intern()) {
+            VirtualDevice newDisk = VmwareHelper.prepareDiskDevice(this, null, controllerKey,
vmdkDatastorePathChain, morDs, unitNumber, 1);
+            controllerKey = newDisk.getControllerKey();
+            unitNumber = newDisk.getUnitNumber();
+            VirtualDiskFlatVer2BackingInfo backingInfo = (VirtualDiskFlatVer2BackingInfo)newDisk.getBacking();
+            String vmdkFileName = backingInfo.getFileName();
+            DiskControllerType diskControllerType = DiskControllerType.getType(diskController);
+            VmdkAdapterType vmdkAdapterType = VmdkAdapterType.getAdapterType(diskControllerType);
+            if (vmdkAdapterType == VmdkAdapterType.none) {
+                String message = "Failed to attach disk due to invalid vmdk adapter type
for vmdk file [" +
+                    vmdkFileName + "] with controller : " + diskControllerType;
+                s_logger.debug(message);
+                throw new Exception(message);
+            }
+            updateVmdkAdapter(vmdkFileName, vmdkAdapterType.toString());
+            VirtualMachineConfigSpec reConfigSpec = new VirtualMachineConfigSpec();
+            VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec();
+
+            deviceConfigSpec.setDevice(newDisk);
+            deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
+
+            reConfigSpec.getDeviceChange().add(deviceConfigSpec);
+
+            ManagedObjectReference morTask = _context.getService().reconfigVMTask(_mor, reConfigSpec);
+            boolean result = _context.getVimClient().waitForTask(morTask);
+
+            if (!result) {
+                if (s_logger.isTraceEnabled())
+                    s_logger.trace("vCenter API trace - attachDisk() done(failed)");
+                throw new Exception("Failed to attach disk due to " + TaskMO.getTaskFailureInfo(_context,
morTask));
+            }
+
+            _context.waitForTaskProgressDone(morTask);
+        }
+
+        if(s_logger.isTraceEnabled())
+            s_logger.trace("vCenter API trace - attachDisk() done(successfully)");
+    }
+
+    private int getControllerBusNumber(int controllerKey) throws Exception {
+        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
+                getDynamicProperty(_mor, "config.hardware.device");
+
+        if (devices != null && devices.size() > 0) {
+            for (VirtualDevice device : devices) {
+                if (device instanceof VirtualController && device.getKey() == controllerKey)
{
+                    return ((VirtualController)device).getBusNumber();
+                }
+            }
+        }
+        throw new Exception("SCSI Controller with key " + controllerKey + " is Not Found");
+
+    }
+
     public void attachDisk(String[] vmdkDatastorePathChain, ManagedObjectReference morDs)
throws Exception {
 
         if (s_logger.isTraceEnabled())
@@ -1760,20 +1887,17 @@ public class VirtualMachineMO extends BaseMO {
         }
     }
 
-  public String getGuestId() throws Exception {
-    return (String)_context.getVimClient().getDynamicProperty(_mor, "config.guestId");
-  }
-
     public GuestOsDescriptor getGuestOsDescriptor(String guestOsId) throws Exception {
         GuestOsDescriptor guestOsDescriptor = null;
-        if (guestOsId == null) {
-            guestOsId = getGuestId();
+        String guestId = guestOsId;
+        if (guestId == null) {
+            guestId = getGuestId();
         }
         ManagedObjectReference vmEnvironmentBrowser = _context.getVimClient().getMoRefProp(_mor,
"environmentBrowser");
         VirtualMachineConfigOption vmConfigOption = _context.getService().queryConfigOption(vmEnvironmentBrowser,
null, null);
         List<GuestOsDescriptor> guestDescriptors = vmConfigOption.getGuestOSDescriptor();
         for (GuestOsDescriptor descriptor : guestDescriptors) {
-            if (guestOsId != null && guestOsId.equalsIgnoreCase(descriptor.getId()))
{
+            if (guestId != null && guestId.equalsIgnoreCase(descriptor.getId()))
{
                 guestOsDescriptor = descriptor;
                 break;
             }
@@ -1912,6 +2036,134 @@ public class VirtualMachineMO extends BaseMO {
         }
     }
 
+    public int getPvScsiDeviceControllerKeyNoException() throws Exception {
+        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
+                getDynamicProperty(_mor, "config.hardware.device");
+
+        if (devices != null && devices.size() > 0) {
+            for (VirtualDevice device : devices) {
+                if (device instanceof ParaVirtualSCSIController) {
+                    return device.getKey();
+                }
+            }
+        }
+
+        return -1;
+    }
+
+    public int getPvScsiDeviceControllerKey() throws Exception {
+        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
+                getDynamicProperty(_mor, "config.hardware.device");
+
+        if (devices != null && devices.size() > 0) {
+            for (VirtualDevice device : devices) {
+                if (device instanceof ParaVirtualSCSIController) {
+                    return device.getKey();
+                }
+            }
+        }
+
+        assert (false);
+        throw new Exception("VMware Paravirtual SCSI Controller Not Found");
+    }
+
+    public void ensurePvScsiDeviceController(int requiredNumScsiControllers, int availableBusNum)
throws Exception {
+        VirtualMachineConfigSpec vmConfig = new VirtualMachineConfigSpec();
+
+        int busNum = availableBusNum;
+        while (busNum < requiredNumScsiControllers) {
+            ParaVirtualSCSIController scsiController = new ParaVirtualSCSIController();
+
+            scsiController.setSharedBus(VirtualSCSISharing.NO_SHARING);
+            scsiController.setBusNumber(busNum);
+            scsiController.setKey(busNum - VmwareHelper.MAX_SCSI_CONTROLLER_COUNT);
+            VirtualDeviceConfigSpec scsiControllerSpec = new VirtualDeviceConfigSpec();
+            scsiControllerSpec.setDevice(scsiController);
+            scsiControllerSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
+
+            vmConfig.getDeviceChange().add(scsiControllerSpec);
+            busNum++;
+        }
+
+        if (configureVm(vmConfig)) {
+            throw new Exception("Unable to add Scsi controllers to the VM " + getName());
+        } else {
+            s_logger.info("Successfully added " + requiredNumScsiControllers + " SCSI controllers.");
+        }
+    }
+
+    public String getRecommendedDiskController(String guestOsId) throws Exception {
+        String recommendedController;
+        GuestOsDescriptor guestOsDescriptor = getGuestOsDescriptor(guestOsId);
+        recommendedController = VmwareHelper.getRecommendedDiskControllerFromDescriptor(guestOsDescriptor);
+        return recommendedController;
+    }
+
+    public boolean isPvScsiSupported() throws Exception {
+        int virtualHardwareVersion;
+
+        virtualHardwareVersion = getVirtualHardwareVersion();
+
+        // Check if virtual machine is using hardware version 7 or later.
+        if (virtualHardwareVersion < 7) {
+            s_logger.error("The virtual hardware version of the VM is " + virtualHardwareVersion
+                    + ", which doesn't support PV SCSI controller type for virtual harddisks.
Please upgrade this VM's virtual hardware version to 7 or later.");
+            return false;
+        }
+        return true;
+    }
+
+    // Would be useful if there exists multiple sub types of SCSI controllers per VM are
supported in CloudStack f
+    public int getScsiDiskControllerKey(String diskController) throws Exception {
+        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
+                getDynamicProperty(_mor, "config.hardware.device");
+
+        if (devices != null && devices.size() > 0) {
+            for (VirtualDevice device : devices) {
+                if ((DiskControllerType.getType(diskController) == DiskControllerType.lsilogic
|| DiskControllerType.getType(diskController) == DiskControllerType.scsi)
+                        && device instanceof VirtualLsiLogicController) {
+                    return ((VirtualLsiLogicController)device).getKey();
+                } else if ((DiskControllerType.getType(diskController) == DiskControllerType.lsisas1068
|| DiskControllerType.getType(diskController) == DiskControllerType.scsi)
+                        && device instanceof VirtualLsiLogicSASController) {
+                    return ((VirtualLsiLogicSASController)device).getKey();
+                } else if ((DiskControllerType.getType(diskController) == DiskControllerType.pvscsi
|| DiskControllerType.getType(diskController) == DiskControllerType.scsi)
+                        && device instanceof ParaVirtualSCSIController) {
+                    return ((ParaVirtualSCSIController)device).getKey();
+                } else if ((DiskControllerType.getType(diskController) == DiskControllerType.buslogic
|| DiskControllerType.getType(diskController) == DiskControllerType.scsi)
+                        && device instanceof VirtualBusLogicController) {
+                    return ((VirtualBusLogicController)device).getKey();
+                }
+            }
+        }
+
+        assert (false);
+        throw new Exception(diskController + " Controller Not Found");
+    }
+
+    public int getScsiDiskControllerKeyNoException(String diskController) throws Exception
{
+        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
+                getDynamicProperty(_mor, "config.hardware.device");
+
+        if (devices != null && devices.size() > 0) {
+            for (VirtualDevice device : devices) {
+                if ((DiskControllerType.getType(diskController) == DiskControllerType.lsilogic
|| DiskControllerType.getType(diskController) == DiskControllerType.scsi)
+                        && device instanceof VirtualLsiLogicController) {
+                    return ((VirtualLsiLogicController)device).getKey();
+                } else if ((DiskControllerType.getType(diskController) == DiskControllerType.lsisas1068
|| DiskControllerType.getType(diskController) == DiskControllerType.scsi)
+                        && device instanceof VirtualLsiLogicSASController) {
+                    return ((VirtualLsiLogicSASController)device).getKey();
+                } else if ((DiskControllerType.getType(diskController) == DiskControllerType.pvscsi
|| DiskControllerType.getType(diskController) == DiskControllerType.scsi)
+                        && device instanceof ParaVirtualSCSIController) {
+                    return ((ParaVirtualSCSIController)device).getKey();
+                } else if ((DiskControllerType.getType(diskController) == DiskControllerType.buslogic
|| DiskControllerType.getType(diskController) == DiskControllerType.scsi)
+                        && device instanceof VirtualBusLogicController) {
+                    return ((VirtualBusLogicController)device).getKey();
+                }
+            }
+        }
+        return -1;
+    }
+
     public int getNextScsiDiskDeviceNumber() throws Exception {
         int scsiControllerKey = getScsiDeviceControllerKey();
         int deviceNumber = getNextDeviceNumber(scsiControllerKey);
@@ -1924,7 +2176,7 @@ public class VirtualMachineMO extends BaseMO {
 
         if (devices != null && devices.size() > 0) {
             for (VirtualDevice device : devices) {
-                if (device instanceof VirtualLsiLogicController) {
+                if (device instanceof VirtualSCSIController) {
                     return device.getKey();
                 }
             }
@@ -1949,11 +2201,12 @@ public class VirtualMachineMO extends BaseMO {
     }
 
     public int getScsiDeviceControllerKeyNoException() throws Exception {
-        List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor,
"config.hardware.device");
+        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
+            getDynamicProperty(_mor, "config.hardware.device");
 
-        if (devices != null && devices.size() > 0) {
-            for (VirtualDevice device : devices) {
-                if (device instanceof VirtualLsiLogicController) {
+        if(devices != null && devices.size() > 0) {
+            for(VirtualDevice device : devices) {
+                if(device instanceof VirtualLsiLogicController) {
                     return device.getKey();
                 }
             }
@@ -1983,6 +2236,32 @@ public class VirtualMachineMO extends BaseMO {
         }
     }
 
+    public void ensureScsiDeviceControllers(int count, int availableBusNum) throws Exception
{
+        int scsiControllerKey = getScsiDeviceControllerKeyNoException();
+        if (scsiControllerKey < 0) {
+            VirtualMachineConfigSpec vmConfig = new VirtualMachineConfigSpec();
+
+            int busNum = availableBusNum;
+            while (busNum < count) {
+            VirtualLsiLogicController scsiController = new VirtualLsiLogicController();
+            scsiController.setSharedBus(VirtualSCSISharing.NO_SHARING);
+                scsiController.setBusNumber(busNum);
+                scsiController.setKey(busNum - VmwareHelper.MAX_SCSI_CONTROLLER_COUNT);
+            VirtualDeviceConfigSpec scsiControllerSpec = new VirtualDeviceConfigSpec();
+            scsiControllerSpec.setDevice(scsiController);
+            scsiControllerSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
+
+            vmConfig.getDeviceChange().add(scsiControllerSpec);
+                busNum++;
+            }
+            if (configureVm(vmConfig)) {
+                throw new Exception("Unable to add Scsi controllers to the VM " + getName());
+            } else {
+                s_logger.info("Successfully added " + count + " SCSI controllers.");
+            }
+        }
+    }
+
     // return pair of VirtualDisk and disk device bus name(ide0:0, etc)
     public Pair<VirtualDisk, String> getDiskDevice(String vmdkDatastorePath) throws
Exception {
         List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor,
"config.hardware.device");
@@ -2361,43 +2640,84 @@ public class VirtualMachineMO extends BaseMO {
         throw new Exception("IDE Controller Not Found");
     }
 
-    public int getNextIDEDeviceNumber() throws Exception {
-        int controllerKey = getIDEDeviceControllerKey();
-        return getNextDeviceNumber(controllerKey);
+    public int getIDEControllerKey(int ideUnitNumber) throws Exception {
+        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
+            getDynamicProperty(_mor, "config.hardware.device");
+
+        int requiredIdeController = ideUnitNumber / VmwareHelper.MAX_IDE_CONTROLLER_COUNT;
+
+        int ideControllerCount = 0;
+        if(devices != null && devices.size() > 0) {
+            for(VirtualDevice device : devices) {
+                if(device instanceof VirtualIDEController) {
+                    if (ideControllerCount == requiredIdeController) {
+                        return ((VirtualIDEController)device).getKey();
+                    }
+                    ideControllerCount++;
+                }
+            }
+        }
+
+        assert(false);
+        throw new Exception("IDE Controller Not Found");
     }
 
-    public VirtualDevice getIsoDevice() throws Exception {
-        List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor,
"config.hardware.device");
+    public int getNumberOfIDEDevices() throws Exception {
+        int ideDeviceCount = 0;
+        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
+                getDynamicProperty(_mor, "config.hardware.device");
+
         if (devices != null && devices.size() > 0) {
             for (VirtualDevice device : devices) {
-                if (device instanceof VirtualCdrom) {
-                    return device;
+                if (device instanceof VirtualIDEController) {
+                    ideDeviceCount += ((VirtualIDEController)device).getDevice().size();
                 }
             }
         }
-        return null;
+        return ideDeviceCount;
     }
 
-    public int getPCIDeviceControllerKey() throws Exception {
-        List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor,
"config.hardware.device");
+    public int getFreeUnitNumberOnIDEController(int controllerKey) throws Exception {
+        int freeUnitNumber = 0;
+        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
+                getDynamicProperty(_mor, "config.hardware.device");
 
+        int deviceCount = 0;
+        int ideDeviceUnitNumber = -1;
         if (devices != null && devices.size() > 0) {
             for (VirtualDevice device : devices) {
-                if (device instanceof VirtualPCIController) {
-                    return ((VirtualPCIController)device).getKey();
+                if (device instanceof VirtualDisk && (controllerKey == device.getControllerKey()))
{
+                    deviceCount++;
+                    ideDeviceUnitNumber = device.getUnitNumber();
                 }
             }
         }
-
-        assert (false);
-        throw new Exception("PCI Controller Not Found");
+        if (deviceCount == 1) {
+            if (ideDeviceUnitNumber == 0) {
+                freeUnitNumber = 1;
+            } // else freeUnitNumber is already initialized to 0
+        } else if (deviceCount == 2) {
+            throw new Exception("IDE controller with key [" + controllerKey + "] already
has 2 device attached. Cannot attach more than the limit of 2.");
+        }
+        return freeUnitNumber;
     }
-
-    public int getNextPCIDeviceNumber() throws Exception {
-        int controllerKey = getPCIDeviceControllerKey();
+    public int getNextIDEDeviceNumber() throws Exception {
+        int controllerKey = getIDEDeviceControllerKey();
         return getNextDeviceNumber(controllerKey);
     }
 
+    public VirtualDevice getIsoDevice() throws Exception {
+        List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor,
"config.hardware.device");
+        if (devices != null && devices.size() > 0) {
+            for (VirtualDevice device : devices) {
+                if (device instanceof VirtualCdrom) {
+                    return device;
+                }
+            }
+        }
+        return null;
+    }
+
     public int getNextDeviceNumber(int controllerKey) throws Exception {
         List<VirtualDevice> devices = _context.getVimClient().getDynamicProperty(_mor,
"config.hardware.device");
 
@@ -2653,6 +2973,9 @@ public class VirtualMachineMO extends BaseMO {
     public long getHotAddMemoryLimitInMb() throws Exception {
         return (Long)_context.getVimClient().getDynamicProperty(_mor, "config.hotPlugMemoryLimit");
     }
+    public String getGuestId() throws Exception {
+        return (String)_context.getVimClient().getDynamicProperty(_mor, "config.guestId");
+    }
 
     public int getCoresPerSocket() throws Exception {
         // number of cores per socket is 1 in case of ESXi. It's not defined explicitly and
the property is support since vSphere API 5.0.
@@ -2729,6 +3052,135 @@ public class VirtualMachineMO extends BaseMO {
         }
         return guestOsSupportsMemoryHotAdd && virtualHardwareSupportsMemoryHotAdd;
     }
+    public void ensureLsiLogicSasDeviceControllers(int count, int availableBusNum) throws
Exception {
+        int scsiControllerKey = getLsiLogicSasDeviceControllerKeyNoException();
+        if (scsiControllerKey < 0) {
+            VirtualMachineConfigSpec vmConfig = new VirtualMachineConfigSpec();
+
+            int busNum = availableBusNum;
+            while (busNum < count) {
+                VirtualLsiLogicSASController scsiController = new VirtualLsiLogicSASController();
+                scsiController.setSharedBus(VirtualSCSISharing.NO_SHARING);
+                scsiController.setBusNumber(busNum);
+                scsiController.setKey(busNum - VmwareHelper.MAX_SCSI_CONTROLLER_COUNT);
+                VirtualDeviceConfigSpec scsiControllerSpec = new VirtualDeviceConfigSpec();
+                scsiControllerSpec.setDevice(scsiController);
+                scsiControllerSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
+
+                vmConfig.getDeviceChange().add(scsiControllerSpec);
+                busNum++;
+            }
+            if (configureVm(vmConfig)) {
+                throw new Exception("Unable to add Scsi controller of type LsiLogic SAS.");
+            }
+        }
+
+    }
+
+    private int getLsiLogicSasDeviceControllerKeyNoException() throws Exception {
+        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
+                getDynamicProperty(_mor, "config.hardware.device");
+
+        if (devices != null && devices.size() > 0) {
+            for (VirtualDevice device : devices) {
+                if (device instanceof VirtualLsiLogicSASController) {
+                    return device.getKey();
+                }
+            }
+        }
+
+        return -1;
+    }
+
+    public void ensureBusLogicDeviceControllers(int count, int availableBusNum) throws Exception
{
+        int scsiControllerKey = getBusLogicDeviceControllerKeyNoException();
+        if (scsiControllerKey < 0) {
+            VirtualMachineConfigSpec vmConfig = new VirtualMachineConfigSpec();
+
+            int busNum = availableBusNum;
+            while (busNum < count) {
+                VirtualBusLogicController scsiController = new VirtualBusLogicController();
+
+                scsiController.setSharedBus(VirtualSCSISharing.NO_SHARING);
+                scsiController.setBusNumber(busNum);
+                scsiController.setKey(busNum - VmwareHelper.MAX_SCSI_CONTROLLER_COUNT);
+                VirtualDeviceConfigSpec scsiControllerSpec = new VirtualDeviceConfigSpec();
+                scsiControllerSpec.setDevice(scsiController);
+                scsiControllerSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD);
+
+                vmConfig.getDeviceChange().add(scsiControllerSpec);
+                busNum++;
+            }
+
+            if (configureVm(vmConfig)) {
+                throw new Exception("Unable to add Scsi BusLogic controllers to the VM "
+ getName());
+            } else {
+                s_logger.info("Successfully added " + count + " SCSI BusLogic controllers.");
+            }
+        }
+    }
+
+    private int getBusLogicDeviceControllerKeyNoException() throws Exception {
+        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
+                getDynamicProperty(_mor, "config.hardware.device");
+
+        if (devices != null && devices.size() > 0) {
+            for (VirtualDevice device : devices) {
+                if (device instanceof VirtualBusLogicController) {
+                    return device.getKey();
+                }
+            }
+        }
+
+        return -1;
+    }
+
+    public Ternary<Integer, Integer, DiskControllerType> getScsiControllerInfo() throws
Exception {
+        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
+                getDynamicProperty(_mor, "config.hardware.device");
+
+        int scsiControllerCount = 0;
+        int busNum = -1;
+        DiskControllerType controllerType = DiskControllerType.lsilogic;
+        if (devices != null && devices.size() > 0) {
+            for (VirtualDevice device : devices) {
+                if (device instanceof VirtualSCSIController) {
+                    scsiControllerCount++;
+                    int deviceBus = ((VirtualSCSIController)device).getBusNumber();
+                    if (busNum < deviceBus) {
+                        busNum = deviceBus;
+                    }
+                    if (device instanceof VirtualLsiLogicController) {
+                        controllerType = DiskControllerType.lsilogic;
+                    } else if (device instanceof VirtualLsiLogicSASController) {
+                        controllerType = DiskControllerType.lsisas1068;
+                    } else if (device instanceof VirtualBusLogicController) {
+                        controllerType = DiskControllerType.buslogic;
+                    } else if (device instanceof ParaVirtualSCSIController) {
+                        controllerType = DiskControllerType.pvscsi;
+                    }
+                }
+            }
+        }
+
+        return new Ternary<Integer, Integer, DiskControllerType>(scsiControllerCount,
busNum, controllerType);
+    }
+
+    public int getNumberOfVirtualDisks() throws Exception {
+        List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().getDynamicProperty(_mor,
"config.hardware.device");
+
+        s_logger.info("Counting disk devices attached to VM " + getVmName());
+        int count = 0;
+
+        if (devices != null && devices.size() > 0) {
+            for (VirtualDevice device : devices) {
+                if (device instanceof VirtualDisk) {
+                    count++;
+                }
+            }
+        }
+        return count;
+    }
 
     public boolean consolidateVmDisks() throws Exception {
         ManagedObjectReference morTask = _context.getService().consolidateVMDisksTask(_mor);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6a9956e0/vmware-base/src/com/cloud/hypervisor/vmware/mo/VmdkAdapterType.java
----------------------------------------------------------------------
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VmdkAdapterType.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VmdkAdapterType.java
new file mode 100644
index 0000000..f602c46
--- /dev/null
+++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VmdkAdapterType.java
@@ -0,0 +1,48 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.hypervisor.vmware.mo;
+
+public enum VmdkAdapterType {
+    ide,
+    lsilogic,
+    buslogic,
+    none;
+
+    public static VmdkAdapterType getAdapterType(DiskControllerType diskControllerType) {
+        if (diskControllerType == DiskControllerType.ide) {
+            return VmdkAdapterType.ide;
+        } else if (diskControllerType == DiskControllerType.buslogic) {
+            return VmdkAdapterType.buslogic;
+        } else if (diskControllerType == DiskControllerType.lsilogic || diskControllerType
== DiskControllerType.pvscsi || diskControllerType == DiskControllerType.lsisas1068) {
+            return VmdkAdapterType.lsilogic;
+        } else {
+            return VmdkAdapterType.none;
+        }
+    }
+
+    public static VmdkAdapterType getType(String vmdkAdapterType) {
+        if (vmdkAdapterType.equalsIgnoreCase("ide")) {
+            return VmdkAdapterType.ide;
+        } else if (vmdkAdapterType.equalsIgnoreCase("lsilogic")) {
+            return VmdkAdapterType.lsilogic;
+        } else if (vmdkAdapterType.equalsIgnoreCase("buslogic")) {
+            return VmdkAdapterType.buslogic;
+        } else {
+            return VmdkAdapterType.none;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6a9956e0/vmware-base/src/com/cloud/hypervisor/vmware/mo/VmdkFileDescriptor.java
----------------------------------------------------------------------
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VmdkFileDescriptor.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VmdkFileDescriptor.java
index fdce93c..556efd7 100644
--- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VmdkFileDescriptor.java
+++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VmdkFileDescriptor.java
@@ -29,6 +29,9 @@ import org.apache.log4j.Logger;
 
 public class VmdkFileDescriptor {
     private static final Logger s_logger = Logger.getLogger(VmdkFileDescriptor.class);
+    private static final String VMDK_PROPERTY_CREATE_TYPE = "createType";
+    private static final String VMDK_CREATE_TYPE_VMFSSPARSE = "vmfsSparse";
+    private static final String VMDK_PROPERTY_ADAPTER_TYPE = "ddb.adapterType";
 
     private Properties _properties = new Properties();
     private String _baseFileName;
@@ -84,6 +87,73 @@ public class VmdkFileDescriptor {
         return _properties.getProperty("parentFileNameHint");
     }
 
+    public boolean isVmfsSparseFile() {
+        String vmdkCreateType = _properties.getProperty(VMDK_PROPERTY_CREATE_TYPE);
+        if (vmdkCreateType.equalsIgnoreCase(VMDK_CREATE_TYPE_VMFSSPARSE)) {
+            return true;
+        }
+        return false;
+    }
+
+    public String getAdapterType() {
+        return _properties.getProperty(VMDK_PROPERTY_ADAPTER_TYPE);
+    }
+
+
+    public static byte[] changeVmdkAdapterType(byte[] vmdkContent, String newAdapterType)
throws IOException {
+        assert (vmdkContent != null);
+
+        BufferedReader in = null;
+        BufferedWriter out = null;
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+        try {
+            in = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(vmdkContent)));
+            out = new BufferedWriter(new OutputStreamWriter(bos));
+            String line;
+            while ((line = in.readLine()) != null) {
+                // ignore empty and comment lines
+                line = line.trim();
+                if (line.isEmpty()) {
+                    out.newLine();
+                    continue;
+                }
+                if (line.charAt(0) == '#') {
+                    out.write(line);
+                    out.newLine();
+                    continue;
+                }
+
+                String[] tokens = line.split("=");
+                if (tokens.length == 2) {
+                    String name = tokens[0].trim();
+                    String value = tokens[1].trim();
+                    if (value.charAt(0) == '\"')
+                        value = value.substring(1, value.length() - 1);
+
+                    if (newAdapterType != null && name.equals(VMDK_PROPERTY_ADAPTER_TYPE))
{
+                        out.write(name + "=\"" + newAdapterType + "\"");
+                        out.newLine();
+                    } else {
+                        out.write(line);
+                        out.newLine();
+                    }
+                } else {
+                    out.write(line);
+                    out.newLine();
+                }
+            }
+        } finally {
+            if (in != null)
+                in.close();
+            if (out != null)
+                out.close();
+        }
+
+        return bos.toByteArray();
+
+    }
+
     public static byte[] changeVmdkContentBaseInfo(byte[] vmdkContent, String baseFileName,
String parentFileName) throws IOException {
 
         assert (vmdkContent != null);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6a9956e0/vmware-base/src/com/cloud/hypervisor/vmware/mo/VmwareHypervisorHost.java
----------------------------------------------------------------------
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VmwareHypervisorHost.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VmwareHypervisorHost.java
index 9727e17..fdfc254 100644
--- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VmwareHypervisorHost.java
+++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VmwareHypervisorHost.java
@@ -23,6 +23,7 @@ import com.vmware.vim25.ObjectContent;
 import com.vmware.vim25.VirtualMachineConfigSpec;
 
 import com.cloud.hypervisor.vmware.util.VmwareContext;
+import com.cloud.utils.Pair;
 
 /**
  * Interface to consolidate ESX(i) hosts and HA/FT clusters into a common interface used
by CloudStack Hypervisor resources
@@ -53,7 +54,8 @@ public interface VmwareHypervisorHost {
     boolean createVm(VirtualMachineConfigSpec vmSpec) throws Exception;
 
     boolean createBlankVm(String vmName, String vmInternalCSName, int cpuCount, int cpuSpeedMHz,
int cpuReservedMHz, boolean limitCpuUse, int memoryMB,
-        int memoryReserveMB, String guestOsIdentifier, ManagedObjectReference morDs, boolean
snapshotDirToParent) throws Exception;
+        int memoryReserveMB, String guestOsIdentifier, ManagedObjectReference morDs, boolean
snapshotDirToParent,
+        Pair<String, String> controllerInfo, Boolean systemVm) throws Exception;
 
     void importVmFromOVF(String ovfFilePath, String vmName, DatastoreMO dsMo, String diskOption)
throws Exception;
 
@@ -81,4 +83,5 @@ public interface VmwareHypervisorHost {
     ComputeResourceSummary getHyperHostHardwareSummary() throws Exception;
 
     LicenseAssignmentManagerMO getLicenseAssignmentManager() throws Exception;
+    String getRecommendedDiskController(String guestOsId) throws Exception;
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6a9956e0/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareHelper.java
----------------------------------------------------------------------
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareHelper.java b/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareHelper.java
index 817ce26..b1c28b9 100644
--- a/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareHelper.java
+++ b/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareHelper.java
@@ -34,6 +34,7 @@ import org.apache.log4j.Logger;
 
 import com.vmware.vim25.DistributedVirtualSwitchPortConnection;
 import com.vmware.vim25.DynamicProperty;
+import com.vmware.vim25.GuestOsDescriptor;
 import com.vmware.vim25.ManagedObjectReference;
 import com.vmware.vim25.MethodFault;
 import com.vmware.vim25.ObjectContent;
@@ -62,6 +63,7 @@ import com.vmware.vim25.VirtualPCNet32;
 import com.vmware.vim25.VirtualVmxnet2;
 import com.vmware.vim25.VirtualVmxnet3;
 
+import com.cloud.hypervisor.vmware.mo.DiskControllerType;
 import com.cloud.hypervisor.vmware.mo.HostMO;
 import com.cloud.hypervisor.vmware.mo.LicenseAssignmentManagerMO;
 import com.cloud.hypervisor.vmware.mo.VirtualEthernetCardType;
@@ -75,6 +77,11 @@ public class VmwareHelper {
     @SuppressWarnings("unused")
     private static final Logger s_logger = Logger.getLogger(VmwareHelper.class);
 
+    public static final int MAX_SCSI_CONTROLLER_COUNT = 4;
+    public static final int MAX_IDE_CONTROLLER_COUNT = 2;
+    public static final int MAX_ALLOWED_DEVICES_IDE_CONTROLLER = 2;
+    public static final int MAX_ALLOWED_DEVICES_SCSI_CONTROLLER = 15;
+
     public static boolean isReservedScsiDeviceNumber(int deviceNumber) {
         return deviceNumber == 7;
     }
@@ -706,6 +713,19 @@ public class VmwareHelper {
         return UUID.randomUUID().toString().replaceAll("-", "");
     }
 
+    public static String getRecommendedDiskControllerFromDescriptor(GuestOsDescriptor guestOsDescriptor)
throws Exception {
+        String recommendedController;
+
+        recommendedController = guestOsDescriptor.getRecommendedDiskController();
+
+        // By-pass auto detected PVSCSI controller to use LsiLogic Parallel instead
+        if (DiskControllerType.getType(recommendedController) == DiskControllerType.pvscsi)
{
+            recommendedController = DiskControllerType.lsilogic.toString();
+        }
+
+        return recommendedController;
+    }
+
     public static String trimSnapshotDeltaPostfix(String name) {
         String[] tokens = name.split("-");
         if (tokens.length > 1 && tokens[tokens.length - 1].matches("[0-9]{6,}"))
{
@@ -717,4 +737,8 @@ public class VmwareHelper {
         return name;
     }
 
+    public static boolean isControllerOsRecommended(String dataDiskController) {
+        return DiskControllerType.getType(dataDiskController) == DiskControllerType.osdefault;
+    }
+
 }


Mime
View raw message