You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by da...@apache.org on 2019/05/23 11:18:41 UTC

[cloudstack] branch master updated: vmware: don't use redundant worker VM to extract volume (#3218)

This is an automated email from the ASF dual-hosted git repository.

dahn pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cloudstack.git


The following commit(s) were added to refs/heads/master by this push:
     new 4f35639  vmware: don't use redundant worker VM to extract volume (#3218)
4f35639 is described below

commit 4f356392ab8b5ac064966af9b2e29e10f5867132
Author: Rohit Yadav <ro...@apache.org>
AuthorDate: Thu May 23 16:48:30 2019 +0530

    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 <ro...@shapeblue.com>
---
 .../vmware/manager/VmwareStorageManagerImpl.java   | 41 +++++++++++++---------
 .../storage/resource/VmwareStorageProcessor.java   | 38 ++++++++++++--------
 2 files changed, 47 insertions(+), 32 deletions(-)

diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java
index b6f207a..b73d250 100644
--- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java
+++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java
@@ -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();
diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageProcessor.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageProcessor.java
index 82cd4ca..9d6aca4 100644
--- a/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageProcessor.java
+++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/storage/resource/VmwareStorageProcessor.java
@@ -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());
     }