This is an automated email from the ASF dual-hosted git repository.
rohit pushed a commit to branch 4.15
in repository https://gitbox.apache.org/repos/asf/cloudstack.git
The following commit(s) were added to refs/heads/4.15 by this push:
new 88337bd server: fix finding pools for volume migration (#4693)
88337bd is described below
commit 88337bdea4ff68ba86fe0a02a707e5265273283a
Author: Abhishek Kumar <[email protected]>
AuthorDate: Thu Feb 25 22:13:50 2021 +0530
server: fix finding pools for volume migration (#4693)
While finding pools for volume migration list following compatible storages:
- all zone-wide storages of the same hypervisor.
- when the volume is attached to a VM, then all storages from the same
cluster as that of VM.
- for detached volume, all storages that belong to clusters of the same
hypervisor.
Fixes #4692
Fixes #4400
---
.../api/storage/StoragePoolAllocator.java | 10 +-
.../storage/datastore/db/PrimaryDataStoreDao.java | 2 +
.../datastore/db/PrimaryDataStoreDaoImpl.java | 13 +++
.../allocator/AbstractStoragePoolAllocator.java | 18 ++--
.../ClusterScopeStoragePoolAllocator.java | 6 +-
.../GarbageCollectingStoragePoolAllocator.java | 4 +-
.../allocator/LocalStoragePoolAllocator.java | 4 +-
.../allocator/UseLocalForRootAllocator.java | 7 +-
.../allocator/ZoneWideStoragePoolAllocator.java | 4 +-
.../allocator/RandomStoragePoolAllocator.java | 2 +-
.../com/cloud/server/ManagementServerImpl.java | 118 +++++++++++++++------
11 files changed, 139 insertions(+), 49 deletions(-)
diff --git
a/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/StoragePoolAllocator.java
b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/StoragePoolAllocator.java
index 46f8f5e..c8fcf5f 100644
---
a/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/StoragePoolAllocator.java
+++
b/engine/api/src/main/java/org/apache/cloudstack/engine/subsystem/api/storage/StoragePoolAllocator.java
@@ -29,6 +29,12 @@ import com.cloud.vm.VirtualMachineProfile;
*/
public interface StoragePoolAllocator extends Adapter {
/**
+ * Overloaded method calls allocateToPool with bypassStorageTypeCheck =
false
+ * and returns a list of pools suitable.
+ **/
+ List<StoragePool> allocateToPool(DiskProfile dskCh, VirtualMachineProfile
vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo);
+
+ /**
* Determines which storage pools are suitable for the guest virtual
machine
* and returns a list of pools suitable.
*
@@ -45,10 +51,12 @@ public interface StoragePoolAllocator extends Adapter {
* @param ExcludeList
* avoid
* @param int returnUpTo (use -1 to return all possible pools)
+ * @param boolean bypassStorageTypeCheck allows bypassing useLocalStorage
check for provided DiskProfile when true
* @return List<StoragePool> List of storage pools that are suitable for
the
* VM
**/
- List<StoragePool> allocateToPool(DiskProfile dskCh, VirtualMachineProfile
vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo);
+ List<StoragePool> allocateToPool(DiskProfile dskCh, VirtualMachineProfile
vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo, boolean
bypassStorageTypeCheck);
+
static int RETURN_UPTO_ALL = -1;
diff --git
a/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java
b/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java
index 59fe3f1..3375c6f 100644
---
a/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java
+++
b/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java
@@ -122,6 +122,8 @@ public interface PrimaryDataStoreDao extends
GenericDao<StoragePoolVO, Long> {
List<StoragePoolVO> listLocalStoragePoolByPath(long datacenterId, String
path);
+ List<StoragePoolVO> findPoolsInClusters(List<Long> clusterIds);
+
void deletePoolTags(long poolId);
List<StoragePoolVO> listChildStoragePoolsInDatastoreCluster(long poolId);
diff --git
a/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java
b/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java
index 7830df5..dfe1a69 100644
---
a/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java
+++
b/engine/schema/src/main/java/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java
@@ -56,6 +56,7 @@ public class PrimaryDataStoreDaoImpl extends
GenericDaoBase<StoragePoolVO, Long>
private final SearchBuilder<StoragePoolVO> DeleteLvmSearch;
private final SearchBuilder<StoragePoolVO> DcLocalStorageSearch;
private final GenericSearchBuilder<StoragePoolVO, Long> StatusCountSearch;
+ private final SearchBuilder<StoragePoolVO> ClustersSearch;
@Inject
private StoragePoolDetailsDao _detailsDao;
@@ -133,6 +134,10 @@ public class PrimaryDataStoreDaoImpl extends
GenericDaoBase<StoragePoolVO, Long>
DcLocalStorageSearch.and("scope",
DcLocalStorageSearch.entity().getScope(), SearchCriteria.Op.EQ);
DcLocalStorageSearch.done();
+ ClustersSearch = createSearchBuilder();
+ ClustersSearch.and("clusterIds",
ClustersSearch.entity().getClusterId(), Op.IN);
+ ClustersSearch.and("status", ClustersSearch.entity().getStatus(),
Op.EQ);
+
}
@Override
@@ -568,4 +573,12 @@ public class PrimaryDataStoreDaoImpl extends
GenericDaoBase<StoragePoolVO, Long>
sc.addAnd("removed", SearchCriteria.Op.NULL);
return getCount(sc);
}
+
+ @Override
+ public List<StoragePoolVO> findPoolsInClusters(List<Long> clusterIds) {
+ SearchCriteria<StoragePoolVO> sc = ClustersSearch.create();
+ sc.setParameters("clusterIds", clusterIds.toArray());
+ sc.setParameters("status", StoragePoolStatus.Up);
+ return listBy(sc);
+ }
}
diff --git
a/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java
b/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java
index cfe32c2..82649b9 100644
---
a/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java
+++
b/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java
@@ -26,15 +26,12 @@ import java.util.Map;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
-import com.cloud.exception.StorageUnavailableException;
-import com.cloud.storage.StoragePoolStatus;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import org.apache.log4j.Logger;
-
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.log4j.Logger;
import com.cloud.capacity.Capacity;
import com.cloud.capacity.dao.CapacityDao;
@@ -42,10 +39,12 @@ import com.cloud.dc.ClusterVO;
import com.cloud.dc.dao.ClusterDao;
import com.cloud.deploy.DeploymentPlan;
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
+import com.cloud.exception.StorageUnavailableException;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.storage.Storage;
import com.cloud.storage.StorageManager;
import com.cloud.storage.StoragePool;
+import com.cloud.storage.StoragePoolStatus;
import com.cloud.storage.StorageUtil;
import com.cloud.storage.Volume;
import com.cloud.storage.dao.VolumeDao;
@@ -87,11 +86,16 @@ public abstract class AbstractStoragePoolAllocator extends
AdapterBase implement
return false;
}
- protected abstract List<StoragePool> select(DiskProfile dskCh,
VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int
returnUpTo);
+ protected abstract List<StoragePool> select(DiskProfile dskCh,
VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int
returnUpTo, boolean bypassStorageTypeCheck);
@Override
public List<StoragePool> allocateToPool(DiskProfile dskCh,
VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int
returnUpTo) {
- List<StoragePool> pools = select(dskCh, vmProfile, plan, avoid,
returnUpTo);
+ return allocateToPool(dskCh, vmProfile, plan, avoid, returnUpTo,
false);
+ }
+
+ @Override
+ public List<StoragePool> allocateToPool(DiskProfile dskCh,
VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int
returnUpTo, boolean bypassStorageTypeCheck) {
+ List<StoragePool> pools = select(dskCh, vmProfile, plan, avoid,
returnUpTo, bypassStorageTypeCheck);
return reorderPools(pools, vmProfile, plan);
}
diff --git
a/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/ClusterScopeStoragePoolAllocator.java
b/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/ClusterScopeStoragePoolAllocator.java
index 12884d5..9967a2c 100644
---
a/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/ClusterScopeStoragePoolAllocator.java
+++
b/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/ClusterScopeStoragePoolAllocator.java
@@ -45,9 +45,13 @@ public class ClusterScopeStoragePoolAllocator extends
AbstractStoragePoolAllocat
DiskOfferingDao _diskOfferingDao;
@Override
- protected List<StoragePool> select(DiskProfile dskCh,
VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int
returnUpTo) {
+ protected List<StoragePool> select(DiskProfile dskCh,
VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int
returnUpTo, boolean bypassStorageTypeCheck) {
s_logger.debug("ClusterScopeStoragePoolAllocator looking for storage
pool");
+ if (!bypassStorageTypeCheck && dskCh.useLocalStorage()) {
+ return null;
+ }
+
List<StoragePool> suitablePools = new ArrayList<StoragePool>();
long dcId = plan.getDataCenterId();
diff --git
a/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/GarbageCollectingStoragePoolAllocator.java
b/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/GarbageCollectingStoragePoolAllocator.java
index b3a1c0d..f02a898 100644
---
a/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/GarbageCollectingStoragePoolAllocator.java
+++
b/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/GarbageCollectingStoragePoolAllocator.java
@@ -47,7 +47,7 @@ public class GarbageCollectingStoragePoolAllocator extends
AbstractStoragePoolAl
boolean _storagePoolCleanupEnabled;
@Override
- public List<StoragePool> select(DiskProfile dskCh, VirtualMachineProfile
vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo) {
+ public List<StoragePool> select(DiskProfile dskCh, VirtualMachineProfile
vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo, boolean
bypassStorageTypeCheck) {
s_logger.debug("GarbageCollectingStoragePoolAllocator looking for
storage pool");
if (!_storagePoolCleanupEnabled) {
s_logger.debug("Storage pool cleanup is not enabled, so
GarbageCollectingStoragePoolAllocator is being skipped.");
@@ -68,7 +68,7 @@ public class GarbageCollectingStoragePoolAllocator extends
AbstractStoragePoolAl
ExcludeList myAvoids =
new ExcludeList(avoid.getDataCentersToAvoid(),
avoid.getPodsToAvoid(), avoid.getClustersToAvoid(), avoid.getHostsToAvoid(),
avoid.getPoolsToAvoid());
- return allocator.allocateToPool(dskCh, vmProfile, plan, myAvoids,
returnUpTo);
+ return allocator.allocateToPool(dskCh, vmProfile, plan, myAvoids,
returnUpTo, bypassStorageTypeCheck);
}
@Override
diff --git
a/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/LocalStoragePoolAllocator.java
b/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/LocalStoragePoolAllocator.java
index 390272e..6fc4ada 100644
---
a/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/LocalStoragePoolAllocator.java
+++
b/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/LocalStoragePoolAllocator.java
@@ -60,10 +60,10 @@ public class LocalStoragePoolAllocator extends
AbstractStoragePoolAllocator {
ConfigurationDao _configDao;
@Override
- protected List<StoragePool> select(DiskProfile dskCh,
VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int
returnUpTo) {
+ protected List<StoragePool> select(DiskProfile dskCh,
VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int
returnUpTo, boolean bypassStorageTypeCheck) {
s_logger.debug("LocalStoragePoolAllocator trying to find storage pool
to fit the vm");
- if (!dskCh.useLocalStorage()) {
+ if (!bypassStorageTypeCheck && !dskCh.useLocalStorage()) {
return null;
}
diff --git
a/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/UseLocalForRootAllocator.java
b/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/UseLocalForRootAllocator.java
index e552a1b..4b150b2 100644
---
a/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/UseLocalForRootAllocator.java
+++
b/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/UseLocalForRootAllocator.java
@@ -39,12 +39,17 @@ public class UseLocalForRootAllocator extends
LocalStoragePoolAllocator implemen
@Override
public List<StoragePool> allocateToPool(DiskProfile dskCh,
VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int
returnUpTo) {
+ return allocateToPool(dskCh, vmProfile, plan, avoid, returnUpTo,
false);
+ }
+
+ @Override
+ public List<StoragePool> allocateToPool(DiskProfile dskCh,
VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int
returnUpTo, boolean bypassStorageTypeCheck) {
DataCenterVO dc = _dcDao.findById(plan.getDataCenterId());
if (!dc.isLocalStorageEnabled()) {
return null;
}
- return super.allocateToPool(dskCh, vmProfile, plan, avoid, returnUpTo);
+ return super.allocateToPool(dskCh, vmProfile, plan, avoid, returnUpTo,
bypassStorageTypeCheck);
}
@Override
diff --git
a/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/ZoneWideStoragePoolAllocator.java
b/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/ZoneWideStoragePoolAllocator.java
index 301704a..e3b2991 100644
---
a/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/ZoneWideStoragePoolAllocator.java
+++
b/engine/storage/src/main/java/org/apache/cloudstack/storage/allocator/ZoneWideStoragePoolAllocator.java
@@ -50,10 +50,10 @@ public class ZoneWideStoragePoolAllocator extends
AbstractStoragePoolAllocator {
@Override
- protected List<StoragePool> select(DiskProfile dskCh,
VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int
returnUpTo) {
+ protected List<StoragePool> select(DiskProfile dskCh,
VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int
returnUpTo, boolean bypassStorageTypeCheck) {
LOGGER.debug("ZoneWideStoragePoolAllocator to find storage pool");
- if (dskCh.useLocalStorage()) {
+ if (!bypassStorageTypeCheck && dskCh.useLocalStorage()) {
return null;
}
diff --git
a/plugins/storage-allocators/random/src/main/java/org/apache/cloudstack/storage/allocator/RandomStoragePoolAllocator.java
b/plugins/storage-allocators/random/src/main/java/org/apache/cloudstack/storage/allocator/RandomStoragePoolAllocator.java
index 6b912fb..eed623a 100644
---
a/plugins/storage-allocators/random/src/main/java/org/apache/cloudstack/storage/allocator/RandomStoragePoolAllocator.java
+++
b/plugins/storage-allocators/random/src/main/java/org/apache/cloudstack/storage/allocator/RandomStoragePoolAllocator.java
@@ -35,7 +35,7 @@ public class RandomStoragePoolAllocator extends
AbstractStoragePoolAllocator {
private static final Logger s_logger =
Logger.getLogger(RandomStoragePoolAllocator.class);
@Override
- public List<StoragePool> select(DiskProfile dskCh, VirtualMachineProfile
vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo) {
+ public List<StoragePool> select(DiskProfile dskCh, VirtualMachineProfile
vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo, boolean
bypassStorageTypeCheck) {
List<StoragePool> suitablePools = new ArrayList<StoragePool>();
diff --git a/server/src/main/java/com/cloud/server/ManagementServerImpl.java
b/server/src/main/java/com/cloud/server/ManagementServerImpl.java
index 8df118d..8f0007a 100644
--- a/server/src/main/java/com/cloud/server/ManagementServerImpl.java
+++ b/server/src/main/java/com/cloud/server/ManagementServerImpl.java
@@ -27,6 +27,7 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.Set;
import java.util.TimeZone;
import java.util.concurrent.Executors;
@@ -40,7 +41,6 @@ import javax.crypto.spec.SecretKeySpec;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
-import com.cloud.storage.Storage;
import org.apache.cloudstack.acl.ControlledEntity;
import org.apache.cloudstack.affinity.AffinityGroupProcessor;
import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
@@ -573,6 +573,8 @@ import com.cloud.alert.AlertManager;
import com.cloud.alert.AlertVO;
import com.cloud.alert.dao.AlertDao;
import com.cloud.api.ApiDBUtils;
+import com.cloud.api.query.dao.StoragePoolJoinDao;
+import com.cloud.api.query.vo.StoragePoolJoinVO;
import com.cloud.capacity.Capacity;
import com.cloud.capacity.CapacityVO;
import com.cloud.capacity.dao.CapacityDao;
@@ -657,8 +659,10 @@ import com.cloud.storage.GuestOSHypervisorVO;
import com.cloud.storage.GuestOSVO;
import com.cloud.storage.GuestOsCategory;
import com.cloud.storage.ScopeType;
+import com.cloud.storage.Storage;
import com.cloud.storage.StorageManager;
import com.cloud.storage.StoragePool;
+import com.cloud.storage.StoragePoolStatus;
import com.cloud.storage.Volume;
import com.cloud.storage.VolumeApiServiceImpl;
import com.cloud.storage.VolumeVO;
@@ -789,6 +793,8 @@ public class ManagementServerImpl extends ManagerBase
implements ManagementServe
@Inject
private PrimaryDataStoreDao _poolDao;
@Inject
+ private StoragePoolJoinDao _poolJoinDao;
+ @Inject
private NetworkDao _networkDao;
@Inject
private StorageManager _storageMgr;
@@ -1145,7 +1151,7 @@ public class ManagementServerImpl extends ManagerBase
implements ManagementServe
return new Pair<List<? extends Cluster>, Integer>(result.first(),
result.second());
}
- private HypervisorType getHypervisorType(VMInstanceVO vm, StoragePool
srcVolumePool, VirtualMachineProfile profile) {
+ private HypervisorType getHypervisorType(VMInstanceVO vm, StoragePool
srcVolumePool) {
HypervisorType type = null;
if (vm == null) {
StoragePoolVO poolVo = _poolDao.findById(srcVolumePool.getId());
@@ -1155,18 +1161,13 @@ public class ManagementServerImpl extends ManagerBase
implements ManagementServe
ClusterVO cluster = _clusterDao.findById(clusterId);
type = cluster.getHypervisorType();
}
- } else if (ScopeType.ZONE.equals(poolVo.getScope())) {
- Long zoneId = poolVo.getDataCenterId();
- if (zoneId != null) {
- DataCenterVO dc = _dcDao.findById(zoneId);
- }
}
if (null == type) {
type = srcVolumePool.getHypervisor();
}
} else {
- type = profile.getHypervisorType();
+ type = vm.getHypervisorType();
}
return type;
}
@@ -1488,12 +1489,17 @@ public class ManagementServerImpl extends ManagerBase
implements ManagementServe
}
StoragePool srcVolumePool = _poolDao.findById(volume.getPoolId());
- allPools =
getAllStoragePoolCompatileWithVolumeSourceStoragePool(srcVolumePool);
+ HypervisorType hypervisorType = getHypervisorType(vm, srcVolumePool);
+ Pair<Host, List<Cluster>> hostClusterPair =
getVolumeVmHostClusters(srcVolumePool, vm, hypervisorType);
+ Host vmHost = hostClusterPair.first();
+ List<Cluster> clusters = hostClusterPair.second();
+ allPools =
getAllStoragePoolCompatibleWithVolumeSourceStoragePool(srcVolumePool,
hypervisorType, clusters);
allPools.remove(srcVolumePool);
if (vm != null) {
- suitablePools = findAllSuitableStoragePoolsForVm(volume, vm,
srcVolumePool);
+ suitablePools = findAllSuitableStoragePoolsForVm(volume, vm,
vmHost, srcVolumePool,
+ CollectionUtils.isNotEmpty(clusters) ? clusters.get(0) :
null, hypervisorType);
} else {
- suitablePools = allPools;
+ suitablePools =
findAllSuitableStoragePoolsForDetachedVolume(volume, allPools);
}
List<StoragePool> avoidPools = new ArrayList<>();
if (srcVolumePool.getParent() != 0L) {
@@ -1520,6 +1526,30 @@ public class ManagementServerImpl extends ManagerBase
implements ManagementServe
}
}
+ private Pair<Host, List<Cluster>> getVolumeVmHostClusters(StoragePool
srcVolumePool, VirtualMachine vm, HypervisorType hypervisorType) {
+ Host host = null;
+ List<Cluster> clusters = new ArrayList<>();
+ Long clusterId = srcVolumePool.getClusterId();
+ if (vm != null) {
+ Long hostId = vm.getHostId();
+ if (hostId == null) {
+ hostId = vm.getLastHostId();
+ }
+ if (hostId != null) {
+ host = _hostDao.findById(hostId);
+ }
+ }
+ if (clusterId == null && host != null) {
+ clusterId = host.getClusterId();
+ }
+ if (clusterId != null && vm != null) {
+ clusters.add(_clusterDao.findById(clusterId));
+ } else {
+
clusters.addAll(_clusterDao.listByDcHyType(srcVolumePool.getDataCenterId(),
hypervisorType.toString()));
+ }
+ return new Pair<>(host, clusters);
+ }
+
/**
* This method looks for all storage pools that are compatible with the
given volume.
* <ul>
@@ -1527,15 +1557,18 @@ public class ManagementServerImpl extends ManagerBase
implements ManagementServe
* <li>We also all storage available filtering by data center, pod and
cluster as the current storage pool used by the given volume.</li>
* </ul>
*/
- private List<? extends StoragePool>
getAllStoragePoolCompatileWithVolumeSourceStoragePool(StoragePool
srcVolumePool) {
+ private List<? extends StoragePool>
getAllStoragePoolCompatibleWithVolumeSourceStoragePool(StoragePool
srcVolumePool, HypervisorType hypervisorType, List<Cluster> clusters) {
List<StoragePoolVO> storagePools = new ArrayList<>();
- List<StoragePoolVO> zoneWideStoragePools =
_poolDao.findZoneWideStoragePoolsByTags(srcVolumePool.getDataCenterId(), null);
+ List<StoragePoolVO> zoneWideStoragePools =
_poolDao.findZoneWideStoragePoolsByHypervisor(srcVolumePool.getDataCenterId(),
hypervisorType);
if (CollectionUtils.isNotEmpty(zoneWideStoragePools)) {
storagePools.addAll(zoneWideStoragePools);
}
- List<StoragePoolVO> clusterAndLocalStoragePools =
_poolDao.listBy(srcVolumePool.getDataCenterId(), srcVolumePool.getPodId(),
srcVolumePool.getClusterId(), null);
- if (CollectionUtils.isNotEmpty(clusterAndLocalStoragePools)) {
- storagePools.addAll(clusterAndLocalStoragePools);
+ if (CollectionUtils.isNotEmpty(clusters)) {
+ List<Long> clusterIds =
clusters.stream().map(Cluster::getId).collect(Collectors.toList());
+ List<StoragePoolVO> clusterAndLocalStoragePools =
_poolDao.findPoolsInClusters(clusterIds);
+ if (CollectionUtils.isNotEmpty(clusterAndLocalStoragePools)) {
+ storagePools.addAll(clusterAndLocalStoragePools);
+ }
}
return storagePools;
}
@@ -1547,35 +1580,33 @@ public class ManagementServerImpl extends ManagerBase
implements ManagementServe
*
* Side note: the idea behind this method is to provide power for
administrators of manually overriding deployments defined by CloudStack.
*/
- private List<StoragePool> findAllSuitableStoragePoolsForVm(final VolumeVO
volume, VMInstanceVO vm, StoragePool srcVolumePool) {
+ private List<StoragePool> findAllSuitableStoragePoolsForVm(final VolumeVO
volume, VMInstanceVO vm, Host vmHost, StoragePool srcVolumePool, Cluster
srcCluster, HypervisorType hypervisorType) {
List<StoragePool> suitablePools = new ArrayList<>();
-
- HostVO host = _hostDao.findById(vm.getHostId());
- if (host == null) {
- host = _hostDao.findById(vm.getLastHostId());
- }
-
ExcludeList avoid = new ExcludeList();
avoid.addPool(srcVolumePool.getId());
-
- DataCenterDeployment plan = new
DataCenterDeployment(volume.getDataCenterId(), srcVolumePool.getPodId(),
srcVolumePool.getClusterId(), null, null, null);
+ Long clusterId = null;
+ Long podId = null;
+ if (srcCluster != null) {
+ clusterId = srcCluster.getId();
+ podId = srcCluster.getPodId();
+ }
+ DataCenterDeployment plan = new
DataCenterDeployment(volume.getDataCenterId(), podId, clusterId,
+ null, null, null, null);
VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm);
// OfflineVmwareMigration: vm might be null here; deal!
- HypervisorType type = getHypervisorType(vm, srcVolumePool, profile);
DiskOfferingVO diskOffering =
_diskOfferingDao.findById(volume.getDiskOfferingId());
- //This is an override mechanism so we can list the possible local
storage pools that a volume in a shared pool might be able to be migrated to
- DiskProfile diskProfile = new DiskProfile(volume, diskOffering, type);
- diskProfile.setUseLocalStorage(true);
+ DiskProfile diskProfile = new DiskProfile(volume, diskOffering,
hypervisorType);
for (StoragePoolAllocator allocator : _storagePoolAllocators) {
- List<StoragePool> pools = allocator.allocateToPool(diskProfile,
profile, plan, avoid, StoragePoolAllocator.RETURN_UPTO_ALL);
+ List<StoragePool> pools = allocator.allocateToPool(diskProfile,
profile, plan, avoid, StoragePoolAllocator.RETURN_UPTO_ALL, true);
if (CollectionUtils.isEmpty(pools)) {
continue;
}
for (StoragePool pool : pools) {
- boolean isLocalPoolSameHostAsSourcePool = pool.isLocal() &&
StringUtils.equals(host.getPrivateIpAddress(), pool.getHostAddress());
- if (isLocalPoolSameHostAsSourcePool || pool.isShared()) {
+ boolean isLocalPoolSameHostAsVmHost = pool.isLocal() &&
+ (vmHost == null ||
StringUtils.equals(vmHost.getPrivateIpAddress(), pool.getHostAddress()));
+ if (isLocalPoolSameHostAsVmHost || pool.isShared()) {
suitablePools.add(pool);
}
@@ -1584,6 +1615,29 @@ public class ManagementServerImpl extends ManagerBase
implements ManagementServe
return suitablePools;
}
+ private List<StoragePool>
findAllSuitableStoragePoolsForDetachedVolume(Volume volume, List<? extends
StoragePool> allPools) {
+ List<StoragePool> suitablePools = new ArrayList<>();
+ if (CollectionUtils.isEmpty(allPools)) {
+ return suitablePools;
+ }
+ DiskOfferingVO diskOffering =
_diskOfferingDao.findById(volume.getDiskOfferingId());
+ List<String> tags = new ArrayList<>();
+ String[] tagsArray = diskOffering.getTagsArray();
+ if (tagsArray != null && tagsArray.length > 0) {
+ tags = Arrays.asList(tagsArray);
+ }
+ Long[] poolIds =
allPools.stream().map(StoragePool::getId).toArray(Long[]::new);
+ List<StoragePoolJoinVO> pools = _poolJoinDao.searchByIds(poolIds);
+ for (StoragePoolJoinVO storagePool : pools) {
+ if (StoragePoolStatus.Up.equals(storagePool.getStatus()) &&
+ (CollectionUtils.isEmpty(tags) ||
tags.contains(storagePool.getTag()))) {
+ Optional<? extends StoragePool> match =
allPools.stream().filter(x -> x.getId() == storagePool.getId()).findFirst();
+ match.ifPresent(suitablePools::add);
+ }
+ }
+ return suitablePools;
+ }
+
private Pair<List<HostVO>, Integer> searchForServers(final Long
startIndex, final Long pageSize, final Object name, final Object type,
final Object state, final Object zone, final Object pod, final Object
cluster, final Object id, final Object keyword,
final Object resourceState, final Object haHosts, final Object
hypervisorType, final Object hypervisorVersion, final Object... excludes) {