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:
sureshanaparti 2020-07-15 15:51:55 +05:30 committed by GitHub
parent dfc76e0278
commit f0a67cca7a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 92 additions and 56 deletions

View File

@ -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

View File

@ -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) {

View File

@ -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