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 20495530909d..9e105749da98 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 @@ -2350,13 +2350,16 @@ protected StartAnswer execute(StartCommand cmd) { continue; } + VirtualMachineDiskInfo matchingExistingDisk = getMatchingExistingDisk(diskInfoBuilder, vol, hyperHost, context); + Pair volumeDsDetails = getVolumeDatastoreDetails(vol, dataStoresDetails); + syncVolumeDatastoreAndPathForDatastoreCluster(vol, diskInfoBuilder, matchingExistingDisk, volumeDsDetails, diskDatastores, hyperHost, context); + if (deployAsIs && vol.getType() == Volume.Type.ROOT) { rootDiskTO = vol; resizeRootDiskOnVMStart(vmMo, rootDiskTO, hyperHost, context); continue; } - VirtualMachineDiskInfo matchingExistingDisk = getMatchingExistingDisk(diskInfoBuilder, vol, hyperHost, context); String diskController = getDiskController(vmMo, matchingExistingDisk, vol, chosenDiskControllers, deployAsIs); if (DiskControllerType.getType(diskController) == DiskControllerType.ide) { controllerKey = vmMo.getIDEControllerKey(ideUnitNumber); @@ -2365,7 +2368,7 @@ protected StartAnswer execute(StartCommand cmd) { // Ensure maximum of 2 data volumes over IDE controller, 3 includeing root volume if (vmMo.getNumberOfVirtualDisks() > 3) { throw new CloudRuntimeException("Found more than 3 virtual disks attached to this VM [" + vmMo.getVmName() + "]. Unable to implement the disks over " - + diskController + " controller, as maximum number of devices supported over IDE controller is 4 includeing CDROM device."); + + diskController + " controller, as maximum number of devices supported over IDE controller is 4 including CDROM device."); } } } else { @@ -2385,51 +2388,6 @@ protected StartAnswer execute(StartCommand cmd) { if (!hasSnapshot) { deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec(); - VolumeObjectTO volumeTO = (VolumeObjectTO) vol.getData(); - DataStoreTO primaryStore = volumeTO.getDataStore(); - Map details = vol.getDetails(); - boolean managed = false; - String iScsiName = null; - - if (details != null) { - managed = Boolean.parseBoolean(details.get(DiskTO.MANAGED)); - iScsiName = details.get(DiskTO.IQN); - } - - String primaryStoreUuid = primaryStore.getUuid(); - // if the storage is managed, iScsiName should not be null - String datastoreName = managed ? VmwareResource.getDatastoreName(iScsiName) : primaryStoreUuid; - Pair volumeDsDetails = dataStoresDetails.get(datastoreName); - - assert (volumeDsDetails != null); - if (volumeDsDetails == null) { - throw new Exception("Primary datastore " + primaryStore.getUuid() + " is not mounted on host."); - } - - if (vol.getDetails().get(DiskTO.PROTOCOL_TYPE) != null && vol.getDetails().get(DiskTO.PROTOCOL_TYPE).equalsIgnoreCase("DatastoreCluster")) { - if (diskInfoBuilder != null && matchingExistingDisk != null) { - String[] diskChain = matchingExistingDisk.getDiskChain(); - if (diskChain != null && diskChain.length > 0) { - DatastoreFile file = new DatastoreFile(diskChain[0]); - if (!file.getFileBaseName().equalsIgnoreCase(volumeTO.getPath())) { - if (s_logger.isInfoEnabled()) - s_logger.info("Detected disk-chain top file change on volume: " + volumeTO.getId() + " " + volumeTO.getPath() + " -> " + file.getFileBaseName()); - volumeTO.setPath(file.getFileBaseName()); - } - } - DatastoreMO diskDatastoreMofromVM = getDataStoreWhereDiskExists(hyperHost, context, diskInfoBuilder, vol, diskDatastores); - if (diskDatastoreMofromVM != null) { - String actualPoolUuid = diskDatastoreMofromVM.getCustomFieldValue(CustomFieldConstants.CLOUD_UUID); - if (actualPoolUuid != null && !actualPoolUuid.equalsIgnoreCase(primaryStore.getUuid())) { - volumeDsDetails = new Pair<>(diskDatastoreMofromVM.getMor(), diskDatastoreMofromVM); - if (s_logger.isInfoEnabled()) - s_logger.info("Detected datastore uuid change on volume: " + volumeTO.getId() + " " + primaryStore.getUuid() + " -> " + actualPoolUuid); - ((PrimaryDataStoreTO)primaryStore).setUuid(actualPoolUuid); - } - } - } - } - String[] diskChain = syncDiskChain(dcMo, vmMo, vol, matchingExistingDisk, volumeDsDetails.second()); int deviceNumber = -1; @@ -2441,6 +2399,7 @@ protected StartAnswer execute(StartCommand cmd) { scsiUnitNumber++; } + VolumeObjectTO volumeTO = (VolumeObjectTO) vol.getData(); Long maxIops = volumeTO.getIopsWriteRate() + volumeTO.getIopsReadRate(); VirtualDevice device = VmwareHelper.prepareDiskDevice(vmMo, null, controllerKey, diskChain, volumeDsDetails.first(), deviceNumber, i + 1, maxIops); s_logger.debug(LogUtils.logGsonWithoutException("The following definitions will be used to start the VM: virtual device [%s], volume [%s].", device, volumeTO)); @@ -2709,6 +2668,64 @@ protected StartAnswer execute(StartCommand cmd) { } } + private Pair getVolumeDatastoreDetails(DiskTO vol, HashMap> dataStoresDetails) throws Exception { + boolean managed = false; + String iScsiName = null; + Map details = vol.getDetails(); + if (MapUtils.isNotEmpty(details)) { + managed = Boolean.parseBoolean(details.get(DiskTO.MANAGED)); + iScsiName = details.get(DiskTO.IQN); + } + + VolumeObjectTO volumeTO = (VolumeObjectTO) vol.getData(); + DataStoreTO primaryStore = volumeTO.getDataStore(); + String primaryStoreUuid = primaryStore.getUuid(); + // if the storage is managed, iScsiName should not be null + String datastoreName = managed ? VmwareResource.getDatastoreName(iScsiName) : primaryStoreUuid; + Pair volumeDsDetails = dataStoresDetails.get(datastoreName); + if (volumeDsDetails == null) { + throw new Exception("Primary datastore " + primaryStore.getUuid() + " is not mounted on host."); + } + + return volumeDsDetails; + } + + private void syncVolumeDatastoreAndPathForDatastoreCluster(DiskTO vol, VirtualMachineDiskInfoBuilder diskInfoBuilder, VirtualMachineDiskInfo matchingExistingDisk, + Pair volumeDsDetails, List> diskDatastores, + VmwareHypervisorHost hyperHost, VmwareContext context) throws Exception { + if (vol.getDetails() == null || vol.getDetails().get(DiskTO.PROTOCOL_TYPE) == null || !vol.getDetails().get(DiskTO.PROTOCOL_TYPE).equalsIgnoreCase("DatastoreCluster")) { + return; + } + + if (diskInfoBuilder != null && matchingExistingDisk != null) { + String[] diskChain = matchingExistingDisk.getDiskChain(); + if (diskChain != null && diskChain.length > 0) { + DatastoreFile file = new DatastoreFile(diskChain[0]); + VolumeObjectTO volumeTO = (VolumeObjectTO) vol.getData(); + if (!file.getFileBaseName().equalsIgnoreCase(volumeTO.getPath())) { + if (s_logger.isInfoEnabled()) { + s_logger.info("Detected disk-chain top file change on volume: " + volumeTO.getId() + " " + volumeTO.getPath() + " -> " + file.getFileBaseName()); + } + volumeTO.setPath(file.getFileBaseName()); + vol.setPath(file.getFileBaseName()); + } + } + DatastoreMO diskDatastoreMofromVM = getDataStoreWhereDiskExists(hyperHost, context, diskInfoBuilder, vol, diskDatastores); + if (diskDatastoreMofromVM != null) { + String actualPoolUuid = diskDatastoreMofromVM.getCustomFieldValue(CustomFieldConstants.CLOUD_UUID); + VolumeObjectTO volumeTO = (VolumeObjectTO) vol.getData(); + DataStoreTO primaryStore = volumeTO.getDataStore(); + if (actualPoolUuid != null && !actualPoolUuid.equalsIgnoreCase(primaryStore.getUuid())) { + volumeDsDetails = new Pair<>(diskDatastoreMofromVM.getMor(), diskDatastoreMofromVM); + if (s_logger.isInfoEnabled()) { + s_logger.info("Detected datastore uuid change on volume: " + volumeTO.getId() + " " + primaryStore.getUuid() + " -> " + actualPoolUuid); + } + ((PrimaryDataStoreTO)primaryStore).setUuid(actualPoolUuid); + } + } + } + } + private boolean powerOnVM(final VirtualMachineMO vmMo, final String vmInternalCSName, final String vmNameOnVcenter) throws Exception { int retry = 20; while (retry-- > 0) {