VMware 80u2 and 80u3 updates/fixes (#10586)

* VMware - Ignore disk not found error on cleanup when the VM disk doesn't exists

* VMware - Retry powerOn on lock issues

* addressed comments

* Update CPVM reboot tests - wait for the agent to Disconnect and back Up

* Retry moveDatastoreFile when any file access issue while creating volume from snapshot

* Update full clone flag when restoring vm using root disk offering with more size than the template size

* refactored (mainly,for diskInfo - causing NPE in some cases)

* Retry moveDatastoreFile when there is any file access issue
This commit is contained in:
Suresh Kumar Anaparti 2025-05-17 00:39:34 +05:30 committed by GitHub
parent 8f8c685d17
commit 90316b2e90
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 160 additions and 85 deletions

View File

@ -2042,7 +2042,6 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
VirtualMachineDefinedProfileSpec diskProfileSpec = null;
VirtualMachineDefinedProfileSpec vmProfileSpec = null;
DeployAsIsInfoTO deployAsIsInfo = vmSpec.getDeployAsIsInfo();
boolean deployAsIs = deployAsIsInfo != null;
@ -2086,7 +2085,6 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
}
VirtualMachineDiskInfoBuilder diskInfoBuilder = null;
VirtualDevice[] nicDevices = null;
VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(vmInternalCSName);
DiskControllerType systemVmScsiControllerType = DiskControllerType.lsilogic;
int firstScsiControllerBusNum = 0;
@ -2103,7 +2101,6 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
diskDatastores = vmMo.getAllDiskDatastores();
diskInfoBuilder = vmMo.getDiskInfoBuilder();
hasSnapshot = vmMo.hasSnapshot();
nicDevices = vmMo.getNicDevices();
tearDownVmDevices(vmMo, hasSnapshot, deployAsIs);
ensureDiskControllersInternal(vmMo, systemVm, controllerInfo, systemVmScsiControllerType,
@ -2119,17 +2116,20 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
}
takeVmFromOtherHyperHost(hyperHost, vmInternalCSName);
vmMo = hyperHost.findVmOnHyperHost(vmInternalCSName);
if (getVmPowerState(vmMo) != PowerState.PowerOff)
vmMo.safePowerOff(_shutdownWaitMs);
if (vmMo != null) {
if (getVmPowerState(vmMo) != PowerState.PowerOff)
vmMo.safePowerOff(_shutdownWaitMs);
diskInfoBuilder = vmMo.getDiskInfoBuilder();
hasSnapshot = vmMo.hasSnapshot();
diskDatastores = vmMo.getAllDiskDatastores();
diskInfoBuilder = vmMo.getDiskInfoBuilder();
hasSnapshot = vmMo.hasSnapshot();
diskDatastores = vmMo.getAllDiskDatastores();
tearDownVmDevices(vmMo, hasSnapshot, deployAsIs);
ensureDiskControllersInternal(vmMo, systemVm, controllerInfo, systemVmScsiControllerType,
numScsiControllerForSystemVm, firstScsiControllerBusNum, deployAsIs);
tearDownVmDevices(vmMo, hasSnapshot, deployAsIs);
ensureDiskControllersInternal(vmMo, systemVm, controllerInfo, systemVmScsiControllerType,
numScsiControllerForSystemVm, firstScsiControllerBusNum, deployAsIs);
}
} else {
// If a VM with the same name is found in a different cluster in the DC, unregister the old VM and configure a new VM (cold-migration).
VirtualMachineMO existingVmInDc = dcMo.findVm(vmInternalCSName);
@ -2146,7 +2146,7 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
vmMo = hyperHost.findVmOnHyperHost(vmInternalCSName);
if (vmMo == null) {
logger.info("Cloned deploy-as-is VM " + vmInternalCSName + " is not in this host, relocating it");
vmMo = takeVmFromOtherHyperHost(hyperHost, vmInternalCSName);
takeVmFromOtherHyperHost(hyperHost, vmInternalCSName);
}
} else {
DiskTO rootDisk = null;
@ -2256,11 +2256,11 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
vmConfigSpec.setCpuHotAddEnabled(vmMo.isCpuHotAddSupported(guestOsId) && vmSpec.isEnableDynamicallyScaleVm());
}
if(!vmMo.isMemoryHotAddSupported(guestOsId) && vmSpec.isEnableDynamicallyScaleVm()){
if (!vmMo.isMemoryHotAddSupported(guestOsId) && vmSpec.isEnableDynamicallyScaleVm()) {
logger.warn("hotadd of memory is not supported, dynamic scaling feature can not be applied to vm: " + vmInternalCSName);
}
if(!vmMo.isCpuHotAddSupported(guestOsId) && vmSpec.isEnableDynamicallyScaleVm()){
if (!vmMo.isCpuHotAddSupported(guestOsId) && vmSpec.isEnableDynamicallyScaleVm()) {
logger.warn("hotadd of cpu is not supported, dynamic scaling feature can not be applied to vm: " + vmInternalCSName);
}
@ -2593,7 +2593,7 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
Map<String, Map<String, String>> iqnToData = new HashMap<>();
postDiskConfigBeforeStart(vmMo, vmSpec, sortedDisks, ideControllerKey, scsiControllerKey, iqnToData, hyperHost, context);
postDiskConfigBeforeStart(vmMo, vmSpec, sortedDisks, iqnToData, hyperHost, context);
//
// Power-on VM
@ -2731,14 +2731,24 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
}
private boolean powerOnVM(final VirtualMachineMO vmMo, final String vmInternalCSName, final String vmNameOnVcenter) throws Exception {
int retry = 20;
while (retry-- > 0) {
final int retry = 20;
int retryAttempt = 0;
while (++retryAttempt <= retry) {
try {
logger.debug(String.format("VM %s, powerOn attempt #%d", vmInternalCSName, retryAttempt));
return vmMo.powerOn();
} catch (Exception e) {
logger.info(String.format("Got exception while power on VM %s with hostname %s", vmInternalCSName, vmNameOnVcenter), e);
if (e.getMessage() != null && e.getMessage().contains("File system specific implementation of Ioctl[file] failed")) {
if (e.getMessage() != null &&
(e.getMessage().contains("File system specific implementation of Ioctl[file] failed") ||
e.getMessage().contains("Unable to access file") ||
e.getMessage().contains("it is locked"))) {
logger.debug(String.format("Failed to power on VM %s with hostname %s. Retrying", vmInternalCSName, vmNameOnVcenter));
try {
Thread.sleep(1000);
} catch (InterruptedException ie) {
logger.debug(String.format("Waiting to power on VM %s been interrupted: ", vmInternalCSName));
}
} else {
throw e;
}
@ -3292,7 +3302,7 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
int getReservedMemoryMb(VirtualMachineTO vmSpec) {
if (vmSpec.getDetails().get(VMwareGuru.VmwareReserveMemory.key()).equalsIgnoreCase("true")) {
if(vmSpec.getDetails().get(VmDetailConstants.RAM_RESERVATION) != null){
if (vmSpec.getDetails().get(VmDetailConstants.RAM_RESERVATION) != null) {
float reservedMemory = (vmSpec.getMaxRam() * Float.parseFloat(vmSpec.getDetails().get(VmDetailConstants.RAM_RESERVATION)));
return (int) (reservedMemory / ResourceType.bytesToMiB);
}
@ -3630,18 +3640,18 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
private VirtualMachineDiskInfo getMatchingExistingDisk(VirtualMachineDiskInfoBuilder diskInfoBuilder, DiskTO vol, VmwareHypervisorHost hyperHost, VmwareContext context)
throws Exception {
if (diskInfoBuilder != null) {
VolumeObjectTO volume = (VolumeObjectTO) vol.getData();
String chainInfo = volume.getChainInfo();
Map<String, String> details = vol.getDetails();
boolean isManaged = details != null && Boolean.parseBoolean(details.get(DiskTO.MANAGED));
String iScsiName = details.get(DiskTO.IQN);
String datastoreUUID = volume.getDataStore().getUuid();
return getMatchingExistingDiskWithVolumeDetails(diskInfoBuilder, volume.getPath(), chainInfo, isManaged, iScsiName, datastoreUUID, hyperHost, context);
} else {
if (diskInfoBuilder == null) {
return null;
}
VolumeObjectTO volume = (VolumeObjectTO) vol.getData();
String chainInfo = volume.getChainInfo();
Map<String, String> details = vol.getDetails();
boolean isManaged = details != null && Boolean.parseBoolean(details.get(DiskTO.MANAGED));
String iScsiName = details.get(DiskTO.IQN);
String datastoreUUID = volume.getDataStore().getUuid();
return getMatchingExistingDiskWithVolumeDetails(diskInfoBuilder, volume.getPath(), chainInfo, isManaged, iScsiName, datastoreUUID, hyperHost, context);
}
private String getDiskController(VirtualMachineMO vmMo, VirtualMachineDiskInfo matchingExistingDisk, DiskTO vol, Pair<String, String> controllerInfo, boolean deployAsIs) throws Exception {
@ -3666,34 +3676,36 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
return VmwareHelper.getControllerBasedOnDiskType(controllerInfo, vol);
}
private void postDiskConfigBeforeStart(VirtualMachineMO vmMo, VirtualMachineTO vmSpec, DiskTO[] sortedDisks, int ideControllerKey,
int scsiControllerKey, Map<String, Map<String, String>> iqnToData, VmwareHypervisorHost hyperHost, VmwareContext context) throws Exception {
private void postDiskConfigBeforeStart(VirtualMachineMO vmMo, VirtualMachineTO vmSpec, DiskTO[] sortedDisks,
Map<String, Map<String, String>> iqnToData, VmwareHypervisorHost hyperHost, VmwareContext context) throws Exception {
VirtualMachineDiskInfoBuilder diskInfoBuilder = vmMo.getDiskInfoBuilder();
for (DiskTO vol : sortedDisks) {
if (vol.getType() == Volume.Type.ISO)
continue;
VolumeObjectTO volumeTO = (VolumeObjectTO) vol.getData();
VirtualMachineDiskInfo diskInfo = getMatchingExistingDisk(diskInfoBuilder, vol, hyperHost, context);
assert (diskInfo != null);
if (diskInfo == null) {
continue;
}
String[] diskChain = diskInfo.getDiskChain();
assert (diskChain.length > 0);
Map<String, String> details = vol.getDetails();
boolean managed = false;
if (details != null) {
managed = Boolean.parseBoolean(details.get(DiskTO.MANAGED));
if (diskChain.length <= 0) {
continue;
}
DatastoreFile file = new DatastoreFile(diskChain[0]);
boolean managed = false;
Map<String, String> details = vol.getDetails();
if (details != null) {
managed = Boolean.parseBoolean(details.get(DiskTO.MANAGED));
}
VolumeObjectTO volumeTO = (VolumeObjectTO) vol.getData();
if (managed) {
DatastoreFile originalFile = new DatastoreFile(volumeTO.getPath());
if (!file.getFileBaseName().equalsIgnoreCase(originalFile.getFileBaseName())) {
if (logger.isInfoEnabled())
logger.info("Detected disk-chain top file change on volume: " + volumeTO.getId() + " " + volumeTO.getPath() + " -> " + diskChain[0]);
@ -3706,7 +3718,6 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
}
VolumeObjectTO volInSpec = getVolumeInSpec(vmSpec, volumeTO);
if (volInSpec != null) {
if (managed) {
Map<String, String> data = new HashMap<>();
@ -3871,20 +3882,20 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
if (diskInfo != null) {
logger.info("Found existing disk info from volume path: " + volume.getPath());
return dsMo;
} else {
String chainInfo = volume.getChainInfo();
if (chainInfo != null) {
VirtualMachineDiskInfo infoInChain = _gson.fromJson(chainInfo, VirtualMachineDiskInfo.class);
if (infoInChain != null) {
String[] disks = infoInChain.getDiskChain();
if (disks.length > 0) {
for (String diskPath : disks) {
DatastoreFile file = new DatastoreFile(diskPath);
diskInfo = diskInfoBuilder.getDiskInfoByBackingFileBaseName(file.getFileBaseName(), dsName);
if (diskInfo != null) {
logger.info("Found existing disk from chain info: " + diskPath);
return dsMo;
}
}
String chainInfo = volume.getChainInfo();
if (chainInfo != null) {
VirtualMachineDiskInfo infoInChain = _gson.fromJson(chainInfo, VirtualMachineDiskInfo.class);
if (infoInChain != null) {
String[] disks = infoInChain.getDiskChain();
if (disks.length > 0) {
for (String diskPath : disks) {
DatastoreFile file = new DatastoreFile(diskPath);
diskInfo = diskInfoBuilder.getDiskInfoByBackingFileBaseName(file.getFileBaseName(), dsName);
if (diskInfo != null) {
logger.info("Found existing disk from chain info: " + diskPath);
return dsMo;
}
}
}
@ -4747,7 +4758,7 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
Map<Integer, Long> volumeDeviceKey = new HashMap<>();
if (cmd instanceof MigrateVolumeCommand) { // Else device keys will be found in relocateVirtualMachine
MigrateVolumeCommand mcmd = (MigrateVolumeCommand) cmd;
addVolumeDiskmapping(vmMo, volumeDeviceKey, mcmd.getVolumePath(), mcmd.getVolumeId());
addVolumeDiskMapping(vmMo, volumeDeviceKey, mcmd.getVolumePath(), mcmd.getVolumeId());
if (logger.isTraceEnabled()) {
for (Integer diskId: volumeDeviceKey.keySet()) {
logger.trace(String.format("Disk to migrate has disk id %d and volumeId %d", diskId, volumeDeviceKey.get(diskId)));
@ -4765,9 +4776,7 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
Answer createAnswerForCmd(VirtualMachineMO vmMo, List<VolumeObjectTO> volumeObjectToList, Command cmd, Map<Integer, Long> volumeDeviceKey) throws Exception {
List<VolumeObjectTO> volumeToList;
VirtualMachineDiskInfoBuilder diskInfoBuilder = vmMo.getDiskInfoBuilder();
VirtualDisk[] disks = vmMo.getAllDiskDevice();
Answer answer;
if (logger.isTraceEnabled()) {
logger.trace(String.format("creating answer for %s", cmd.getClass().getSimpleName()));
}
@ -4784,7 +4793,7 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
return new Answer(cmd, false, null);
}
private void addVolumeDiskmapping(VirtualMachineMO vmMo, Map<Integer, Long> volumeDeviceKey, String volumePath, long volumeId) throws Exception {
private void addVolumeDiskMapping(VirtualMachineMO vmMo, Map<Integer, Long> volumeDeviceKey, String volumePath, long volumeId) throws Exception {
if (logger.isDebugEnabled()) {
logger.debug(String.format("locating disk for volume (%d) using path %s", volumeId, volumePath));
}
@ -4919,7 +4928,7 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
VmwareHypervisorHost dsHost = hyperHostInTargetCluster == null ? hyperHost : hyperHostInTargetCluster;
String targetDsName = cmd.getTargetPool().getUuid();
morDestinationDS = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(dsHost, targetDsName);
if(morDestinationDS == null) {
if (morDestinationDS == null) {
String msg = "Unable to find the target datastore: " + targetDsName + " on host: " + dsHost.getHyperHostName();
logger.error(msg);
throw new CloudRuntimeException(msg);
@ -5886,6 +5895,11 @@ public class VmwareResource extends ServerResourceBase implements StoragePoolRes
logger.debug(msg);
return new Answer(cmd, true, msg);
} catch (Exception e) {
if (e.getMessage().contains("was not found")) {
String msg = String.format("%s - VM [%s] file(s) not found, cleanup not needed .", e.getMessage(), cmd.getVmName());
logger.debug(msg);
return new Answer(cmd, true, msg);
}
return new Answer(cmd, false, createLogMessageException(e, cmd));
}
}

View File

@ -20,6 +20,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import com.vmware.vim25.ManagedObjectReference;
import org.apache.cloudstack.framework.config.ConfigKey;
import org.apache.cloudstack.framework.config.Configurable;
import org.apache.logging.log4j.Logger;
@ -193,7 +194,7 @@ public class VmwareStorageLayoutHelper implements Configurable {
if (ds.fileExists(vmdkFullCloneModeLegacyPair[i])) {
LOGGER.info("sync " + vmdkFullCloneModeLegacyPair[i] + "->" + vmdkFullCloneModePair[i]);
ds.moveDatastoreFile(vmdkFullCloneModeLegacyPair[i], dcMo.getMor(), ds.getMor(), vmdkFullCloneModePair[i], dcMo.getMor(), true);
moveDatastoreFile(ds, vmdkFullCloneModeLegacyPair[i], dcMo.getMor(), ds.getMor(), vmdkFullCloneModePair[i], dcMo.getMor(), true);
}
}
@ -201,13 +202,13 @@ public class VmwareStorageLayoutHelper implements Configurable {
if (ds.fileExists(vmdkLinkedCloneModeLegacyPair[i])) {
LOGGER.info("sync " + vmdkLinkedCloneModeLegacyPair[i] + "->" + vmdkLinkedCloneModePair[i]);
ds.moveDatastoreFile(vmdkLinkedCloneModeLegacyPair[i], dcMo.getMor(), ds.getMor(), vmdkLinkedCloneModePair[i], dcMo.getMor(), true);
moveDatastoreFile(ds, vmdkLinkedCloneModeLegacyPair[i], dcMo.getMor(), ds.getMor(), vmdkLinkedCloneModePair[i], dcMo.getMor(), true);
}
}
if (ds.fileExists(vmdkLinkedCloneModeLegacyPair[0])) {
LOGGER.info("sync " + vmdkLinkedCloneModeLegacyPair[0] + "->" + vmdkLinkedCloneModePair[0]);
ds.moveDatastoreFile(vmdkLinkedCloneModeLegacyPair[0], dcMo.getMor(), ds.getMor(), vmdkLinkedCloneModePair[0], dcMo.getMor(), true);
moveDatastoreFile(ds, vmdkLinkedCloneModeLegacyPair[0], dcMo.getMor(), ds.getMor(), vmdkLinkedCloneModePair[0], dcMo.getMor(), true);
}
// Note: we will always return a path
@ -242,14 +243,14 @@ public class VmwareStorageLayoutHelper implements Configurable {
String targetPath = getDatastorePathBaseFolderFromVmdkFileName(ds, String.format("%s-%s",vmdkName, linkedCloneExtension));
LOGGER.info("Fixup folder-synchronization. move " + companionFilePath + " -> " + targetPath);
ds.moveDatastoreFile(companionFilePath, dcMo.getMor(), ds.getMor(), targetPath, dcMo.getMor(), true);
moveDatastoreFile(ds, companionFilePath, dcMo.getMor(), ds.getMor(), targetPath, dcMo.getMor(), true);
}
}
// move the identity VMDK file the last
String targetPath = getDatastorePathBaseFolderFromVmdkFileName(ds, vmdkName + ".vmdk");
LOGGER.info("Fixup folder-synchronization. move " + fileDsFullPath + " -> " + targetPath);
ds.moveDatastoreFile(fileDsFullPath, dcMo.getMor(), ds.getMor(), targetPath, dcMo.getMor(), true);
moveDatastoreFile(ds, fileDsFullPath, dcMo.getMor(), ds.getMor(), targetPath, dcMo.getMor(), true);
try {
if (folderName != null) {
@ -287,7 +288,7 @@ public class VmwareStorageLayoutHelper implements Configurable {
DatastoreFile targetFile = new DatastoreFile(file.getDatastoreName(), HypervisorHostHelper.VSPHERE_DATASTORE_BASE_FOLDER, file.getFileName());
if (!targetFile.getPath().equalsIgnoreCase(file.getPath())) {
LOGGER.info("Move " + file.getPath() + " -> " + targetFile.getPath());
dsMo.moveDatastoreFile(file.getPath(), dcMo.getMor(), dsMo.getMor(), targetFile.getPath(), dcMo.getMor(), true);
moveDatastoreFile(dsMo, file.getPath(), dcMo.getMor(), dsMo.getMor(), targetFile.getPath(), dcMo.getMor(), true);
List<String> vSphereFileExtensions = new ArrayList<>(Arrays.asList(VsphereLinkedCloneExtensions.value().trim().split("\\s*,\\s*")));
// add flat file format to the above list
@ -297,7 +298,7 @@ public class VmwareStorageLayoutHelper implements Configurable {
String pairTargetFilePath = targetFile.getCompanionPath(String.format("%s-%s", file.getFileBaseName(), linkedCloneExtension));
if (dsMo.fileExists(pairSrcFilePath)) {
LOGGER.info("Move " + pairSrcFilePath + " -> " + pairTargetFilePath);
dsMo.moveDatastoreFile(pairSrcFilePath, dcMo.getMor(), dsMo.getMor(), pairTargetFilePath, dcMo.getMor(), true);
moveDatastoreFile(dsMo, pairSrcFilePath, dcMo.getMor(), dsMo.getMor(), pairTargetFilePath, dcMo.getMor(), true);
}
}
}
@ -429,6 +430,31 @@ public class VmwareStorageLayoutHelper implements Configurable {
return dsMo.searchFileInSubFolders(volumePath + ".vmdk", false, null);
}
public static boolean moveDatastoreFile(final DatastoreMO dsMo, String srcFilePath, ManagedObjectReference morSrcDc, ManagedObjectReference morDestDs,
String destFilePath, ManagedObjectReference morDestDc, boolean forceOverwrite) throws Exception {
final int retry = 20;
int retryAttempt = 0;
while (++retryAttempt <= retry) {
try {
LOGGER.debug(String.format("Move datastore file %s, attempt #%d", srcFilePath, retryAttempt));
return dsMo.moveDatastoreFile(srcFilePath, morSrcDc, morDestDs, destFilePath, morDestDc, forceOverwrite);
} catch (Exception e) {
LOGGER.info(String.format("Got exception while moving datastore file %s ", srcFilePath), e);
if (e.getMessage() != null && e.getMessage().contains("Unable to access file")) {
LOGGER.debug(String.format("Failed to move datastore file %s. Retrying", srcFilePath));
try {
Thread.sleep(1000);
} catch (InterruptedException ie) {
LOGGER.debug(String.format("Waiting to move datastore file %s been interrupted: ", srcFilePath));
}
} else {
throw e;
}
}
}
return false;
}
@Override
public String getConfigComponentName() {
return VmwareStorageLayoutHelper.class.getSimpleName();

View File

@ -682,9 +682,9 @@ public class VmwareStorageProcessor implements StorageProcessor {
String[] legacyCloudStackLayoutFilePair = VmwareStorageLayoutHelper.getVmdkFilePairManagedDatastorePath(dsMo, null,
managedStoragePoolRootVolumeName, VmwareStorageLayoutType.CLOUDSTACK_LEGACY, false);
dsMo.moveDatastoreFile(vmwareLayoutFilePair[0], dcMo.getMor(), dsMo.getMor(), legacyCloudStackLayoutFilePair[0], dcMo.getMor(), true);
VmwareStorageLayoutHelper.moveDatastoreFile(dsMo, vmwareLayoutFilePair[0], dcMo.getMor(), dsMo.getMor(), legacyCloudStackLayoutFilePair[0], dcMo.getMor(), true);
for (int i=1; i<vmwareLayoutFilePair.length; i++) {
dsMo.moveDatastoreFile(vmwareLayoutFilePair[i], dcMo.getMor(), dsMo.getMor(), legacyCloudStackLayoutFilePair[i], dcMo.getMor(), true);
VmwareStorageLayoutHelper.moveDatastoreFile(dsMo, vmwareLayoutFilePair[i], dcMo.getMor(), dsMo.getMor(), legacyCloudStackLayoutFilePair[i], dcMo.getMor(), true);
}
String folderToDelete = dsMo.getDatastorePath(managedStoragePoolRootVolumeName, true);
@ -814,7 +814,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
existingVm.detachAllDisksAndDestroy();
}
logger.info("ROOT Volume from deploy-as-is template, cloning template");
cloneVMFromTemplate(hyperHost, template.getPath(), vmName, primaryStore.getUuid());
cloneVMFromTemplate(hyperHost, template, volume, vmName, primaryStore.getUuid());
} else {
logger.info("ROOT Volume from deploy-as-is template, volume already created at this point");
}
@ -945,7 +945,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
String[] legacyCloudStackLayoutFilePair = VmwareStorageLayoutHelper.getVmdkFilePairDatastorePath(dsMo, vmdkName, vmdkFileBaseName, VmwareStorageLayoutType.CLOUDSTACK_LEGACY, !_fullCloneFlag);
for (int i = 0; i < vmwareLayoutFilePair.length; i++) {
dsMo.moveDatastoreFile(vmwareLayoutFilePair[i], dcMo.getMor(), dsMo.getMor(), legacyCloudStackLayoutFilePair[i], dcMo.getMor(), true);
VmwareStorageLayoutHelper.moveDatastoreFile(dsMo, vmwareLayoutFilePair[i], dcMo.getMor(), dsMo.getMor(), legacyCloudStackLayoutFilePair[i], dcMo.getMor(), true);
}
logger.info("detach disks from volume-wrapper VM and destroy {}", vmdkName);
@ -1222,10 +1222,10 @@ public class VmwareStorageProcessor implements StorageProcessor {
// Get VMDK filename
String templateVMDKName = "";
File[] files = new File(installFullPath).listFiles();
if(files != null) {
if (files != null) {
for(File file : files) {
String fileName = file.getName();
if(fileName.toLowerCase().startsWith(templateUniqueName) && fileName.toLowerCase().endsWith(".vmdk")) {
if (fileName.toLowerCase().startsWith(templateUniqueName) && fileName.toLowerCase().endsWith(".vmdk")) {
templateVMDKName += fileName;
break;
}
@ -1856,16 +1856,16 @@ public class VmwareStorageProcessor implements StorageProcessor {
CopyCmdAnswer answer = null;
try {
if(vmName != null) {
if (vmName != null) {
vmMo = hyperHost.findVmOnHyperHost(vmName);
if (vmMo == null) {
if(logger.isDebugEnabled()) {
if (logger.isDebugEnabled()) {
logger.debug("Unable to find owner VM for BackupSnapshotCommand on host " + hyperHost.getHyperHostName() + ", will try within datacenter");
}
vmMo = hyperHost.findVmOnPeerHyperHost(vmName);
}
}
if(vmMo == null) {
if (vmMo == null) {
dsMo = new DatastoreMO(hyperHost.getContext(), morDs);
workerVMName = hostService.getWorkerName(context, cmd, 0, dsMo);
vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, workerVMName, null);
@ -1899,10 +1899,10 @@ public class VmwareStorageProcessor implements StorageProcessor {
String secondaryMountPoint = mountService.getMountPoint(secondaryStorageUrl, _nfsVersion);
String snapshotDir = destSnapshot.getPath() + "/" + snapshotBackupUuid;
File[] files = new File(secondaryMountPoint + "/" + snapshotDir).listFiles();
if(files != null) {
if (files != null) {
for(File file : files) {
String fileName = file.getName();
if(fileName.toLowerCase().startsWith(snapshotBackupUuid) && fileName.toLowerCase().endsWith(".vmdk")) {
if (fileName.toLowerCase().startsWith(snapshotBackupUuid) && fileName.toLowerCase().endsWith(".vmdk")) {
physicalSize = new File(secondaryMountPoint + "/" + snapshotDir + "/" + fileName).length();
break;
}
@ -3651,7 +3651,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
}
workerVm.tagAsWorkerVM();
if(!primaryDsMo.getDatastoreType().equalsIgnoreCase("VVOL")) {
if (!primaryDsMo.getDatastoreType().equalsIgnoreCase("VVOL")) {
HypervisorHostHelper.createBaseFolderInDatastore(primaryDsMo, primaryDsMo.getDataCenterMor());
workerVm.moveAllVmDiskFiles(primaryDsMo, HypervisorHostHelper.VSPHERE_DATASTORE_BASE_FOLDER, false);
}
@ -3811,8 +3811,9 @@ public class VmwareStorageProcessor implements StorageProcessor {
/**
* Return the cloned VM from the template
*/
public VirtualMachineMO cloneVMFromTemplate(VmwareHypervisorHost hyperHost, String templateName, String cloneName, String templatePrimaryStoreUuid) {
public VirtualMachineMO cloneVMFromTemplate(VmwareHypervisorHost hyperHost, TemplateObjectTO template, VolumeObjectTO volume, String cloneName, String templatePrimaryStoreUuid) {
try {
String templateName = template.getPath();
VmwareContext context = hyperHost.getContext();
DatacenterMO dcMo = new DatacenterMO(context, hyperHost.getHyperHostDatacenter());
VirtualMachineMO templateMo = dcMo.findVm(templateName);
@ -3826,6 +3827,9 @@ public class VmwareStorageProcessor implements StorageProcessor {
throw new CloudRuntimeException("Unable to find datastore in vSphere");
}
logger.info("Cloning VM " + cloneName + " from template " + templateName + " into datastore " + templatePrimaryStoreUuid);
if (template.getSize() != null) {
_fullCloneFlag = volume.getSize() > template.getSize() ? true : _fullCloneFlag;
}
if (!_fullCloneFlag) {
createVMLinkedClone(templateMo, dcMo, cloneName, morDatastore, morPool, null);
} else {

View File

@ -8394,6 +8394,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
getRootVolumeSizeForVmRestore(newVol, template, userVm, diskOffering, details, true);
volumeMgr.saveVolumeDetails(newVol.getDiskOfferingId(), newVol.getId());
newVol = _volsDao.findById(newVol.getId());
// 1. Save usage event and update resource count for user vm volumes
try {
@ -8493,7 +8494,6 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
Long getRootVolumeSizeForVmRestore(Volume vol, VMTemplateVO template, UserVmVO userVm, DiskOffering diskOffering, Map<String, String> details, boolean update) {
VolumeVO resizedVolume = (VolumeVO) vol;
Long size = null;
if (template != null && template.getSize() != null) {
UserVmDetailVO vmRootDiskSizeDetail = userVmDetailsDao.findDetail(userVm.getId(), VmDetailConstants.ROOT_DISK_SIZE);

View File

@ -988,6 +988,9 @@ class TestSSVMs(cloudstackTestCase):
# Private IP Address of System VMs are allowed to change after reboot - CLOUDSTACK-7745
# Agent in Up state for a while after reboot, wait for the agent to Disconnect and back Up.
time.sleep(60)
# Wait for the agent to be up
self.waitForSystemVMAgent(cpvm_response.name)
@ -1103,6 +1106,9 @@ class TestSSVMs(cloudstackTestCase):
"Check whether CPVM is running or not"
)
# Agent in Up state for a while after reboot, wait for the agent to Disconnect and back Up.
time.sleep(60)
# Wait for the agent to be up
self.waitForSystemVMAgent(cpvm_response.name)

View File

@ -2332,7 +2332,7 @@ public class VirtualMachineMO extends BaseMO {
vmdkDescriptor = getVmdkFileInfo(fileItem.first());
logger.info("Move VM disk file " + srcFile.getPath() + " to " + destFile.getPath());
srcDsMo.moveDatastoreFile(fileItem.first(), dcMo.getMor(), destDsMo.getMor(), destFile.getPath(), dcMo.getMor(), true);
moveDatastoreFile(srcDsMo, fileItem.first(), dcMo.getMor(), destDsMo.getMor(), destFile.getPath(), dcMo.getMor(), true);
if (vmdkDescriptor != null) {
String vmdkBaseFileName = vmdkDescriptor.first().getBaseFileName();
@ -2340,13 +2340,38 @@ public class VirtualMachineMO extends BaseMO {
destFile = new DatastoreFile(destDsMo.getName(), destDsDir, vmdkBaseFileName);
logger.info("Move VM disk file " + baseFilePath + " to " + destFile.getPath());
srcDsMo.moveDatastoreFile(baseFilePath, dcMo.getMor(), destDsMo.getMor(), destFile.getPath(), dcMo.getMor(), true);
moveDatastoreFile(srcDsMo, baseFilePath, dcMo.getMor(), destDsMo.getMor(), destFile.getPath(), dcMo.getMor(), true);
}
}
}
}
}
private boolean moveDatastoreFile(final DatastoreMO dsMo, String srcFilePath, ManagedObjectReference morSrcDc, ManagedObjectReference morDestDs,
String destFilePath, ManagedObjectReference morDestDc, boolean forceOverwrite) throws Exception {
final int retry = 20;
int retryAttempt = 0;
while (++retryAttempt <= retry) {
try {
logger.debug(String.format("Move datastore file %s, attempt #%d", srcFilePath, retryAttempt));
return dsMo.moveDatastoreFile(srcFilePath, morSrcDc, morDestDs, destFilePath, morDestDc, forceOverwrite);
} catch (Exception e) {
logger.info(String.format("Got exception while moving datastore file %s ", srcFilePath), e);
if (e.getMessage() != null && e.getMessage().contains("Unable to access file")) {
logger.debug(String.format("Failed to move datastore file %s. Retrying", srcFilePath));
try {
Thread.sleep(1000);
} catch (InterruptedException ie) {
logger.debug(String.format("Waiting to move datastore file %s been interrupted: ", srcFilePath));
}
} else {
throw e;
}
}
}
return false;
}
public int getPvScsiDeviceControllerKeyNoException() throws Exception {
List<VirtualDevice> devices = (List<VirtualDevice>)_context.getVimClient().
getDynamicProperty(_mor, "config.hardware.device");