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