From 5d7ea30f87d0c333a647cef832412f30187a29cb Mon Sep 17 00:00:00 2001 From: SadiJr Date: Sat, 8 Jan 2022 00:32:00 -0300 Subject: [PATCH] vmware: Remove restriction, in VMWare, to resize only SCSI disks (#5650) Remove restriction, in VMWare, to resize only SCSI disks, because VMWare supports resize of subtypes of SCSI, like LSILOGIC, LSILOGIC SAS, etc In VMWare, there are different types of SCSI controllers, such as BusLogic Parallel, LSI Logic Parallel, LSI Logic SAS, etc. All of these sub-types support the disk resize operation, the only exception is the IDE controller. However, in ACS, there is a logical restriction to allow only resizing of volumes of the specific SCSI type; thus, not allowing resizing of the SCSI sub-types. This PR corrects this behavior blocking the resize of volumes which uses IDE controller only. More information can be found at: https://www.starwindsoftware.com/blog/storage-controllers-in-vmware-vsphere https://www.nakivo.com/blog/scsi-controller-and-other-vmware-controller-types/ https://docs.vmware.com/en/VMware-vSphere/7.0/com.vmware.vsphere.vm_admin.doc/GUID-5872D173-A076-42FE-8D0B-9DB0EB0E7362.html https://communities.vmware.com/t5/ESXi-Discussions/Unable-to-increase-disk-Space/td-p/397823 Co-authored-by: SadiJr --- .../vmware/resource/VmwareResource.java | 51 +++++++++---------- .../java/com/cloud/vm/UserVmManagerImpl.java | 4 +- 2 files changed, 26 insertions(+), 29 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 cce875ea6bc..297e5344a1d 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 @@ -784,8 +784,10 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa try { if (newSize < oldSize) { - throw new Exception( - "VMware doesn't support shrinking volume from larger size: " + oldSize / ResourceType.bytesToMiB + " GB to a smaller size: " + newSize / ResourceType.bytesToMiB + " GB"); + String errorMsg = String.format("VMware doesn't support shrinking volume from larger size [%s] GB to a smaller size [%s] GB. Can't resize volume of VM [name: %s].", + oldSize / Float.valueOf(ResourceType.bytesToMiB), newSize / Float.valueOf(ResourceType.bytesToMiB), vmName); + s_logger.error(errorMsg); + throw new Exception(errorMsg); } else if (newSize == oldSize) { return new ResizeVolumeAnswer(cmd, true, "success", newSize * ResourceType.bytesToKiB); } @@ -827,11 +829,9 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa vmMo = hyperHost.findVmOnPeerHyperHost(vmName); if (vmMo == null) { - String msg = "VM " + vmName + " does not exist in VMware datacenter"; - - s_logger.error(msg); - - throw new Exception(msg); + String errorMsg = String.format("VM [name: %s] does not exist in VMware datacenter.", vmName); + s_logger.error(errorMsg); + throw new Exception(errorMsg); } @@ -894,7 +894,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa vmConfigSpec.getDeviceChange().add(deviceConfigSpec); if (!vmMo.configureVm(vmConfigSpec)) { - throw new Exception("Failed to configure VM to resize disk. vmName: " + vmName); + throw new Exception(String.format("Failed to configure VM [name: %s] to resize disk.", vmName)); } ResizeVolumeAnswer answer = new ResizeVolumeAnswer(cmd, true, "success", newSize * 1024); @@ -909,11 +909,9 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } return answer; } catch (Exception e) { - s_logger.error("Unable to resize volume", e); - - String error = "Failed to resize volume: " + e.getMessage(); - - return new ResizeVolumeAnswer(cmd, false, error); + String errorMsg = String.format("Failed to resize volume of VM [name: %s] due to: [%s].", vmName, e.getMessage()); + s_logger.error(errorMsg, e); + return new ResizeVolumeAnswer(cmd, false, errorMsg); } finally { // OfflineVmwareMigration: 6. check if a worker was used and destroy it if needed try { @@ -924,7 +922,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa vmMo.destroy(); } } catch (Throwable e) { - s_logger.info("Failed to destroy worker VM: " + vmName); + s_logger.error(String.format("Failed to destroy worker VM [name: %s] due to: [%s].", vmName, e.getMessage()), e); } } } @@ -932,26 +930,25 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa private VirtualDisk getDiskAfterResizeDiskValidations(VirtualMachineMO vmMo, String volumePath) throws Exception { Pair vdisk = vmMo.getDiskDevice(volumePath); if (vdisk == null) { - if (s_logger.isTraceEnabled()) { - s_logger.trace("resize volume done (failed)"); - } - throw new Exception("No such disk device: " + volumePath); + String errorMsg = String.format("Resize volume of VM [name: %s] failed because disk device [path: %s] doesn't exist.", vmMo.getVmName(), volumePath); + s_logger.error(errorMsg); + throw new Exception(errorMsg); } // IDE virtual disk cannot be re-sized if VM is running - if (vdisk.second() != null && vdisk.second().contains("ide")) { - throw new Exception("Re-sizing a virtual disk over an IDE controller is not supported in the VMware hypervisor. " + - "Please re-try when virtual disk is attached to a VM using a SCSI controller."); + if (vdisk.second() != null && vdisk.second().toLowerCase().contains("ide")) { + String errorMsg = String.format("Re-sizing a virtual disk over an IDE controller is not supported in the VMware hypervisor. " + + "Please re-try when virtual disk is attached to VM [name: %s] using a SCSI controller.", vmMo.getVmName()); + s_logger.error(errorMsg); + throw new Exception(errorMsg); } - if (vdisk.second() != null && !vdisk.second().toLowerCase().startsWith("scsi")) { - s_logger.error("Unsupported disk device bus " + vdisk.second()); - throw new Exception("Unsupported disk device bus " + vdisk.second()); - } VirtualDisk disk = vdisk.first(); if ((VirtualDiskFlatVer2BackingInfo) disk.getBacking() != null && ((VirtualDiskFlatVer2BackingInfo) disk.getBacking()).getParent() != null) { - s_logger.error("Resize is not supported because Disk device has Parent " + ((VirtualDiskFlatVer2BackingInfo) disk.getBacking()).getParent().getUuid()); - throw new Exception("Resize is not supported because Disk device has Parent " + ((VirtualDiskFlatVer2BackingInfo) disk.getBacking()).getParent().getUuid()); + String errorMsg = String.format("Resize of volume in VM [name: %s] is not supported because Disk device [path: %s] has Parents: [%s].", + vmMo.getVmName(), volumePath, ((VirtualDiskFlatVer2BackingInfo) disk.getBacking()).getParent().getUuid()); + s_logger.error(errorMsg); + throw new Exception(errorMsg); } return disk; } diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index 3eb01ea1bed..3df23af89c4 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -4453,8 +4453,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } else if ((rootDiskSize << 30) > templateVO.getSize()) { if (hypervisorType == HypervisorType.VMware && (vm.getDetails() == null || vm.getDetails().get(VmDetailConstants.ROOT_DISK_CONTROLLER) == null)) { s_logger.warn("If Root disk controller parameter is not overridden, then Root disk resize may fail because current Root disk controller value is NULL."); - } else if (hypervisorType == HypervisorType.VMware && !vm.getDetails().get(VmDetailConstants.ROOT_DISK_CONTROLLER).toLowerCase().contains("scsi")) { - String error = "Found unsupported root disk controller: " + vm.getDetails().get(VmDetailConstants.ROOT_DISK_CONTROLLER); + } else if (hypervisorType == HypervisorType.VMware && vm.getDetails().get(VmDetailConstants.ROOT_DISK_CONTROLLER).toLowerCase().contains("ide")) { + String error = String.format("Found unsupported root disk controller [%s].", vm.getDetails().get(VmDetailConstants.ROOT_DISK_CONTROLLER)); s_logger.error(error); throw new InvalidParameterValueException(error); } else {