This is an automated email from the ASF dual-hosted git repository.

rohit pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cloudstack.git


The following commit(s) were added to refs/heads/master by this push:
     new f0a67cc  vmware: Support to attach more than 15 data disks in VMware 
VM (#4172)
f0a67cc is described below

commit f0a67cca7a38ca6a6cd38f1d2c54d15137d206e2
Author: sureshanaparti <[email protected]>
AuthorDate: Wed Jul 15 15:51:55 2020 +0530

    vmware: Support to attach more than 15 data disks in VMware VM (#4172)
    
    Support to attach more than 15 data disks in VMware VM
    
    Fixes #4102
---
 .../hypervisor/vmware/resource/VmwareResource.java |  25 +++--
 .../hypervisor/vmware/mo/VirtualMachineMO.java     | 116 +++++++++++++--------
 .../cloud/hypervisor/vmware/util/VmwareHelper.java |   7 +-
 3 files changed, 92 insertions(+), 56 deletions(-)

diff --git 
a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java
 
b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java
index aebda55..9051981 100644
--- 
a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java
+++ 
b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java
@@ -1949,7 +1949,7 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
             int ideUnitNumber = 0;
             int scsiUnitNumber = 0;
             int ideControllerKey = vmMo.getIDEDeviceControllerKey();
-            int scsiControllerKey = 
vmMo.getGenericScsiDeviceControllerKeyNoException();
+            int scsiControllerKey = 
vmMo.getScsiDeviceControllerKeyNoException();
             int controllerKey;
 
             //
@@ -2072,13 +2072,17 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
                         }
                     }
                 } else {
-                    controllerKey = 
vmMo.getScsiDiskControllerKeyNoException(diskController);
+                    if 
(VmwareHelper.isReservedScsiDeviceNumber(scsiUnitNumber)) {
+                        scsiUnitNumber++;
+                    }
+
+                    controllerKey = 
vmMo.getScsiDiskControllerKeyNoException(diskController, scsiUnitNumber);
                     if (controllerKey == -1) {
                         // This may happen for ROOT legacy VMs which doesn't 
have recommended disk controller when global configuration parameter 
'vmware.root.disk.controller' is set to "osdefault"
                         // Retrieve existing controller and use.
                         Ternary<Integer, Integer, DiskControllerType> 
vmScsiControllerInfo = vmMo.getScsiControllerInfo();
                         DiskControllerType existingControllerType = 
vmScsiControllerInfo.third();
-                        controllerKey = 
vmMo.getScsiDiskControllerKeyNoException(existingControllerType.toString());
+                        controllerKey = 
vmMo.getScsiDiskControllerKeyNoException(existingControllerType.toString(), 
scsiUnitNumber);
                     }
                 }
                 if (!hasSnapshot) {
@@ -2102,10 +2106,17 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
                     assert (volumeDsDetails != null);
 
                     String[] diskChain = syncDiskChain(dcMo, vmMo, vmSpec, 
vol, matchingExistingDisk, dataStoresDetails);
-                    if (controllerKey == scsiControllerKey && 
VmwareHelper.isReservedScsiDeviceNumber(scsiUnitNumber))
+
+                    int deviceNumber = -1;
+                    if (controllerKey == 
vmMo.getIDEControllerKey(ideUnitNumber)) {
+                        deviceNumber = ideUnitNumber % 
VmwareHelper.MAX_ALLOWED_DEVICES_IDE_CONTROLLER;
+                        ideUnitNumber++;
+                    } else {
+                        deviceNumber = scsiUnitNumber % 
VmwareHelper.MAX_ALLOWED_DEVICES_SCSI_CONTROLLER;
                         scsiUnitNumber++;
-                    VirtualDevice device = 
VmwareHelper.prepareDiskDevice(vmMo, null, controllerKey, diskChain, 
volumeDsDetails.first(),
-                            (controllerKey == 
vmMo.getIDEControllerKey(ideUnitNumber)) ? ((ideUnitNumber++) % 
VmwareHelper.MAX_IDE_CONTROLLER_COUNT) : scsiUnitNumber++, i + 1);
+                    }
+
+                    VirtualDevice device = 
VmwareHelper.prepareDiskDevice(vmMo, null, controllerKey, diskChain, 
volumeDsDetails.first(), deviceNumber, i + 1);
 
                     if (vol.getType() == Volume.Type.ROOT)
                         rootDiskTO = vol;
@@ -2117,8 +2128,6 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
 
                     i++;
                 } else {
-                    if (controllerKey == scsiControllerKey && 
VmwareHelper.isReservedScsiDeviceNumber(scsiUnitNumber))
-                        scsiUnitNumber++;
                     if (controllerKey == 
vmMo.getIDEControllerKey(ideUnitNumber))
                         ideUnitNumber++;
                     else
diff --git 
a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java
 
b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java
index d5df4b9..3945056 100644
--- 
a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java
+++ 
b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java
@@ -2224,22 +2224,22 @@ public class VirtualMachineMO extends BaseMO {
 
     // 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");
+        List<VirtualDevice> devices = 
(List<VirtualDevice>)_context.getVimClient().getDynamicProperty(_mor, 
"config.hardware.device");
 
-        if (devices != null && devices.size() > 0) {
+        if (CollectionUtils.isNotEmpty(devices)) {
+            DiskControllerType diskControllerType = 
DiskControllerType.getType(diskController);
             for (VirtualDevice device : devices) {
-                if ((DiskControllerType.getType(diskController) == 
DiskControllerType.lsilogic || DiskControllerType.getType(diskController) == 
DiskControllerType.scsi)
-                        && device instanceof VirtualLsiLogicController) {
+                if ((diskControllerType == DiskControllerType.lsilogic || 
diskControllerType == DiskControllerType.scsi)
+                        && device instanceof VirtualLsiLogicController && 
isValidScsiDiskController((VirtualLsiLogicController)device)) {
                     return ((VirtualLsiLogicController)device).getKey();
-                } else if ((DiskControllerType.getType(diskController) == 
DiskControllerType.lsisas1068 || DiskControllerType.getType(diskController) == 
DiskControllerType.scsi)
-                        && device instanceof VirtualLsiLogicSASController) {
+                } else if ((diskControllerType == 
DiskControllerType.lsisas1068 || diskControllerType == DiskControllerType.scsi)
+                        && device instanceof VirtualLsiLogicSASController && 
isValidScsiDiskController((VirtualLsiLogicSASController)device)) {
                     return ((VirtualLsiLogicSASController)device).getKey();
-                } else if ((DiskControllerType.getType(diskController) == 
DiskControllerType.pvscsi || DiskControllerType.getType(diskController) == 
DiskControllerType.scsi)
-                        && device instanceof ParaVirtualSCSIController) {
+                } else if ((diskControllerType == DiskControllerType.pvscsi || 
diskControllerType == DiskControllerType.scsi)
+                        && device instanceof ParaVirtualSCSIController && 
isValidScsiDiskController((ParaVirtualSCSIController)device)) {
                     return ((ParaVirtualSCSIController)device).getKey();
-                } else if ((DiskControllerType.getType(diskController) == 
DiskControllerType.buslogic || DiskControllerType.getType(diskController) == 
DiskControllerType.scsi)
-                        && device instanceof VirtualBusLogicController) {
+                } else if ((diskControllerType == DiskControllerType.buslogic 
|| diskControllerType == DiskControllerType.scsi)
+                        && device instanceof VirtualBusLogicController && 
isValidScsiDiskController((VirtualBusLogicController)device)) {
                     return ((VirtualBusLogicController)device).getKey();
                 }
             }
@@ -2249,24 +2249,46 @@ public class VirtualMachineMO extends BaseMO {
         throw new IllegalStateException("Scsi disk controller of type " + 
diskController + " not found among configured devices.");
     }
 
-    public int getScsiDiskControllerKeyNoException(String diskController) 
throws Exception {
-        List<VirtualDevice> devices = 
(List<VirtualDevice>)_context.getVimClient().
-                getDynamicProperty(_mor, "config.hardware.device");
+    public int getScsiDiskControllerKeyNoException(String diskController, int 
scsiUnitNumber) throws Exception {
+        List<VirtualDevice> devices = 
(List<VirtualDevice>)_context.getVimClient().getDynamicProperty(_mor, 
"config.hardware.device");
 
-        if (devices != null && devices.size() > 0) {
+        if (CollectionUtils.isNotEmpty(devices) && scsiUnitNumber >= 0) {
+            int requiredScsiController = scsiUnitNumber / 
VmwareHelper.MAX_ALLOWED_DEVICES_SCSI_CONTROLLER;
+            int scsiControllerDeviceCount = 0;
+            DiskControllerType diskControllerType = 
DiskControllerType.getType(diskController);
             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();
+                if ((diskControllerType == DiskControllerType.lsilogic || 
diskControllerType == DiskControllerType.scsi) && device instanceof 
VirtualLsiLogicController) {
+                    if (scsiControllerDeviceCount == requiredScsiController) {
+                        if 
(isValidScsiDiskController((VirtualLsiLogicController)device)) {
+                            return 
((VirtualLsiLogicController)device).getKey();
+                        }
+                        break;
+                    }
+                    scsiControllerDeviceCount++;
+                } else if ((diskControllerType == 
DiskControllerType.lsisas1068 || diskControllerType == DiskControllerType.scsi) 
&& device instanceof VirtualLsiLogicSASController) {
+                    if (scsiControllerDeviceCount == requiredScsiController) {
+                        if 
(isValidScsiDiskController((VirtualLsiLogicSASController)device)) {
+                            return 
((VirtualLsiLogicSASController)device).getKey();
+                        }
+                        break;
+                    }
+                    scsiControllerDeviceCount++;
+                } else if ((diskControllerType == DiskControllerType.pvscsi || 
diskControllerType == DiskControllerType.scsi) && device instanceof 
ParaVirtualSCSIController) {
+                    if (scsiControllerDeviceCount == requiredScsiController) {
+                        if 
(isValidScsiDiskController((ParaVirtualSCSIController)device)) {
+                            return 
((ParaVirtualSCSIController)device).getKey();
+                        }
+                        break;
+                    }
+                    scsiControllerDeviceCount++;
+                } else if ((diskControllerType == DiskControllerType.buslogic 
|| diskControllerType == DiskControllerType.scsi) && device instanceof 
VirtualBusLogicController) {
+                    if (scsiControllerDeviceCount == requiredScsiController) {
+                        if 
(isValidScsiDiskController((VirtualBusLogicController)device)) {
+                            return 
((VirtualBusLogicController)device).getKey();
+                        }
+                        break;
+                    }
+                    scsiControllerDeviceCount++;
                 }
             }
         }
@@ -2285,7 +2307,7 @@ public class VirtualMachineMO extends BaseMO {
 
         if (devices != null && devices.size() > 0) {
             for (VirtualDevice device : devices) {
-                if (device instanceof VirtualSCSIController) {
+                if (device instanceof VirtualSCSIController && 
isValidScsiDiskController((VirtualSCSIController)device)) {
                     return device.getKey();
                 }
             }
@@ -2295,27 +2317,12 @@ public class VirtualMachineMO extends BaseMO {
         throw new Exception("SCSI Controller Not Found");
     }
 
-    public int getGenericScsiDeviceControllerKeyNoException() throws Exception 
{
+    public int getScsiDeviceControllerKeyNoException() 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 VirtualSCSIController) {
-                    return device.getKey();
-                }
-            }
-        }
-
-        return -1;
-    }
-
-    public int getScsiDeviceControllerKeyNoException() 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 VirtualSCSIController) {
+                if (device instanceof VirtualSCSIController && 
isValidScsiDiskController((VirtualSCSIController)device)) {
                     return device.getKey();
                 }
             }
@@ -2412,6 +2419,23 @@ public class VirtualMachineMO extends BaseMO {
         }
     }
 
+    private boolean isValidScsiDiskController(VirtualSCSIController 
scsiDiskController) {
+        if (scsiDiskController == null) {
+            return false;
+        }
+
+        List<Integer> scsiDiskDevicesOnController = 
scsiDiskController.getDevice();
+        if (scsiDiskDevicesOnController == null || 
scsiDiskDevicesOnController.size() >= 
(VmwareHelper.MAX_SUPPORTED_DEVICES_SCSI_CONTROLLER)) {
+            return false;
+        }
+
+        if (scsiDiskController.getBusNumber() >= 
VmwareHelper.MAX_SCSI_CONTROLLER_COUNT) {
+            return false;
+        }
+
+        return true;
+    }
+
     // return pair of VirtualDisk and disk device bus name(ide0:0, etc)
     public Pair<VirtualDisk, String> getDiskDevice(String vmdkDatastorePath) 
throws Exception {
         final String zeroLengthString = "";
@@ -2985,7 +3009,7 @@ public class VirtualMachineMO extends BaseMO {
 
         List<Integer> existingUnitNumbers = new ArrayList<Integer>();
         int deviceNumber = 0;
-        int scsiControllerKey = getGenericScsiDeviceControllerKeyNoException();
+        int scsiControllerKey = getScsiDeviceControllerKeyNoException();
         if (devices != null && devices.size() > 0) {
             for (VirtualDevice device : devices) {
                 if (device.getControllerKey() != null && 
device.getControllerKey().intValue() == controllerKey) {
diff --git 
a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareHelper.java 
b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareHelper.java
index 3d209fb..181b2ef 100644
--- 
a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareHelper.java
+++ 
b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareHelper.java
@@ -91,11 +91,14 @@ public class VmwareHelper {
     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 final int MAX_ALLOWED_DEVICES_SCSI_CONTROLLER = 16;
+    public static final int MAX_SUPPORTED_DEVICES_SCSI_CONTROLLER = 
MAX_ALLOWED_DEVICES_SCSI_CONTROLLER - 1; // One device node is unavailable for 
hard disks or SCSI devices
+    public static final int MAX_USABLE_SCSI_CONTROLLERS = 2;
     public static final String MIN_VERSION_UEFI_LEGACY = "5.5";
 
     public static boolean isReservedScsiDeviceNumber(int deviceNumber) {
-        return deviceNumber == 7;
+        // The SCSI controller is assigned to virtual device node (z:7), so 
that device node is unavailable for hard disks or SCSI devices.
+        return (deviceNumber % 
VmwareHelper.MAX_ALLOWED_DEVICES_SCSI_CONTROLLER) == 7;
     }
 
     @Nonnull

Reply via email to