mirror of
https://github.com/apache/cloudstack.git
synced 2025-11-03 04:12:31 +01:00
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:
parent
a5da389b15
commit
4f356392ab
@ -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();
|
||||
|
||||
@ -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());
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user