Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1945,7 +1945,7 @@ protected StartAnswer execute(StartCommand cmd) {
int ideUnitNumber = 0;
int scsiUnitNumber = 0;
int ideControllerKey = vmMo.getIDEDeviceControllerKey();
int scsiControllerKey = vmMo.getGenericScsiDeviceControllerKeyNoException();
int scsiControllerKey = vmMo.getScsiDeviceControllerKeyNoException();
int controllerKey;

//
Expand Down Expand Up @@ -2068,13 +2068,17 @@ protected StartAnswer execute(StartCommand cmd) {
}
}
} 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) {
Expand All @@ -2098,10 +2102,17 @@ protected StartAnswer execute(StartCommand cmd) {
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;
Expand All @@ -2113,8 +2124,6 @@ protected StartAnswer execute(StartCommand cmd) {

i++;
} else {
if (controllerKey == scsiControllerKey && VmwareHelper.isReservedScsiDeviceNumber(scsiUnitNumber))
scsiUnitNumber++;
if (controllerKey == vmMo.getIDEControllerKey(ideUnitNumber))
ideUnitNumber++;
else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2224,22 +2224,22 @@ public boolean isPvScsiSupported() throws Exception {

// 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();
}
}
Expand All @@ -2249,24 +2249,46 @@ public int getScsiDiskControllerKey(String diskController) throws Exception {
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++;
}
}
}
Expand All @@ -2285,7 +2307,7 @@ public int getScsiDeviceControllerKey() throws Exception {

if (devices != null && devices.size() > 0) {
for (VirtualDevice device : devices) {
if (device instanceof VirtualSCSIController) {
if (device instanceof VirtualSCSIController && isValidScsiDiskController((VirtualSCSIController)device)) {
return device.getKey();
}
}
Expand All @@ -2295,27 +2317,12 @@ public int getScsiDeviceControllerKey() throws Exception {
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();
}
}
Expand Down Expand Up @@ -2412,6 +2419,23 @@ public void ensureScsiDeviceControllers(int count, int availableBusNum) throws E
}
}

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 = "";
Expand Down Expand Up @@ -2985,7 +3009,7 @@ public int getNextDeviceNumber(int controllerKey) throws Exception {

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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down