mirror of
				https://github.com/apache/cloudstack.git
				synced 2025-10-26 08:42:29 +01:00 
			
		
		
		
	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
This commit is contained in:
		
							parent
							
								
									dfc76e0278
								
							
						
					
					
						commit
						f0a67cca7a
					
				| @ -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 | ||||
|  | ||||
| @ -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,25 +2249,47 @@ 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) { | ||||
|                 if ((diskControllerType == DiskControllerType.lsilogic || diskControllerType == DiskControllerType.scsi) && device instanceof VirtualLsiLogicController) { | ||||
|                     if (scsiControllerDeviceCount == requiredScsiController) { | ||||
|                         if (isValidScsiDiskController((VirtualLsiLogicController)device)) { | ||||
|                             return ((VirtualLsiLogicController)device).getKey(); | ||||
|                 } else if ((DiskControllerType.getType(diskController) == DiskControllerType.lsisas1068 || DiskControllerType.getType(diskController) == DiskControllerType.scsi) | ||||
|                         && device instanceof VirtualLsiLogicSASController) { | ||||
|                         } | ||||
|                         break; | ||||
|                     } | ||||
|                     scsiControllerDeviceCount++; | ||||
|                 } else if ((diskControllerType == DiskControllerType.lsisas1068 || diskControllerType == DiskControllerType.scsi) && device instanceof VirtualLsiLogicSASController) { | ||||
|                     if (scsiControllerDeviceCount == requiredScsiController) { | ||||
|                         if (isValidScsiDiskController((VirtualLsiLogicSASController)device)) { | ||||
|                             return ((VirtualLsiLogicSASController)device).getKey(); | ||||
|                 } else if ((DiskControllerType.getType(diskController) == DiskControllerType.pvscsi || DiskControllerType.getType(diskController) == DiskControllerType.scsi) | ||||
|                         && device instanceof ParaVirtualSCSIController) { | ||||
|                         } | ||||
|                         break; | ||||
|                     } | ||||
|                     scsiControllerDeviceCount++; | ||||
|                 } else if ((diskControllerType == DiskControllerType.pvscsi || diskControllerType == DiskControllerType.scsi) && device instanceof ParaVirtualSCSIController) { | ||||
|                     if (scsiControllerDeviceCount == requiredScsiController) { | ||||
|                         if (isValidScsiDiskController((ParaVirtualSCSIController)device)) { | ||||
|                             return ((ParaVirtualSCSIController)device).getKey(); | ||||
|                 } else if ((DiskControllerType.getType(diskController) == DiskControllerType.buslogic || DiskControllerType.getType(diskController) == DiskControllerType.scsi) | ||||
|                         && device instanceof VirtualBusLogicController) { | ||||
|                         } | ||||
|                         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++; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         return -1; | ||||
| @ -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) { | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user