cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mtutkow...@apache.org
Subject git commit: updated refs/heads/4.3 to ecd4a9c
Date Tue, 07 Jan 2014 19:42:17 GMT
Updated Branches:
  refs/heads/4.3 279e9cbe4 -> ecd4a9c64


CLOUDSTACK-5823: Taking a VMware snapshot doesn't work


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/ecd4a9c6
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/ecd4a9c6
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/ecd4a9c6

Branch: refs/heads/4.3
Commit: ecd4a9c6424be73b24a44c73f04c67c47e1611e8
Parents: 279e9cb
Author: Mike Tutkowski <mike.tutkowski@solidfire.com>
Authored: Mon Jan 6 18:35:03 2014 -0700
Committer: Mike Tutkowski <mike.tutkowski@solidfire.com>
Committed: Tue Jan 7 12:41:18 2014 -0700

----------------------------------------------------------------------
 .../manager/VmwareStorageManagerImpl.java       | 241 ++++++++++++-------
 .../cloud/hypervisor/vmware/mo/ClusterMO.java   |   5 +
 .../com/cloud/hypervisor/vmware/mo/HostMO.java  |   6 +
 .../vmware/mo/VmwareHypervisorHost.java         |   2 +
 4 files changed, 161 insertions(+), 93 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ecd4a9c6/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java
b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java
index 3519ca1..268017c 100644
--- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java
@@ -1215,10 +1215,9 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager
{
     }
 
     private long getVMSnapshotChainSize(VmwareContext context, VmwareHypervisorHost hyperHost,
-            String fileName, String poolUuid, String exceptFileName)
+            String fileName, ManagedObjectReference morDs, String exceptFileName)
                     throws Exception{
         long size = 0;
-        ManagedObjectReference morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost,
poolUuid);
         DatastoreMO dsMo = new DatastoreMO(context, morDs);
         HostDatastoreBrowserMO browserMo = dsMo.getHostDatastoreBrowserMO();
         String datastorePath = "[" + dsMo.getName() + "]";
@@ -1278,97 +1277,179 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager
{
         boolean quiescevm = cmd.getTarget().getQuiescevm();
         VirtualMachineMO vmMo = null;
         VmwareContext context = hostService.getServiceContext(cmd);
-        Map<String, String> mapNewDisk = new HashMap<String, String>();
+
         try {
             VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd);
 
             // wait if there are already VM snapshot task running
             ManagedObjectReference taskmgr = context.getServiceContent().getTaskManager();
             List<ManagedObjectReference> tasks = (ArrayList<ManagedObjectReference>)context.getVimClient().getDynamicProperty(taskmgr,
"recentTask");
+
             for (ManagedObjectReference taskMor : tasks) {
-                TaskInfo info = (TaskInfo) (context.getVimClient().getDynamicProperty(taskMor,
"info"));
-                if(info.getEntityName().equals(cmd.getVmName()) && info.getName().equalsIgnoreCase("CreateSnapshot_Task")){
+                TaskInfo info = (TaskInfo)(context.getVimClient().getDynamicProperty(taskMor,
"info"));
+
+                if (info.getEntityName().equals(cmd.getVmName()) && info.getName().equalsIgnoreCase("CreateSnapshot_Task"))
{
                     s_logger.debug("There is already a VM snapshot task running, wait for
it");
                     context.getVimClient().waitForTask(taskMor);
                 }
             }
 
             vmMo = hyperHost.findVmOnHyperHost(vmName);
-            if(vmMo == null) {
+
+            if (vmMo == null) {
                 vmMo = hyperHost.findVmOnPeerHyperHost(vmName);
             }
+
             if (vmMo == null) {
                 String msg = "Unable to find VM for CreateVMSnapshotCommand";
                 s_logger.debug(msg);
+
                 return new CreateVMSnapshotAnswer(cmd, false, msg);
             } else {
                 if (vmMo.getSnapshotMor(vmSnapshotName) != null){
                     s_logger.debug("VM snapshot " + vmSnapshotName + " already exists");
-                }else if (!vmMo.createSnapshot(vmSnapshotName, vmSnapshotDesc, snapshotMemory,
quiescevm)) {
-                    return new CreateVMSnapshotAnswer(cmd, false,
-                            "Unable to create snapshot due to esxi internal failed");
-                }
-                // find VM disk file path after creating snapshot
-                VirtualDisk[] vdisks = vmMo.getAllDiskDevice();
-                for (int i = 0; i < vdisks.length; i ++){
-                    List<Pair<String, ManagedObjectReference>> vmdkFiles = vmMo.getDiskDatastorePathChain(vdisks[i],
false);
-                    for(Pair<String, ManagedObjectReference> fileItem : vmdkFiles)
{
-                        String vmdkName = fileItem.first().split(" ")[1];
-                        if (vmdkName.endsWith(".vmdk")){
-                            vmdkName = vmdkName.substring(0, vmdkName.length() - (".vmdk").length());
-                        }
-                        String baseName = extractSnapshotBaseFileName(vmdkName);
-                        mapNewDisk.put(baseName, vmdkName);
-                    }
+                } else if (!vmMo.createSnapshot(vmSnapshotName, vmSnapshotDesc, snapshotMemory,
quiescevm)) {
+                    return new CreateVMSnapshotAnswer(cmd, false, "Unable to create snapshot
due to esxi internal failed");
                 }
-                for (VolumeObjectTO volumeTO : volumeTOs) {
-                    String baseName = extractSnapshotBaseFileName(volumeTO.getPath());
-                    String newPath = mapNewDisk.get(baseName);
-                    // get volume's chain size for this VM snapshot, exclude current volume
vdisk
-                    DataStoreTO store = volumeTO.getDataStore();
-                    long size = getVMSnapshotChainSize(context,hyperHost,baseName + "*.vmdk",
-                            store.getUuid(), newPath);
-
-                    if(volumeTO.getVolumeType()== Volume.Type.ROOT){
-                        // add memory snapshot size
-                        size = size + getVMSnapshotChainSize(context,hyperHost,cmd.getVmName()+"*.vmsn",store.getUuid(),null);
-                    }
 
-                    volumeTO.setSize(size);
-                    volumeTO.setPath(newPath);
-                }
+                Map<String, String> mapNewDisk = getNewDiskMap(vmMo);
+
+                setVolumeToPathAndSize(volumeTOs, mapNewDisk, context, hyperHost, cmd.getVmName());
+
                 return new CreateVMSnapshotAnswer(cmd, cmd.getTarget(), volumeTOs);
             }
         } catch (Exception e) {
             String msg = e.getMessage();
             s_logger.error("failed to create snapshot for vm:" + vmName + " due to " + msg);
+
             try {
                 if (vmMo.getSnapshotMor(vmSnapshotName) != null) {
                     vmMo.removeSnapshot(vmSnapshotName, false);
                 }
             } catch (Exception e1) {
             }
+
             return new CreateVMSnapshotAnswer(cmd, false, e.getMessage());
         }
     }
 
+    private Map<String, String> getNewDiskMap(VirtualMachineMO vmMo) throws Exception
{
+        Map<String, String> mapNewDisk = new HashMap<String, String>();
+
+        // find VM disk file path after creating snapshot
+        VirtualDisk[] vdisks = vmMo.getAllDiskDevice();
+
+        for (int i = 0; i < vdisks.length; i++) {
+            List<Pair<String, ManagedObjectReference>> vmdkFiles = vmMo.getDiskDatastorePathChain(vdisks[i],
false);
+
+            for (Pair<String, ManagedObjectReference> fileItem : vmdkFiles) {
+                String fullPath = fileItem.first();
+                String baseName = null;
+                String vmdkName = null;
+
+                // if this is managed storage
+                if (fullPath.startsWith("[-iqn.")) { // ex. [-iqn.2010-01.com.company:3y8w.vol-10.64-0]
-iqn.2010-01.com.company:3y8w.vol-10.64-0-000001.vmdk
+                    baseName = fullPath.split(" ")[0]; // ex. [-iqn.2010-01.com.company:3y8w.vol-10.64-0]
+
+                    // remove '[' and ']'
+                    baseName = baseName.substring(1, baseName.length() - 1);
+
+                    vmdkName = fullPath; // for managed storage, vmdkName == fullPath
+                }
+                else {
+                    vmdkName = fullPath.split(" ")[1];
+
+                    if (vmdkName.endsWith(".vmdk")) {
+                        vmdkName = vmdkName.substring(0, vmdkName.length() - (".vmdk").length());
+                    }
+
+                    String token = "/";
+
+                    if (vmdkName.contains(token)) {
+                        vmdkName = vmdkName.substring(vmdkName.indexOf(token) + token.length());
+                    }
+
+                    baseName = extractSnapshotBaseFileName(vmdkName);
+                }
+
+                mapNewDisk.put(baseName, vmdkName);
+            }
+        }
+
+        return mapNewDisk;
+    }
+
+    private void setVolumeToPathAndSize(List<VolumeObjectTO> volumeTOs, Map<String,
String> mapNewDisk, VmwareContext context,
+            VmwareHypervisorHost hyperHost, String vmName) throws Exception {
+        for (VolumeObjectTO volumeTO : volumeTOs) {
+            String oldPath = volumeTO.getPath();
+
+            final String baseName;
+
+            // if this is managed storage
+            if (oldPath.startsWith("[-iqn.")) { // ex. [-iqn.2010-01.com.company:3y8w.vol-10.64-0]
-iqn.2010-01.com.company:3y8w.vol-10.64-0-000001.vmdk
+                oldPath = oldPath.split(" ")[0]; // ex. [-iqn.2010-01.com.company:3y8w.vol-10.64-0]
+
+                // remove '[' and ']'
+                baseName = oldPath.substring(1, oldPath.length() - 1);
+            }
+            else {
+                baseName = extractSnapshotBaseFileName(volumeTO.getPath());
+            }
+
+            String newPath = mapNewDisk.get(baseName);
+
+            // get volume's chain size for this VM snapshot; exclude current volume vdisk
+            DataStoreTO store = volumeTO.getDataStore();
+            ManagedObjectReference morDs = getDatastoreAsManagedObjectReference(baseName,
hyperHost, store);
+            long size = getVMSnapshotChainSize(context, hyperHost, baseName + "*.vmdk", morDs,
newPath);
+
+            if (volumeTO.getVolumeType()== Volume.Type.ROOT) {
+                // add memory snapshot size
+                size += getVMSnapshotChainSize(context, hyperHost, vmName + "*.vmsn", morDs,
null);
+            }
+
+            volumeTO.setSize(size);
+            volumeTO.setPath(newPath);
+        }
+    }
+
+    private ManagedObjectReference getDatastoreAsManagedObjectReference(String baseName,
VmwareHypervisorHost hyperHost, DataStoreTO store)  throws Exception {
+        try {
+            // if baseName equates to a datastore name, this should be managed storage
+            ManagedObjectReference morDs = hyperHost.findDatastoreByName(baseName);
+
+            if (morDs != null) {
+                return morDs;
+            }
+        }
+        catch (Exception ex) {
+        }
+
+        // not managed storage, so use the standard way of getting a ManagedObjectReference
for a datastore
+        return HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, store.getUuid());
+    }
+
     @Override
     public DeleteVMSnapshotAnswer execute(VmwareHostService hostService, DeleteVMSnapshotCommand
cmd) {
         List<VolumeObjectTO> listVolumeTo = cmd.getVolumeTOs();
         VirtualMachineMO vmMo = null;
         VmwareContext context = hostService.getServiceContext(cmd);
-        Map<String, String> mapNewDisk = new HashMap<String, String>();
         String vmName = cmd.getVmName();
         String vmSnapshotName = cmd.getTarget().getSnapshotName();
+
         try {
             VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd);
             vmMo = hyperHost.findVmOnHyperHost(vmName);
-            if(vmMo == null) {
+
+            if (vmMo == null) {
                 vmMo = hyperHost.findVmOnPeerHyperHost(vmName);
             }
+
             if (vmMo == null) {
                 String msg = "Unable to find VM for RevertToVMSnapshotCommand";
                 s_logger.debug(msg);
+
                 return new DeleteVMSnapshotAnswer(cmd, false, msg);
             } else {
                 if (vmMo.getSnapshotMor(vmSnapshotName) == null) {
@@ -1377,42 +1458,25 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager
{
                     if (!vmMo.removeSnapshot(vmSnapshotName, false)) {
                         String msg = "delete vm snapshot " + vmSnapshotName + " due to error
occured in vmware";
                         s_logger.error(msg);
+
                         return new DeleteVMSnapshotAnswer(cmd, false, msg);
                     }
                 }
+
                 s_logger.debug("snapshot: " + vmSnapshotName + " is removed");
+
                 // after removed snapshot, the volumes' paths have been changed for the VM,
needs to report new paths to manager
-                VirtualDisk[] vdisks = vmMo.getAllDiskDevice();
-                for (int i = 0; i < vdisks.length; i++) {
-                    @SuppressWarnings("deprecation")
-                    List<Pair<String, ManagedObjectReference>> vmdkFiles = vmMo.getDiskDatastorePathChain(vdisks[i],
false);
-                    for (Pair<String, ManagedObjectReference> fileItem : vmdkFiles)
{
-                        String vmdkName = fileItem.first().split(" ")[1];
-                        if (vmdkName.endsWith(".vmdk")) {
-                            vmdkName = vmdkName.substring(0, vmdkName.length() - (".vmdk").length());
-                        }
-                        String baseName = extractSnapshotBaseFileName(vmdkName);
-                        mapNewDisk.put(baseName, vmdkName);
-                    }
-                }
-                for (VolumeObjectTO volumeTo : listVolumeTo) {
-                    String baseName = extractSnapshotBaseFileName(volumeTo.getPath());
-                    String newPath = mapNewDisk.get(baseName);
-                    DataStoreTO store = volumeTo.getDataStore();
-                    long size = getVMSnapshotChainSize(context,hyperHost,
-                            baseName + "*.vmdk", store.getUuid(), newPath);
-                    if(volumeTo.getVolumeType()== Volume.Type.ROOT){
-                        // add memory snapshot size
-                        size = size + getVMSnapshotChainSize(context,hyperHost,cmd.getVmName()+"*.vmsn",store.getUuid(),null);
-                    }
-                    volumeTo.setSize(size);
-                    volumeTo.setPath(newPath);
-                }
+
+                Map<String, String> mapNewDisk = getNewDiskMap(vmMo);
+
+                setVolumeToPathAndSize(listVolumeTo, mapNewDisk, context, hyperHost, cmd.getVmName());
+
                 return new DeleteVMSnapshotAnswer(cmd, listVolumeTo);
             }
         } catch (Exception e) {
             String msg = e.getMessage();
             s_logger.error("failed to delete vm snapshot " + vmSnapshotName + " of vm " +
vmName + " due to " + msg);
+
             return new DeleteVMSnapshotAnswer(cmd, false, msg);
         }
     }
@@ -1426,16 +1490,18 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager
{
         VirtualMachine.State vmState = VirtualMachine.State.Running;
         VirtualMachineMO vmMo = null;
         VmwareContext context = hostService.getServiceContext(cmd);
-        Map<String, String> mapNewDisk = new HashMap<String, String>();
+
         try {
             VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd);
 
             // wait if there are already VM revert task running
             ManagedObjectReference taskmgr = context.getServiceContent().getTaskManager();
             List<ManagedObjectReference> tasks = (ArrayList<ManagedObjectReference>)context.getVimClient().getDynamicProperty(taskmgr,
"recentTask");
+
             for (ManagedObjectReference taskMor : tasks) {
-                TaskInfo info = (TaskInfo) (context.getVimClient().getDynamicProperty(taskMor,
"info"));
-                if(info.getEntityName().equals(cmd.getVmName()) && info.getName().equalsIgnoreCase("RevertToSnapshot_Task")){
+                TaskInfo info = (TaskInfo)(context.getVimClient().getDynamicProperty(taskMor,
"info"))
+;
+                if (info.getEntityName().equals(cmd.getVmName()) && info.getName().equalsIgnoreCase("RevertToSnapshot_Task"))
{
                     s_logger.debug("There is already a VM snapshot task running, wait for
it");
                     context.getVimClient().waitForTask(taskMor);
                 }
@@ -1443,60 +1509,49 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager
{
 
             HostMO hostMo = (HostMO) hyperHost;
             vmMo = hyperHost.findVmOnHyperHost(vmName);
-            if(vmMo == null) {
+
+            if (vmMo == null) {
                 vmMo = hyperHost.findVmOnPeerHyperHost(vmName);
             }
+
             if (vmMo == null) {
                 String msg = "Unable to find VM for RevertToVMSnapshotCommand";
                 s_logger.debug(msg);
+
                 return new RevertToVMSnapshotAnswer(cmd, false, msg);
             } else {
                 if (cmd.isReloadVm()) {
                     vmMo.reload();
                 }
+
                 boolean result = false;
+
                 if (snapshotName != null) {
                     ManagedObjectReference morSnapshot = vmMo.getSnapshotMor(snapshotName);
+
                     result = hostMo.revertToSnapshot(morSnapshot);
                 } else {
                     return new RevertToVMSnapshotAnswer(cmd, false, "Unable to find the snapshot
by name " + snapshotName);
                 }
 
                 if (result) {
-                    VirtualDisk[] vdisks = vmMo.getAllDiskDevice();
-                    // build a map<volumeName, vmdk>
-                    for (int i = 0; i < vdisks.length; i++) {
-                        @SuppressWarnings("deprecation")
-                        List<Pair<String, ManagedObjectReference>> vmdkFiles
= vmMo.getDiskDatastorePathChain(
-                                vdisks[i], false);
-                        for (Pair<String, ManagedObjectReference> fileItem : vmdkFiles)
{
-                            String vmdkName = fileItem.first().split(" ")[1];
-                            if (vmdkName.endsWith(".vmdk")) {
-                                vmdkName = vmdkName.substring(0, vmdkName.length() - (".vmdk").length());
-                            }
-                            String[] s = vmdkName.split("-");
-                            mapNewDisk.put(s[0], vmdkName);
-                        }
-                    }
-                    String key = null;
-                    for (VolumeObjectTO volumeTo : listVolumeTo) {
-                        String parentUUID = volumeTo.getPath();
-                        String[] s = parentUUID.split("-");
-                        key = s[0];
-                        volumeTo.setPath(mapNewDisk.get(key));
-                    }
+                    Map<String, String> mapNewDisk = getNewDiskMap(vmMo);
+
+                    setVolumeToPathAndSize(listVolumeTo, mapNewDisk, context, hyperHost,
cmd.getVmName());
+
                     if (!snapshotMemory) {
                         vmState = VirtualMachine.State.Stopped;
                     }
+
                     return new RevertToVMSnapshotAnswer(cmd, listVolumeTo, vmState);
                 } else {
-                    return new RevertToVMSnapshotAnswer(cmd, false,
-                            "Error while reverting to snapshot due to execute in esxi");
+                    return new RevertToVMSnapshotAnswer(cmd, false, "Error while reverting
to snapshot due to execute in ESXi");
                 }
             }
         } catch (Exception e) {
             String msg = "revert vm " + vmName + " to snapshot " + snapshotName + " failed
due to " + e.getMessage();
             s_logger.error(msg);
+
             return new RevertToVMSnapshotAnswer(cmd, false, msg);
         }
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ecd4a9c6/vmware-base/src/com/cloud/hypervisor/vmware/mo/ClusterMO.java
----------------------------------------------------------------------
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/ClusterMO.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/ClusterMO.java
index bbd9e79..14bddc5 100755
--- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/ClusterMO.java
+++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/ClusterMO.java
@@ -384,6 +384,11 @@ public class ClusterMO extends BaseMO implements VmwareHypervisorHost
{
 		return null;
 	}
 
+    @Override
+    public ManagedObjectReference findDatastoreByName(String datastoreName) throws Exception
{
+       throw new UnsupportedOperationException();
+   }
+
 	@Override
 	public ManagedObjectReference findDatastoreByExportPath(String exportPath) throws Exception
{
 	    if(s_logger.isTraceEnabled())

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ecd4a9c6/vmware-base/src/com/cloud/hypervisor/vmware/mo/HostMO.java
----------------------------------------------------------------------
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/HostMO.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/HostMO.java
index 7ef8326..2dafbf3 100755
--- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/HostMO.java
+++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/HostMO.java
@@ -893,6 +893,12 @@ public class HostMO extends BaseMO implements VmwareHypervisorHost {
 		return hostDsMo.findDatastore(poolUuid);
 	}
 
+    @Override
+    public ManagedObjectReference findDatastoreByName(String datastoreName) throws Exception
{
+        HostDatastoreSystemMO hostDsMo = getHostDatastoreSystemMO();
+        return hostDsMo.findDatastoreByName(datastoreName);
+    }
+
 	@Override
 	public ManagedObjectReference findDatastoreByExportPath(String exportPath) throws Exception
{
 		HostDatastoreSystemMO datastoreSystemMo = getHostDatastoreSystemMO();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ecd4a9c6/vmware-base/src/com/cloud/hypervisor/vmware/mo/VmwareHypervisorHost.java
----------------------------------------------------------------------
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VmwareHypervisorHost.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VmwareHypervisorHost.java
index c2c326a..d37c066 100755
--- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VmwareHypervisorHost.java
+++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VmwareHypervisorHost.java
@@ -58,6 +58,8 @@ public interface VmwareHypervisorHost {
 	
 	ManagedObjectReference findDatastore(String poolUuid) throws Exception;
 	
+	ManagedObjectReference findDatastoreByName(String datastoreName) throws Exception;
+
 	@Deprecated
 	ManagedObjectReference findDatastoreByExportPath(String exportPath) throws Exception;
 	


Mime
View raw message