Github user mike-tutkowski commented on a diff in the pull request: https://github.com/apache/cloudstack/pull/1671#discussion_r77634892 --- Diff: engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java --- @@ -2045,62 +2045,74 @@ protected void migrate(final VMInstanceVO vm, final long srcHostId, final Deploy private Map<Volume, StoragePool> getPoolListForVolumesForMigration(final VirtualMachineProfile profile, final Host host, final Map<Long, Long> volumeToPool) { final List<VolumeVO> allVolumes = _volsDao.findUsableVolumesForInstance(profile.getId()); - final Map<Volume, StoragePool> volumeToPoolObjectMap = new HashMap<Volume, StoragePool> (); + final Map<Volume, StoragePool> volumeToPoolObjectMap = new HashMap<>(); + for (final VolumeVO volume : allVolumes) { final Long poolId = volumeToPool.get(Long.valueOf(volume.getId())); - final StoragePoolVO pool = _storagePoolDao.findById(poolId); + final StoragePoolVO destPool = _storagePoolDao.findById(poolId); final StoragePoolVO currentPool = _storagePoolDao.findById(volume.getPoolId()); final DiskOfferingVO diskOffering = _diskOfferingDao.findById(volume.getDiskOfferingId()); - if (pool != null) { + + if (destPool != null) { // Check if pool is accessible from the destination host and disk offering with which the volume was // created is compliant with the pool type. - if (_poolHostDao.findByPoolHost(pool.getId(), host.getId()) == null || pool.isLocal() != diskOffering.getUseLocalStorage()) { + if (_poolHostDao.findByPoolHost(destPool.getId(), host.getId()) == null || destPool.isLocal() != diskOffering.getUseLocalStorage()) { // Cannot find a pool for the volume. Throw an exception. - throw new CloudRuntimeException("Cannot migrate volume " + volume + " to storage pool " + pool + " while migrating vm to host " + host + + throw new CloudRuntimeException("Cannot migrate volume " + volume + " to storage pool " + destPool + " while migrating vm to host " + host + ". Either the pool is not accessible from the host or because of the offering with which the volume is created it cannot be placed on " + "the given pool."); - } else if (pool.getId() == currentPool.getId()) { - // If the pool to migrate too is the same as current pool, the volume doesn't need to be migrated. + } else if (destPool.getId() == currentPool.getId()) { + // If the pool to migrate to is the same as current pool, the volume doesn't need to be migrated. } else { - volumeToPoolObjectMap.put(volume, pool); + volumeToPoolObjectMap.put(volume, destPool); } } else { - // Find a suitable pool for the volume. Call the storage pool allocator to find the list of pools. - final DiskProfile diskProfile = new DiskProfile(volume, diskOffering, profile.getHypervisorType()); - final DataCenterDeployment plan = new DataCenterDeployment(host.getDataCenterId(), host.getPodId(), host.getClusterId(), host.getId(), null, null); - final ExcludeList avoid = new ExcludeList(); - boolean currentPoolAvailable = false; - - final List<StoragePool> poolList = new ArrayList<StoragePool>(); - for (final StoragePoolAllocator allocator : _storagePoolAllocators) { - final List<StoragePool> poolListFromAllocator = allocator.allocateToPool(diskProfile, profile, plan, avoid, StoragePoolAllocator.RETURN_UPTO_ALL); - if (poolListFromAllocator != null && !poolListFromAllocator.isEmpty()) { - poolList.addAll(poolListFromAllocator); - } - } + if (currentPool.isManaged()) { + volumeToPoolObjectMap.put(volume, currentPool); + } else { + // Find a suitable pool for the volume. Call the storage pool allocator to find the list of pools. - if (poolList != null && !poolList.isEmpty()) { - // Volume needs to be migrated. Pick the first pool from the list. Add a mapping to migrate the - // volume to a pool only if it is required; that is the current pool on which the volume resides - // is not available on the destination host. - final Iterator<StoragePool> iter = poolList.iterator(); - while (iter.hasNext()) { - if (currentPool.getId() == iter.next().getId()) { - currentPoolAvailable = true; - break; + final DiskProfile diskProfile = new DiskProfile(volume, diskOffering, profile.getHypervisorType()); + final DataCenterDeployment plan = new DataCenterDeployment(host.getDataCenterId(), host.getPodId(), host.getClusterId(), host.getId(), null, null); --- End diff -- For this PR, the limitation is not just storage tagging, but also the src and dest have to be the same zone-wide primary storage. I know you and I have another task on our shared to-do list to enable cross-primary storage migration (where managed storage is one or both of the primary storages). This, however, does not implement that functionality. This PR just enables Storage XenMotion/vMotion from one cluster to another where managed storage is involved (and the data effectively stays on the same primary storage).
--- If your project is set up for it, you can reply to this email and have your reply appear on GitHub as well. If your project does not have this feature enabled and wishes so, or if the feature is enabled but not working, please contact infrastructure at infrastruct...@apache.org or file a JIRA ticket with INFRA. ---