Skip to content

Commit 47a2682

Browse files
[VMware] Sync the disk path or datastore changes for IDE disks, and before any volume resize during start vm (for the volumes on datastore cluster) (#10748)
1 parent 3959dbd commit 47a2682

File tree

1 file changed

+64
-47
lines changed
  • plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource

1 file changed

+64
-47
lines changed

plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java

Lines changed: 64 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -2350,13 +2350,16 @@ protected StartAnswer execute(StartCommand cmd) {
23502350
continue;
23512351
}
23522352

2353+
VirtualMachineDiskInfo matchingExistingDisk = getMatchingExistingDisk(diskInfoBuilder, vol, hyperHost, context);
2354+
Pair<ManagedObjectReference, DatastoreMO> volumeDsDetails = getVolumeDatastoreDetails(vol, dataStoresDetails);
2355+
syncVolumeDatastoreAndPathForDatastoreCluster(vol, diskInfoBuilder, matchingExistingDisk, volumeDsDetails, diskDatastores, hyperHost, context);
2356+
23532357
if (deployAsIs && vol.getType() == Volume.Type.ROOT) {
23542358
rootDiskTO = vol;
23552359
resizeRootDiskOnVMStart(vmMo, rootDiskTO, hyperHost, context);
23562360
continue;
23572361
}
23582362

2359-
VirtualMachineDiskInfo matchingExistingDisk = getMatchingExistingDisk(diskInfoBuilder, vol, hyperHost, context);
23602363
String diskController = getDiskController(vmMo, matchingExistingDisk, vol, chosenDiskControllers, deployAsIs);
23612364
if (DiskControllerType.getType(diskController) == DiskControllerType.ide) {
23622365
controllerKey = vmMo.getIDEControllerKey(ideUnitNumber);
@@ -2365,7 +2368,7 @@ protected StartAnswer execute(StartCommand cmd) {
23652368
// Ensure maximum of 2 data volumes over IDE controller, 3 includeing root volume
23662369
if (vmMo.getNumberOfVirtualDisks() > 3) {
23672370
throw new CloudRuntimeException("Found more than 3 virtual disks attached to this VM [" + vmMo.getVmName() + "]. Unable to implement the disks over "
2368-
+ diskController + " controller, as maximum number of devices supported over IDE controller is 4 includeing CDROM device.");
2371+
+ diskController + " controller, as maximum number of devices supported over IDE controller is 4 including CDROM device.");
23692372
}
23702373
}
23712374
} else {
@@ -2385,51 +2388,6 @@ protected StartAnswer execute(StartCommand cmd) {
23852388
if (!hasSnapshot) {
23862389
deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec();
23872390

2388-
VolumeObjectTO volumeTO = (VolumeObjectTO) vol.getData();
2389-
DataStoreTO primaryStore = volumeTO.getDataStore();
2390-
Map<String, String> details = vol.getDetails();
2391-
boolean managed = false;
2392-
String iScsiName = null;
2393-
2394-
if (details != null) {
2395-
managed = Boolean.parseBoolean(details.get(DiskTO.MANAGED));
2396-
iScsiName = details.get(DiskTO.IQN);
2397-
}
2398-
2399-
String primaryStoreUuid = primaryStore.getUuid();
2400-
// if the storage is managed, iScsiName should not be null
2401-
String datastoreName = managed ? VmwareResource.getDatastoreName(iScsiName) : primaryStoreUuid;
2402-
Pair<ManagedObjectReference, DatastoreMO> volumeDsDetails = dataStoresDetails.get(datastoreName);
2403-
2404-
assert (volumeDsDetails != null);
2405-
if (volumeDsDetails == null) {
2406-
throw new Exception("Primary datastore " + primaryStore.getUuid() + " is not mounted on host.");
2407-
}
2408-
2409-
if (vol.getDetails().get(DiskTO.PROTOCOL_TYPE) != null && vol.getDetails().get(DiskTO.PROTOCOL_TYPE).equalsIgnoreCase("DatastoreCluster")) {
2410-
if (diskInfoBuilder != null && matchingExistingDisk != null) {
2411-
String[] diskChain = matchingExistingDisk.getDiskChain();
2412-
if (diskChain != null && diskChain.length > 0) {
2413-
DatastoreFile file = new DatastoreFile(diskChain[0]);
2414-
if (!file.getFileBaseName().equalsIgnoreCase(volumeTO.getPath())) {
2415-
if (s_logger.isInfoEnabled())
2416-
s_logger.info("Detected disk-chain top file change on volume: " + volumeTO.getId() + " " + volumeTO.getPath() + " -> " + file.getFileBaseName());
2417-
volumeTO.setPath(file.getFileBaseName());
2418-
}
2419-
}
2420-
DatastoreMO diskDatastoreMofromVM = getDataStoreWhereDiskExists(hyperHost, context, diskInfoBuilder, vol, diskDatastores);
2421-
if (diskDatastoreMofromVM != null) {
2422-
String actualPoolUuid = diskDatastoreMofromVM.getCustomFieldValue(CustomFieldConstants.CLOUD_UUID);
2423-
if (actualPoolUuid != null && !actualPoolUuid.equalsIgnoreCase(primaryStore.getUuid())) {
2424-
volumeDsDetails = new Pair<>(diskDatastoreMofromVM.getMor(), diskDatastoreMofromVM);
2425-
if (s_logger.isInfoEnabled())
2426-
s_logger.info("Detected datastore uuid change on volume: " + volumeTO.getId() + " " + primaryStore.getUuid() + " -> " + actualPoolUuid);
2427-
((PrimaryDataStoreTO)primaryStore).setUuid(actualPoolUuid);
2428-
}
2429-
}
2430-
}
2431-
}
2432-
24332391
String[] diskChain = syncDiskChain(dcMo, vmMo, vol, matchingExistingDisk, volumeDsDetails.second());
24342392

24352393
int deviceNumber = -1;
@@ -2441,6 +2399,7 @@ protected StartAnswer execute(StartCommand cmd) {
24412399
scsiUnitNumber++;
24422400
}
24432401

2402+
VolumeObjectTO volumeTO = (VolumeObjectTO) vol.getData();
24442403
Long maxIops = volumeTO.getIopsWriteRate() + volumeTO.getIopsReadRate();
24452404
VirtualDevice device = VmwareHelper.prepareDiskDevice(vmMo, null, controllerKey, diskChain, volumeDsDetails.first(), deviceNumber, i + 1, maxIops);
24462405
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) {
27092668
}
27102669
}
27112670

2671+
private Pair<ManagedObjectReference, DatastoreMO> getVolumeDatastoreDetails(DiskTO vol, HashMap<String, Pair<ManagedObjectReference, DatastoreMO>> dataStoresDetails) throws Exception {
2672+
boolean managed = false;
2673+
String iScsiName = null;
2674+
Map<String, String> details = vol.getDetails();
2675+
if (MapUtils.isNotEmpty(details)) {
2676+
managed = Boolean.parseBoolean(details.get(DiskTO.MANAGED));
2677+
iScsiName = details.get(DiskTO.IQN);
2678+
}
2679+
2680+
VolumeObjectTO volumeTO = (VolumeObjectTO) vol.getData();
2681+
DataStoreTO primaryStore = volumeTO.getDataStore();
2682+
String primaryStoreUuid = primaryStore.getUuid();
2683+
// if the storage is managed, iScsiName should not be null
2684+
String datastoreName = managed ? VmwareResource.getDatastoreName(iScsiName) : primaryStoreUuid;
2685+
Pair<ManagedObjectReference, DatastoreMO> volumeDsDetails = dataStoresDetails.get(datastoreName);
2686+
if (volumeDsDetails == null) {
2687+
throw new Exception("Primary datastore " + primaryStore.getUuid() + " is not mounted on host.");
2688+
}
2689+
2690+
return volumeDsDetails;
2691+
}
2692+
2693+
private void syncVolumeDatastoreAndPathForDatastoreCluster(DiskTO vol, VirtualMachineDiskInfoBuilder diskInfoBuilder, VirtualMachineDiskInfo matchingExistingDisk,
2694+
Pair<ManagedObjectReference, DatastoreMO> volumeDsDetails, List<Pair<Integer, ManagedObjectReference>> diskDatastores,
2695+
VmwareHypervisorHost hyperHost, VmwareContext context) throws Exception {
2696+
if (vol.getDetails() == null || vol.getDetails().get(DiskTO.PROTOCOL_TYPE) == null || !vol.getDetails().get(DiskTO.PROTOCOL_TYPE).equalsIgnoreCase("DatastoreCluster")) {
2697+
return;
2698+
}
2699+
2700+
if (diskInfoBuilder != null && matchingExistingDisk != null) {
2701+
String[] diskChain = matchingExistingDisk.getDiskChain();
2702+
if (diskChain != null && diskChain.length > 0) {
2703+
DatastoreFile file = new DatastoreFile(diskChain[0]);
2704+
VolumeObjectTO volumeTO = (VolumeObjectTO) vol.getData();
2705+
if (!file.getFileBaseName().equalsIgnoreCase(volumeTO.getPath())) {
2706+
if (s_logger.isInfoEnabled()) {
2707+
s_logger.info("Detected disk-chain top file change on volume: " + volumeTO.getId() + " " + volumeTO.getPath() + " -> " + file.getFileBaseName());
2708+
}
2709+
volumeTO.setPath(file.getFileBaseName());
2710+
vol.setPath(file.getFileBaseName());
2711+
}
2712+
}
2713+
DatastoreMO diskDatastoreMofromVM = getDataStoreWhereDiskExists(hyperHost, context, diskInfoBuilder, vol, diskDatastores);
2714+
if (diskDatastoreMofromVM != null) {
2715+
String actualPoolUuid = diskDatastoreMofromVM.getCustomFieldValue(CustomFieldConstants.CLOUD_UUID);
2716+
VolumeObjectTO volumeTO = (VolumeObjectTO) vol.getData();
2717+
DataStoreTO primaryStore = volumeTO.getDataStore();
2718+
if (actualPoolUuid != null && !actualPoolUuid.equalsIgnoreCase(primaryStore.getUuid())) {
2719+
volumeDsDetails = new Pair<>(diskDatastoreMofromVM.getMor(), diskDatastoreMofromVM);
2720+
if (s_logger.isInfoEnabled()) {
2721+
s_logger.info("Detected datastore uuid change on volume: " + volumeTO.getId() + " " + primaryStore.getUuid() + " -> " + actualPoolUuid);
2722+
}
2723+
((PrimaryDataStoreTO)primaryStore).setUuid(actualPoolUuid);
2724+
}
2725+
}
2726+
}
2727+
}
2728+
27122729
private boolean powerOnVM(final VirtualMachineMO vmMo, final String vmInternalCSName, final String vmNameOnVcenter) throws Exception {
27132730
int retry = 20;
27142731
while (retry-- > 0) {

0 commit comments

Comments
 (0)