Updated Branches:
  refs/heads/4.2 dabc071a1 -> bdb8107c6

CLOUDSTACK-4375 VM Migration is failing from one cluster to another cluster.

listHostsForMigrationOfVM is being called when user attempts to move a VM to 
other host. This is trying to find list of suitable storage pools that are 
attached to each of the suitable hosts for the VM.
Currently the selection of target storage pools for each volume of the VM is 
left to storage pool allocators.
But user might want to leave his volume unmoved/intact If it is on a zone wide 
storage pool.
This would be more efficient while migrating VM as storage live migration is 
not required and VM continues to use volumes on same storage pool as before.
Hence idea is to set same storage pool as target pool for each of the volume if 
the volume is already on zone wide storage pool.
A comparison of source pool of volume against target pool of volume yields the 
information if storage migration is required for the VM to move to target host 
or not.
Based on that information apropriate API migrateVM or migrateVmWithVolume could 
be decided.

Signed-off-by: Sateesh Chodapuneedi <sate...@apache.org>


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

Branch: refs/heads/4.2
Commit: bdb8107c6180c21dfcc4fce446c2a53c4b50f40e
Parents: dabc071
Author: Sateesh Chodapuneedi <sate...@apache.org>
Authored: Mon Aug 19 21:03:46 2013 +0530
Committer: Sateesh Chodapuneedi <sate...@apache.org>
Committed: Mon Aug 19 21:03:46 2013 +0530

----------------------------------------------------------------------
 .../com/cloud/server/ManagementServerImpl.java  | 69 ++++++++++++--------
 1 file changed, 40 insertions(+), 29 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bdb8107c/server/src/com/cloud/server/ManagementServerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/server/ManagementServerImpl.java 
b/server/src/com/cloud/server/ManagementServerImpl.java
index 7a32dc3..a4837fa 100755
--- a/server/src/com/cloud/server/ManagementServerImpl.java
+++ b/server/src/com/cloud/server/ManagementServerImpl.java
@@ -23,7 +23,6 @@ import java.security.NoSuchAlgorithmException;
 import java.security.SecureRandom;
 import java.util.ArrayList;
 import java.util.Calendar;
-import java.util.Collection;
 import java.util.Comparator;
 import java.util.Date;
 import java.util.HashMap;
@@ -517,6 +516,7 @@ import com.cloud.storage.GuestOS;
 import com.cloud.storage.GuestOSCategoryVO;
 import com.cloud.storage.GuestOSVO;
 import com.cloud.storage.GuestOsCategory;
+import com.cloud.storage.ScopeType;
 import com.cloud.storage.Storage.ImageFormat;
 import com.cloud.storage.Storage.TemplateType;
 import com.cloud.storage.StorageManager;
@@ -1109,7 +1109,7 @@ public class ManagementServerImpl extends ManagerBase 
implements ManagementServe
         List<HostVO> allHosts = null;
         Map<Host, Boolean> requiresStorageMotion = new HashMap<Host, 
Boolean>();
         DataCenterDeployment plan = null;
-        boolean allZoneWideStoragePools = false;
+        boolean migrationRequired = false;
         if (canMigrateWithStorage) {
             allHostsPair = searchForServers(startIndex, pageSize, null, 
hostType, null, srcHost.getDataCenterId(), null,
                     null, null, null, null, null, srcHost.getHypervisorType(), 
srcHost.getHypervisorVersion());
@@ -1124,9 +1124,10 @@ public class ManagementServerImpl extends ManagerBase 
implements ManagementServe
                     iterator.remove();
                 } else {
                     if (srcHost.getHypervisorType() == HypervisorType.VMware 
|| srcHost.getHypervisorType() == HypervisorType.KVM) {
-                        allZoneWideStoragePools = 
checkIfAllZoneWideStoragePools(volumePools);
+                        // Check if each volume required migrating to other 
pool or not.
+                        migrationRequired = 
checkIfMigrationRequired(volumePools);
                     }
-                    if ((!host.getClusterId().equals(srcHost.getClusterId()) 
|| usesLocal) && !allZoneWideStoragePools) {
+                    if ((!host.getClusterId().equals(srcHost.getClusterId()) 
|| usesLocal) && migrationRequired) {
                         requiresStorageMotion.put(host, true);
                     }
                 }
@@ -1188,20 +1189,20 @@ public class ManagementServerImpl extends ManagerBase 
implements ManagementServe
                 suitableHosts, requiresStorageMotion);
     }
 
-    private boolean checkIfAllZoneWideStoragePools(Map<Volume, 
List<StoragePool>> volumePools) {
-        boolean allZoneWideStoragePools = true;
-        Collection<List<StoragePool>> pools = volumePools.values();
-        List<StoragePool> aggregatePoolList = new ArrayList<StoragePool>();
-        for (Iterator<List<StoragePool>> volumePoolsIter = pools.iterator(); 
volumePoolsIter.hasNext();) {
-            aggregatePoolList.addAll(volumePoolsIter.next());
-        }
-        for (StoragePool pool : aggregatePoolList) {
-            if (null != pool.getClusterId()) {
-                allZoneWideStoragePools = false;
-                break;
+    private boolean checkIfMigrationRequired(Map<Volume, List<StoragePool>> 
volumePools) {
+        boolean migratingToOtherStoragePool = false;
+        Iterator<Volume> volumesIt = volumePools.keySet().iterator();
+        while(volumesIt.hasNext()) {
+            Volume vol = volumesIt.next();
+            List<StoragePool> poolList = volumePools.get(vol);
+            for (StoragePool pool : poolList) {
+                // See if any volume requies migration to another storage pool
+                if (pool.getId() != vol.getPoolId()) {
+                    migratingToOtherStoragePool = true;
+                }
             }
         }
-        return allZoneWideStoragePools;
+        return migratingToOtherStoragePool;
     }
 
     private Map<Volume, List<StoragePool>> 
findSuitablePoolsForVolumes(VirtualMachineProfile<VMInstanceVO> vmProfile,
@@ -1211,20 +1212,30 @@ public class ManagementServerImpl extends ManagerBase 
implements ManagementServe
 
         // For each volume find list of suitable storage pools by calling the 
allocators
         for (VolumeVO volume : volumes) {
-            DiskOfferingVO diskOffering = 
_diskOfferingDao.findById(volume.getDiskOfferingId());
-            DiskProfile diskProfile = new DiskProfile(volume, diskOffering, 
vmProfile.getHypervisorType());
-            DataCenterDeployment plan = new 
DataCenterDeployment(host.getDataCenterId(), host.getPodId(),
-                    host.getClusterId(), host.getId(), null, null);
-            ExcludeList avoid = new ExcludeList();
-
             boolean foundPools = false;
-            for (StoragePoolAllocator allocator : _storagePoolAllocators) {
-                List<StoragePool> poolList = 
allocator.allocateToPool(diskProfile, vmProfile, plan, avoid,
-                        StoragePoolAllocator.RETURN_UPTO_ALL);
-                if (poolList != null && !poolList.isEmpty()) {
-                    suitableVolumeStoragePools.put(volume, poolList);
-                    foundPools = true;
-                    break;
+            // If volume is already on zone wide storage pool, do not search 
further to allocate target storage pool for that volume.
+            List<StoragePool> poolList = new ArrayList<StoragePool>();
+            Long volPoolId = volume.getPoolId();
+            StoragePoolVO volumePool = _poolDao.findById(volPoolId);
+            if (volumePool.getScope() == ScopeType.ZONE) {
+                poolList.add(volumePool);
+                suitableVolumeStoragePools.put(volume, poolList);
+                foundPools = true;
+            } else {
+                DiskOfferingVO diskOffering = 
_diskOfferingDao.findById(volume.getDiskOfferingId());
+                DiskProfile diskProfile = new DiskProfile(volume, 
diskOffering, vmProfile.getHypervisorType());
+                DataCenterDeployment plan = new 
DataCenterDeployment(host.getDataCenterId(), host.getPodId(),
+                        host.getClusterId(), host.getId(), null, null);
+                ExcludeList avoid = new ExcludeList();
+
+                for (StoragePoolAllocator allocator : _storagePoolAllocators) {
+                    poolList = allocator.allocateToPool(diskProfile, 
vmProfile, plan, avoid,
+                            StoragePoolAllocator.RETURN_UPTO_ALL);
+                    if (poolList != null && !poolList.isEmpty()) {
+                        suitableVolumeStoragePools.put(volume, poolList);
+                        foundPools = true;
+                        break;
+                    }
                 }
             }
 

Reply via email to