vmware: don't use redundant worker VM to extract volume (#3218)

This fixes the issue that VM with VMsnapshots fails to start after
extract volume is done on a stopped VM, on VMware.

Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
This commit is contained in:
Rohit Yadav 2019-05-23 16:48:30 +05:30 committed by dahn
parent a5da389b15
commit 4f356392ab
2 changed files with 47 additions and 32 deletions

View File

@ -930,12 +930,12 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
String prevSnapshotUuid, String prevBackupUuid, String workerVmName, Integer nfsVersion) throws Exception {
String backupUuid = UUID.randomUUID().toString();
exportVolumeToSecondaryStroage(vmMo, volumePath, secStorageUrl, getSnapshotRelativeDirInSecStorage(accountId, volumeId), backupUuid, workerVmName, nfsVersion);
exportVolumeToSecondaryStorage(vmMo, volumePath, secStorageUrl, getSnapshotRelativeDirInSecStorage(accountId, volumeId), backupUuid, workerVmName, nfsVersion, true);
return backupUuid + "/" + backupUuid;
}
private void exportVolumeToSecondaryStroage(VirtualMachineMO vmMo, String volumePath, String secStorageUrl, String secStorageDir, String exportName, String workerVmName,
Integer nfsVersion) throws Exception {
private void exportVolumeToSecondaryStorage(VirtualMachineMO vmMo, String volumePath, String secStorageUrl, String secStorageDir, String exportName, String workerVmName,
Integer nfsVersion, boolean clonedWorkerVMNeeded) throws Exception {
String secondaryMountPoint = _mountService.getMountPoint(secStorageUrl, nfsVersion);
String exportPath = secondaryMountPoint + "/" + secStorageDir + "/" + exportName;
@ -961,16 +961,19 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
throw new Exception(msg);
}
// 4 MB is the minimum requirement for VM memory in VMware
vmMo.cloneFromCurrentSnapshot(workerVmName, 0, 4, volumeDeviceInfo.second(), VmwareHelper.getDiskDeviceDatastore(volumeDeviceInfo.first()));
clonedVm = vmMo.getRunningHost().findVmOnHyperHost(workerVmName);
if (clonedVm == null) {
String msg = "Unable to create dummy VM to export volume. volume path: " + volumePath;
s_logger.error(msg);
throw new Exception(msg);
if (clonedWorkerVMNeeded) {
// 4 MB is the minimum requirement for VM memory in VMware
vmMo.cloneFromCurrentSnapshot(workerVmName, 0, 4, volumeDeviceInfo.second(), VmwareHelper.getDiskDeviceDatastore(volumeDeviceInfo.first()));
clonedVm = vmMo.getRunningHost().findVmOnHyperHost(workerVmName);
if (clonedVm == null) {
String msg = "Unable to create dummy VM to export volume. volume path: " + volumePath;
s_logger.error(msg);
throw new Exception(msg);
}
clonedVm.exportVm(exportPath, exportName, false, false); //Note: volss: not to create ova.
} else {
vmMo.exportVm(exportPath, exportName, false, false);
}
clonedVm.exportVm(exportPath, exportName, false, false); //Note: volss: not to create ova.
} finally {
if (clonedVm != null) {
clonedVm.detachAllDisks();
@ -998,6 +1001,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
throw new Exception(msg);
}
boolean clonedWorkerVMNeeded = true;
vmMo = hyperHost.findVmOnHyperHost(vmName);
if (vmMo == null) {
// create a dummy worker vm for attaching the volume
@ -1014,16 +1018,19 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
String datastoreVolumePath = getVolumePathInDatastore(dsMo, volumePath + ".vmdk", searchExcludedFolders);
workerVm.attachDisk(new String[] {datastoreVolumePath}, morDs);
vmMo = workerVm;
clonedWorkerVMNeeded = false;
} else {
vmMo.createSnapshot(exportName, "Temporary snapshot for copy-volume command", false, false);
}
vmMo.createSnapshot(exportName, "Temporary snapshot for copy-volume command", false, false);
exportVolumeToSecondaryStroage(vmMo, volumePath, secStorageUrl, "volumes/" + volumeFolder, exportName, hostService.getWorkerName(hyperHost.getContext(), cmd, 1),
nfsVersion);
exportVolumeToSecondaryStorage(vmMo, volumePath, secStorageUrl, "volumes/" + volumeFolder, exportName, hostService.getWorkerName(hyperHost.getContext(), cmd, 1),
nfsVersion, clonedWorkerVMNeeded);
return new Pair<String, String>(volumeFolder, exportName);
} finally {
vmMo.removeSnapshot(exportName, false);
if (vmMo != null && vmMo.getSnapshotMor(exportName) != null) {
vmMo.removeSnapshot(exportName, false);
}
if (workerVm != null) {
//detach volume and destroy worker vm
workerVm.detachAllDisks();

View File

@ -983,6 +983,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
throw new Exception(msg);
}
boolean clonedWorkerVMNeeded = true;
vmMo = hyperHost.findVmOnHyperHost(vmName);
if (vmMo == null || VmwareResource.getVmState(vmMo) == PowerState.PowerOff) {
// create a dummy worker vm for attaching the volume
@ -999,15 +1000,18 @@ public class VmwareStorageProcessor implements StorageProcessor {
String datastoreVolumePath = getVolumePathInDatastore(dsMo, volumePath + ".vmdk", searchExcludedFolders);
workerVm.attachDisk(new String[] {datastoreVolumePath}, morDs);
vmMo = workerVm;
clonedWorkerVMNeeded = false;
} else {
vmMo.createSnapshot(exportName, "Temporary snapshot for copy-volume command", false, false);
}
vmMo.createSnapshot(exportName, "Temporary snapshot for copy-volume command", false, false);
exportVolumeToSecondaryStroage(vmMo, volumePath, secStorageUrl, destVolumePath, exportName, hostService.getWorkerName(hyperHost.getContext(), cmd, 1), _nfsVersion);
exportVolumeToSecondaryStorage(vmMo, volumePath, secStorageUrl, destVolumePath, exportName, hostService.getWorkerName(hyperHost.getContext(), cmd, 1), _nfsVersion, clonedWorkerVMNeeded);
return new Pair<>(destVolumePath, exportName);
} finally {
vmMo.removeSnapshot(exportName, false);
if (vmMo != null && vmMo.getSnapshotMor(exportName) != null) {
vmMo.removeSnapshot(exportName, false);
}
if (workerVm != null) {
//detach volume and destroy worker vm
workerVm.detachAllDisks();
@ -1657,8 +1661,8 @@ public class VmwareStorageProcessor implements StorageProcessor {
}
// return Pair<String(divice bus name), String[](disk chain)>
private Pair<String, String[]> exportVolumeToSecondaryStroage(VirtualMachineMO vmMo, String volumePath, String secStorageUrl, String secStorageDir,
String exportName, String workerVmName, Integer nfsVersion) throws Exception {
private Pair<String, String[]> exportVolumeToSecondaryStorage(VirtualMachineMO vmMo, String volumePath, String secStorageUrl, String secStorageDir,
String exportName, String workerVmName, Integer nfsVersion, boolean clonedWorkerVMNeeded) throws Exception {
String secondaryMountPoint = mountService.getMountPoint(secStorageUrl, nfsVersion);
String exportPath = secondaryMountPoint + "/" + secStorageDir + "/" + exportName;
@ -1684,14 +1688,18 @@ public class VmwareStorageProcessor implements StorageProcessor {
throw new Exception(msg);
}
// 4 MB is the minimum requirement for VM memory in VMware
Pair<VirtualMachineMO, String[]> cloneResult =
vmMo.cloneFromCurrentSnapshot(workerVmName, 0, 4, volumeDeviceInfo.second(), VmwareHelper.getDiskDeviceDatastore(volumeDeviceInfo.first()));
clonedVm = cloneResult.first();
String disks[] = cloneResult.second();
clonedVm.exportVm(exportPath, exportName, false, false);
return new Pair<>(volumeDeviceInfo.second(), disks);
String diskDevice = volumeDeviceInfo.second();
String disks[] = vmMo.getCurrentSnapshotDiskChainDatastorePaths(diskDevice);
if (clonedWorkerVMNeeded) {
// 4 MB is the minimum requirement for VM memory in VMware
Pair<VirtualMachineMO, String[]> cloneResult =
vmMo.cloneFromCurrentSnapshot(workerVmName, 0, 4, diskDevice, VmwareHelper.getDiskDeviceDatastore(volumeDeviceInfo.first()));
clonedVm = cloneResult.first();
clonedVm.exportVm(exportPath, exportName, false, false);
} else {
vmMo.exportVm(exportPath, exportName, false, false);
}
return new Pair<>(diskDevice, disks);
} finally {
if (clonedVm != null) {
clonedVm.detachAllDisks();
@ -1706,7 +1714,7 @@ public class VmwareStorageProcessor implements StorageProcessor {
Integer nfsVersion) throws Exception {
String backupUuid = UUID.randomUUID().toString();
Pair<String, String[]> snapshotInfo = exportVolumeToSecondaryStroage(vmMo, volumePath, secStorageUrl, installPath, backupUuid, workerVmName, nfsVersion);
Pair<String, String[]> snapshotInfo = exportVolumeToSecondaryStorage(vmMo, volumePath, secStorageUrl, installPath, backupUuid, workerVmName, nfsVersion, true);
return new Ternary<>(backupUuid, snapshotInfo.first(), snapshotInfo.second());
}