This is an automated email from the ASF dual-hosted git repository.
dahn pushed a commit to branch 4.19
in repository https://gitbox.apache.org/repos/asf/cloudstack.git
The following commit(s) were added to refs/heads/4.19 by this push:
new 47a268202bc [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)
47a268202bc is described below
commit 47a268202bca0c10ef5de729df99815bd3e64bd1
Author: Suresh Kumar Anaparti <[email protected]>
AuthorDate: Mon May 12 16:51:04 2025 +0530
[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)
---
.../hypervisor/vmware/resource/VmwareResource.java | 111 ++++++++++++---------
1 file changed, 64 insertions(+), 47 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 20495530909..9e105749da9 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 @@ public class VmwareResource extends ServerResourceBase
implements StoragePoolRes
continue;
}
+ VirtualMachineDiskInfo matchingExistingDisk =
getMatchingExistingDisk(diskInfoBuilder, vol, hyperHost, context);
+ Pair<ManagedObjectReference, DatastoreMO> 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 @@ public class VmwareResource extends ServerResourceBase
implements StoragePoolRes
// 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 @@ public class VmwareResource extends ServerResourceBase
implements StoragePoolRes
if (!hasSnapshot) {
deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec();
- VolumeObjectTO volumeTO = (VolumeObjectTO) vol.getData();
- DataStoreTO primaryStore = volumeTO.getDataStore();
- Map<String, String> 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<ManagedObjectReference, DatastoreMO> 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 @@ public class VmwareResource extends ServerResourceBase
implements StoragePoolRes
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 @@ public class VmwareResource extends ServerResourceBase
implements StoragePoolRes
}
}
+ private Pair<ManagedObjectReference, DatastoreMO>
getVolumeDatastoreDetails(DiskTO vol, HashMap<String,
Pair<ManagedObjectReference, DatastoreMO>> dataStoresDetails) throws Exception {
+ boolean managed = false;
+ String iScsiName = null;
+ Map<String, String> 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<ManagedObjectReference, DatastoreMO> 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<ManagedObjectReference, DatastoreMO> volumeDsDetails, List<Pair<Integer,
ManagedObjectReference>> 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) {