CLOUDSTACK-6146. [VMware] [ESXi 5.5] Live VM migration of an already migrated 
VM (with storage) across clusters fails
In vCenter 5.5, once a volume is migrated the VMDKs are renamed to match the 
name of the VM.
Update volume path for every volume belonging to the VM to the corresponding 
new disk filename.
(cherry picked from commit 8cb03ddb2387c7aebf20dc0aa011e41f227e9f68)

Signed-off-by: Animesh Chaturvedi <[email protected]>


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

Branch: refs/heads/4.3
Commit: 3cd33f6f4ad756e61c1088d26f7e6b281638f219
Parents: e63af74
Author: Likitha Shetty <[email protected]>
Authored: Tue Feb 25 18:10:52 2014 +0530
Committer: Animesh Chaturvedi <[email protected]>
Committed: Tue Mar 4 23:39:44 2014 -0800

----------------------------------------------------------------------
 .../vmware/resource/VmwareResource.java         | 25 ++++++++++++--
 .../motion/VmwareStorageMotionStrategy.java     | 36 +++++++++++++-------
 2 files changed, 45 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3cd33f6f/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 d27d81f..9f5cf04 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
@@ -4338,6 +4338,8 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
         VolumeTO volume;
         StorageFilerTO filerTo;
         Set<String> mountedDatastoresAtSource = new HashSet<String>();
+        List<VolumeObjectTO> volumeToList =  new ArrayList<VolumeObjectTO>();
+        Map<Long, Integer> volumeDeviceKey = new HashMap<Long, Integer>();
 
         Map<VolumeTO, StorageFilerTO> volToFiler = cmd.getVolumeToFiler();
         String tgtHost = cmd.getTargetHost();
@@ -4402,9 +4404,11 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
                         volume.getPath() + ".vmdk");
                 diskLocator = new VirtualMachineRelocateSpecDiskLocator();
                 diskLocator.setDatastore(morDsAtSource);
-                diskLocator.setDiskId(getVirtualDiskInfo(vmMo, 
volume.getPath() + ".vmdk"));
+                int diskId = getVirtualDiskInfo(vmMo, volume.getPath() + 
".vmdk");
+                diskLocator.setDiskId(diskId);
 
                 diskLocators.add(diskLocator);
+                volumeDeviceKey.put(volume.getId(), diskId);
 
             }
             relocateSpec.getDisk().addAll(diskLocators);
@@ -4436,6 +4440,22 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
                 s_logger.debug("Successfully migrated storage of VM " + vmName 
+ " to target datastore(s)");
             }
 
+            // Update and return volume path for every disk because that could 
have changed after migration
+            for (Entry<VolumeTO, StorageFilerTO> entry : 
volToFiler.entrySet()) {
+                volume = entry.getKey();
+                long volumeId = volume.getId();
+                VirtualDisk[] disks = vmMo.getAllDiskDevice();
+                for (VirtualDisk disk : disks) {
+                    if (volumeDeviceKey.get(volumeId) == disk.getKey()) {
+                        VolumeObjectTO newVol = new VolumeObjectTO();
+                        newVol.setId(volumeId);
+                        newVol.setPath(vmMo.getVmdkFileBaseName(disk));
+                        volumeToList.add(newVol);
+                        break;
+                    }
+                }
+            }
+
             // Change host
             ManagedObjectReference morPool = 
tgtHyperHost.getHyperHostOwnerResourcePool();
             if (!vmMo.migrate(morPool, tgtHyperHost.getMor())) {
@@ -4445,7 +4465,6 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
             }
 
             state = State.Stopping;
-            List<VolumeObjectTO> volumeToList = null;
             return new MigrateWithStorageAnswer(cmd, volumeToList);
         } catch (Throwable e) {
             if (e instanceof RemoteException) {
@@ -4552,7 +4571,7 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
     }
 
     private int getVirtualDiskInfo(VirtualMachineMO vmMo, String srcDiskName) 
throws Exception {
-        Pair<VirtualDisk, String> deviceInfo = vmMo.getDiskDevice(srcDiskName, 
false);
+        Pair<VirtualDisk, String> deviceInfo = vmMo.getDiskDevice(srcDiskName, 
true);
         if(deviceInfo == null) {
             throw new Exception("No such disk device: " + srcDiskName);
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3cd33f6f/plugins/hypervisors/vmware/src/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategy.java
----------------------------------------------------------------------
diff --git 
a/plugins/hypervisors/vmware/src/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategy.java
 
b/plugins/hypervisors/vmware/src/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategy.java
index 446093f..3c4d704 100644
--- 
a/plugins/hypervisors/vmware/src/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategy.java
+++ 
b/plugins/hypervisors/vmware/src/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategy.java
@@ -20,6 +20,7 @@
 package org.apache.cloudstack.storage.motion;
 
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 import javax.inject.Inject;
@@ -33,6 +34,7 @@ import 
org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
 import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
 import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
 import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
 import org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;
 
@@ -143,7 +145,7 @@ public class VmwareStorageMotionStrategy implements 
DataMotionStrategy {
                         ". " + migrateWithStorageAnswer.getDetails());
             } else {
                 // Update the volume details after migration.
-                updateVolumesAfterMigration(volumeToPool);
+                updateVolumesAfterMigration(volumeToPool, 
migrateWithStorageAnswer.getVolumeTos());
             }
             s_logger.debug("Storage migration of VM " + vm.getInstanceName() + 
" completed successfully. Migrated to host " + destHost.getName());
 
@@ -178,7 +180,7 @@ public class VmwareStorageMotionStrategy implements 
DataMotionStrategy {
                         ". " + answer.getDetails());
             } else {
                 // Update the volume details after migration.
-                updateVolumesAfterMigration(volumeToPool);
+                updateVolumesAfterMigration(volumeToPool, 
answer.getVolumeTos());
             }
 
             return answer;
@@ -188,20 +190,28 @@ public class VmwareStorageMotionStrategy implements 
DataMotionStrategy {
         }
     }
 
-    private void updateVolumesAfterMigration(Map<VolumeInfo, DataStore> 
volumeToPool) {
+    private void updateVolumesAfterMigration(Map<VolumeInfo, DataStore> 
volumeToPool, List<VolumeObjectTO> volumeTos) {
         for (Map.Entry<VolumeInfo, DataStore> entry : volumeToPool.entrySet()) 
{
+            boolean updated = false;
             VolumeInfo volume = entry.getKey();
             StoragePool pool = (StoragePool)entry.getValue();
-
-            VolumeVO volumeVO = volDao.findById(volume.getId());
-            Long oldPoolId = volumeVO.getPoolId();
-            volumeVO.setLastPoolId(oldPoolId);
-            volumeVO.setFolder(pool.getPath());
-            volumeVO.setPodId(pool.getPodId());
-            volumeVO.setPoolId(pool.getId());
-
-            volDao.update(volume.getId(), volumeVO);
-            s_logger.debug("Volume path was successfully updated for volume " 
+ volume.getName() + " after it was migrated.");
+            for (VolumeObjectTO volumeTo : volumeTos) {
+                if (volume.getId() == volumeTo.getId()) {
+                    VolumeVO volumeVO = volDao.findById(volume.getId());
+                    Long oldPoolId = volumeVO.getPoolId();
+                    volumeVO.setPath(volumeTo.getPath());
+                    volumeVO.setLastPoolId(oldPoolId);
+                    volumeVO.setFolder(pool.getPath());
+                    volumeVO.setPodId(pool.getPodId());
+                    volumeVO.setPoolId(pool.getId());
+                    volDao.update(volume.getId(), volumeVO);
+                    updated = true;
+                    break;
+                }
+            }
+            if (!updated) {
+                s_logger.error("Volume path wasn't updated for volume " + 
volume + " after it was migrated.");
+            }
         }
     }
 }

Reply via email to