Support for volume live migration across datastores

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

Branch: refs/heads/vmware-storage-motion
Commit: 20106139cf3ae3db11150f084c4155026d8e7584
Parents: cabbba7
Author: Sateesh Chodapuneedi <sate...@apache.org>
Authored: Mon May 20 07:35:46 2013 +0530
Committer: Sateesh Chodapuneedi <sate...@apache.org>
Committed: Tue May 28 16:51:35 2013 +0530

----------------------------------------------------------------------
 .../hypervisor/vmware/manager/VmwareManager.java   |    5 +
 .../vmware/manager/VmwareManagerImpl.java          |   31 ++++++++
 .../hypervisor/vmware/resource/VmwareResource.java |   61 ++++++++++++++-
 3 files changed, 93 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/20106139/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManager.java
----------------------------------------------------------------------
diff --git 
a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManager.java
 
b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManager.java
index fb6d3d6..9273143 100755
--- 
a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManager.java
+++ 
b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManager.java
@@ -20,6 +20,7 @@ import java.io.File;
 import java.util.List;
 import java.util.Map;
 
+import com.cloud.agent.api.to.VolumeTO;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
 import com.cloud.hypervisor.vmware.manager.VmwareStorageManager;
 import com.cloud.hypervisor.vmware.mo.HostMO;
@@ -66,4 +67,8 @@ public interface VmwareManager {
     String getPrivateVSwitchName(long dcId, HypervisorType hypervisorType);
     
     public String getRootDiskController();
+
+    String getVmName(long l);
+
+    String getStoragePoolOfVolume(long volumeId);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/20106139/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
----------------------------------------------------------------------
diff --git 
a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
 
b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
index 9f260f1..0d50a2c 100755
--- 
a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
+++ 
b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
@@ -35,6 +35,8 @@ import javax.ejb.Local;
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole;
 import org.apache.log4j.Logger;
 
 import com.cloud.agent.AgentManager;
@@ -45,6 +47,8 @@ import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.Command;
 import com.cloud.agent.api.StartupCommand;
 import com.cloud.agent.api.StartupRoutingCommand;
+import com.cloud.agent.api.storage.MigrateVolumeAnswer;
+import com.cloud.agent.api.to.VolumeTO;
 import com.cloud.cluster.ClusterManager;
 import com.cloud.configuration.Config;
 import com.cloud.configuration.dao.ConfigurationDao;
@@ -79,6 +83,9 @@ import com.cloud.serializer.GsonHelper;
 import com.cloud.server.ConfigurationServer;
 import com.cloud.storage.JavaStorageLayer;
 import com.cloud.storage.StorageLayer;
+import com.cloud.storage.StoragePool;
+import com.cloud.storage.VolumeVO;
+import com.cloud.storage.dao.VolumeDao;
 import com.cloud.storage.secondary.SecondaryStorageVmManager;
 import com.cloud.utils.FileUtil;
 import com.cloud.utils.NumbersUtil;
@@ -92,6 +99,8 @@ import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.utils.script.Script;
 import com.cloud.utils.ssh.SshHelper;
 import com.cloud.vm.DomainRouterVO;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.dao.VMInstanceDao;
 import com.google.gson.Gson;
 import com.vmware.vim25.AboutInfo;
 import com.vmware.vim25.HostConnectSpec;
@@ -124,6 +133,9 @@ public class VmwareManagerImpl extends ManagerBase 
implements VmwareManager, Vmw
     @Inject ConfigurationDao _configDao;
     @Inject ConfigurationServer _configServer;
     @Inject HypervisorCapabilitiesDao _hvCapabilitiesDao;
+    @Inject VMInstanceDao _vmDao;
+    @Inject VolumeDao _volDao;
+    @Inject DataStoreManager dataStoreMgr;
 
     String _mountParent;
     StorageLayer _storage;
@@ -865,4 +877,23 @@ public class VmwareManagerImpl extends ManagerBase 
implements VmwareManager, Vmw
     public String getRootDiskController() {
         return _rootDiskController;
     }
+
+    @Override
+    public String getVmName(long volumeId) {
+        Long instanceId;
+        VolumeVO vol = _volDao.findById(volumeId);
+        instanceId = vol.getInstanceId();
+        VMInstanceVO vmInstance = null;
+        if (instanceId != null) {
+            vmInstance = _vmDao.findById(instanceId);
+        }
+        return vmInstance.getInstanceName();
+    }
+
+    @Override
+    public String getStoragePoolOfVolume(long volumeId) {
+        VolumeVO vol = _volDao.findById(volumeId);
+        long poolId = vol.getPoolId();
+        return dataStoreMgr.getPrimaryDataStore(poolId).getUuid();
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/20106139/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
----------------------------------------------------------------------
diff --git 
a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
 
b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
index 91579ae..3c9319e 100755
--- 
a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
+++ 
b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
@@ -167,6 +167,7 @@ import com.cloud.agent.api.storage.CopyVolumeAnswer;
 import com.cloud.agent.api.storage.CopyVolumeCommand;
 import com.cloud.agent.api.storage.CreateVolumeOVACommand;
 import com.cloud.agent.api.storage.CreateVolumeOVAAnswer;
+import com.cloud.agent.api.storage.MigrateVolumeAnswer;
 import com.cloud.agent.api.storage.MigrateVolumeCommand;
 import com.cloud.agent.api.storage.PrepareOVAPackingAnswer;
 import com.cloud.agent.api.storage.PrepareOVAPackingCommand;
@@ -297,9 +298,6 @@ import 
com.vmware.vim25.VirtualMachineRelocateSpecDiskLocator;
 import com.vmware.vim25.VirtualMachineRuntimeInfo;
 import com.vmware.vim25.VirtualSCSISharing;
 
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.type.VolumeType;
 import org.apache.log4j.Logger;
 import org.apache.log4j.NDC;
 
@@ -3588,8 +3586,63 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
     }
 
     private Answer execute(MigrateVolumeCommand cmd) {
+        String volumePath = cmd.getVolumePath();
+        StorageFilerTO poolTo = cmd.getPool();
 
-        return null;
+        if (s_logger.isInfoEnabled()) {
+            s_logger.info("Executing resource MigrateVolumeCommand: " + 
_gson.toJson(cmd));
+        }
+
+        VmwareContext context = getServiceContext();
+        VmwareManager mgr = 
context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
+        final String vmName = mgr.getVmName(cmd.getVolumeId());
+
+        VirtualMachineMO vmMo = null;
+        VmwareHypervisorHost srcHyperHost = null;
+
+        ManagedObjectReference morDs = null;
+        ManagedObjectReference morDc = null;
+        VirtualMachineRelocateSpec relocateSpec = new 
VirtualMachineRelocateSpec();
+        List<VirtualMachineRelocateSpecDiskLocator> diskLocators = new 
ArrayList<VirtualMachineRelocateSpecDiskLocator>();
+        VirtualMachineRelocateSpecDiskLocator diskLocator = null;
+
+        String srcDiskName = "";
+        String srcDsName = "";
+
+        try {
+            srcHyperHost = getHyperHost(getServiceContext());
+            morDc = srcHyperHost.getHyperHostDatacenter();
+            srcDsName = mgr.getStoragePoolOfVolume(cmd.getVolumeId());
+
+            // find VM through datacenter (VM is not at the target host yet)
+            vmMo = srcHyperHost.findVmOnPeerHyperHost(vmName);
+            if (vmMo == null) {
+                String msg = "VM " + vmName + " does not exist in VMware 
datacenter " + morDc.getValue();
+                s_logger.error(msg);
+                throw new Exception(msg);
+            }
+
+            srcDiskName = String.format("[%s] %s.vmdk", srcDsName, volumePath);
+            diskLocator = new VirtualMachineRelocateSpecDiskLocator();
+            diskLocator.setDatastore(morDs);
+            diskLocator.setDiskId(getVirtualDiskInfo(vmMo, srcDiskName));
+
+            diskLocators.add(diskLocator);
+            relocateSpec.getDisk().add(diskLocator);
+
+            // Change datastore
+            if (!vmMo.changeDatastore(relocateSpec)) {
+                throw new Exception("Change datastore operation failed during 
volume migration");
+            } else {
+                s_logger.debug("Successfully migrated volume " + vmName + " to 
target datastore");
+            }
+
+            return new MigrateVolumeAnswer(cmd, true, null, volumePath);
+        } catch (Exception e) {
+            String msg = "Catch Exception " + e.getClass().getName() + " due 
to " + e.toString();
+            s_logger.error(msg, e);
+            return new MigrateVolumeAnswer(cmd, false, msg, null);
+        }
     }
 
     private int getVirtualDiskInfo(VirtualMachineMO vmMo, String srcDiskName) 
throws Exception {

Reply via email to