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.
Conflicts:
plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
plugins/hypervisors/vmware/src/org/apache/cloudstack/storage/motion/VmwareStorageMotionStrategy.java
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/88b57616
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/88b57616
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/88b57616
Branch: refs/heads/acl-item-cidrs
Commit: 88b576164789391430d779af74ed3a7ee3be87fb
Parents: 0926bf5
Author: Likitha Shetty <[email protected]>
Authored: Tue Feb 25 18:10:52 2014 +0530
Committer: Likitha Shetty <[email protected]>
Committed: Wed Feb 26 13:45:44 2014 +0530
----------------------------------------------------------------------
.../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/88b57616/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 3b631ac..9e12105 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
@@ -2988,6 +2988,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();
@@ -3049,9 +3051,11 @@ public class VmwareResource implements
StoragePoolResource, ServerResource, Vmwa
".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);
@@ -3083,6 +3087,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())) {
@@ -3092,7 +3112,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) {
@@ -3198,7 +3217,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/88b57616/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 e1527f9..09f1068 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;
@@ -36,6 +37,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 com.cloud.agent.AgentManager;
import com.cloud.agent.api.Answer;
@@ -145,7 +147,7 @@ public class VmwareStorageMotionStrategy implements
DataMotionStrategy {
throw new CloudRuntimeException("Error while migrating the vm
" + vm + " to host " + destHost + ". " + 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());
@@ -179,7 +181,7 @@ public class VmwareStorageMotionStrategy implements
DataMotionStrategy {
throw new CloudRuntimeException("Error while migrating the vm
" + vm + " to host " + destHost + ". " + answer.getDetails());
} else {
// Update the volume details after migration.
- updateVolumesAfterMigration(volumeToPool);
+ updateVolumesAfterMigration(volumeToPool,
answer.getVolumeTos());
}
return answer;
@@ -189,20 +191,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.");
+ }
}
}
}