CLOUDSTACK-4681: data disk with local disk offering are geting created on shared storage

The cluster and zone wide storage pool allocators returned shared pools even for volumes meant to be on local storage pool.
If the VM uses local disk then cluster and zone storage allocators should not handle it and return null or empty list.

Also fixed the deployment planner to avoid a cluster if
a. avoid set returned by storage pool allocators is empty OR
b. all local or shared pools in a cluster are in avoid state

Conflicts:
	engine/storage/src/org/apache/cloudstack/storage/allocator/ClusterScopeStoragePoolAllocator.java
	engine/storage/src/org/apache/cloudstack/storage/allocator/ZoneWideStoragePoolAllocator.java
This commit is contained in:
Koushik Das 2013-10-18 16:34:47 +05:30
parent a92095a4a6
commit 0c1800f70f
4 changed files with 64 additions and 38 deletions

View File

@ -51,8 +51,13 @@ public class ClusterScopeStoragePoolAllocator extends AbstractStoragePoolAllocat
@Override @Override
protected List<StoragePool> select(DiskProfile dskCh, VirtualMachineProfile vmProfile, protected List<StoragePool> select(DiskProfile dskCh, VirtualMachineProfile vmProfile,
DeploymentPlan plan, ExcludeList avoid, int returnUpTo) { DeploymentPlan plan, ExcludeList avoid, int returnUpTo) {
s_logger.debug("ClusterScopeStoragePoolAllocator looking for storage pool"); s_logger.debug("ClusterScopeStoragePoolAllocator looking for storage pool");
if (dskCh.useLocalStorage()) {
// cluster wide allocator should bail out in case of local disk
return null;
}
List<StoragePool> suitablePools = new ArrayList<StoragePool>(); List<StoragePool> suitablePools = new ArrayList<StoragePool>();
long dcId = plan.getDataCenterId(); long dcId = plan.getDataCenterId();
@ -84,9 +89,7 @@ public class ClusterScopeStoragePoolAllocator extends AbstractStoragePoolAllocat
if (pools.size() == 0) { if (pools.size() == 0) {
if (s_logger.isDebugEnabled()) { if (s_logger.isDebugEnabled()) {
String storageType = dskCh.useLocalStorage() ? ServiceOffering.StorageType.local.toString() s_logger.debug("No storage pools available for " + ServiceOffering.StorageType.shared.toString() + " volume allocation, returning");
: ServiceOffering.StorageType.shared.toString();
s_logger.debug("No storage pools available for " + storageType + " volume allocation, returning");
} }
return suitablePools; return suitablePools;
} }
@ -95,16 +98,16 @@ public class ClusterScopeStoragePoolAllocator extends AbstractStoragePoolAllocat
if (suitablePools.size() == returnUpTo) { if (suitablePools.size() == returnUpTo) {
break; break;
} }
StoragePool pol = (StoragePool) dataStoreMgr.getPrimaryDataStore(pool.getId()); StoragePool storagePool = (StoragePool) dataStoreMgr.getPrimaryDataStore(pool.getId());
if (filter(avoid, pol, dskCh, plan)) { if (filter(avoid, storagePool, dskCh, plan)) {
suitablePools.add(pol); suitablePools.add(storagePool);
} else { } else {
avoid.addPool(pool.getId()); avoid.addPool(pool.getId());
} }
} }
if (s_logger.isDebugEnabled()) { if (s_logger.isDebugEnabled()) {
s_logger.debug("FirstFitStoragePoolAllocator returning " + suitablePools.size() + " suitable storage pools"); s_logger.debug("ClusterScopeStoragePoolAllocator returning " + suitablePools.size() + " suitable storage pools");
} }
return suitablePools; return suitablePools;

View File

@ -68,25 +68,24 @@ public class LocalStoragePoolAllocator extends AbstractStoragePoolAllocator {
@Override @Override
protected List<StoragePool> select(DiskProfile dskCh, VirtualMachineProfile vmProfile, protected List<StoragePool> select(DiskProfile dskCh, VirtualMachineProfile vmProfile,
DeploymentPlan plan, ExcludeList avoid, int returnUpTo) { DeploymentPlan plan, ExcludeList avoid, int returnUpTo) {
List<StoragePool> suitablePools = new ArrayList<StoragePool>();
s_logger.debug("LocalStoragePoolAllocator trying to find storage pool to fit the vm"); s_logger.debug("LocalStoragePoolAllocator trying to find storage pool to fit the vm");
if (!dskCh.useLocalStorage()) { if (!dskCh.useLocalStorage()) {
return suitablePools; return null;
} }
List<StoragePool> suitablePools = new ArrayList<StoragePool>();
// data disk and host identified from deploying vm (attach volume case) // data disk and host identified from deploying vm (attach volume case)
if (dskCh.getType() == Volume.Type.DATADISK && plan.getHostId() != null) { if (dskCh.getType() == Volume.Type.DATADISK && plan.getHostId() != null) {
List<StoragePoolHostVO> hostPools = _poolHostDao.listByHostId(plan.getHostId()); List<StoragePoolHostVO> hostPools = _poolHostDao.listByHostId(plan.getHostId());
for (StoragePoolHostVO hostPool : hostPools) { for (StoragePoolHostVO hostPool : hostPools) {
StoragePoolVO pool = _storagePoolDao.findById(hostPool.getPoolId()); StoragePoolVO pool = _storagePoolDao.findById(hostPool.getPoolId());
if (pool != null && pool.isLocal()) { if (pool != null && pool.isLocal()) {
StoragePool pol = (StoragePool) this.dataStoreMgr.getPrimaryDataStore(pool.getId()); StoragePool storagePool = (StoragePool) this.dataStoreMgr.getPrimaryDataStore(pool.getId());
if (filter(avoid, pol, dskCh, plan)) { if (filter(avoid, storagePool, dskCh, plan)) {
s_logger.debug("Found suitable local storage pool " + pool.getId() + ", adding to list"); s_logger.debug("Found suitable local storage pool " + pool.getId() + ", adding to list");
suitablePools.add(pol); suitablePools.add(storagePool);
} else { } else {
avoid.addPool(pool.getId()); avoid.addPool(pool.getId());
} }
@ -107,9 +106,9 @@ public class LocalStoragePoolAllocator extends AbstractStoragePoolAllocator {
if (suitablePools.size() == returnUpTo) { if (suitablePools.size() == returnUpTo) {
break; break;
} }
StoragePool pol = (StoragePool) this.dataStoreMgr.getPrimaryDataStore(pool.getId()); StoragePool storagePool = (StoragePool) this.dataStoreMgr.getPrimaryDataStore(pool.getId());
if (filter(avoid, pol, dskCh, plan)) { if (filter(avoid, storagePool, dskCh, plan)) {
suitablePools.add(pol); suitablePools.add(storagePool);
} else { } else {
avoid.addPool(pool.getId()); avoid.addPool(pool.getId());
} }

View File

@ -57,21 +57,25 @@ public class ZoneWideStoragePoolAllocator extends AbstractStoragePoolAllocator {
storageMgr.storagePoolHasEnoughSpace(requestVolumes, pool); storageMgr.storagePoolHasEnoughSpace(requestVolumes, pool);
} }
@Override
protected List<StoragePool> select(DiskProfile dskCh, @Override
VirtualMachineProfile vmProfile, protected List<StoragePool> select(DiskProfile dskCh,
DeploymentPlan plan, ExcludeList avoid, int returnUpTo) { VirtualMachineProfile vmProfile,
s_logger.debug("ZoneWideStoragePoolAllocator to find storage pool"); DeploymentPlan plan, ExcludeList avoid, int returnUpTo) {
List<StoragePool> suitablePools = new ArrayList<StoragePool>(); s_logger.debug("ZoneWideStoragePoolAllocator to find storage pool");
if (dskCh.useLocalStorage()) {
return null;
}
List<StoragePool> suitablePools = new ArrayList<StoragePool>();
List<StoragePoolVO> storagePools = _storagePoolDao.findZoneWideStoragePoolsByTags(plan.getDataCenterId(), dskCh.getTags()); List<StoragePoolVO> storagePools = _storagePoolDao.findZoneWideStoragePoolsByTags(plan.getDataCenterId(), dskCh.getTags());
if (storagePools == null) { if (storagePools == null) {
storagePools = new ArrayList<StoragePoolVO>(); storagePools = new ArrayList<StoragePoolVO>();
} }
List<StoragePoolVO> anyHypervisorStoragePools = new ArrayList<StoragePoolVO>(); List<StoragePoolVO> anyHypervisorStoragePools = new ArrayList<StoragePoolVO>();
for (StoragePoolVO storagePool : storagePools) { for (StoragePoolVO storagePool : storagePools) {
if (HypervisorType.Any.equals(storagePool.getHypervisor())) { if (HypervisorType.Any.equals(storagePool.getHypervisor())) {
anyHypervisorStoragePools.add(storagePool); anyHypervisorStoragePools.add(storagePool);
@ -79,9 +83,7 @@ public class ZoneWideStoragePoolAllocator extends AbstractStoragePoolAllocator {
} }
List<StoragePoolVO> storagePoolsByHypervisor = _storagePoolDao.findZoneWideStoragePoolsByHypervisor(plan.getDataCenterId(), dskCh.getHypervisorType()); List<StoragePoolVO> storagePoolsByHypervisor = _storagePoolDao.findZoneWideStoragePoolsByHypervisor(plan.getDataCenterId(), dskCh.getHypervisorType());
storagePools.retainAll(storagePoolsByHypervisor); storagePools.retainAll(storagePoolsByHypervisor);
storagePools.addAll(anyHypervisorStoragePools); storagePools.addAll(anyHypervisorStoragePools);
// add remaining pools in zone, that did not match tags, to avoid set // add remaining pools in zone, that did not match tags, to avoid set
@ -95,15 +97,16 @@ public class ZoneWideStoragePoolAllocator extends AbstractStoragePoolAllocator {
if (suitablePools.size() == returnUpTo) { if (suitablePools.size() == returnUpTo) {
break; break;
} }
StoragePool pol = (StoragePool) this.dataStoreMgr.getPrimaryDataStore(storage.getId()); StoragePool storagePool = (StoragePool) this.dataStoreMgr.getPrimaryDataStore(storage.getId());
if (filter(avoid, pol, dskCh, plan)) { if (filter(avoid, storagePool, dskCh, plan)) {
suitablePools.add(pol); suitablePools.add(storagePool);
} else { } else {
avoid.addPool(pol.getId()); avoid.addPool(storagePool.getId());
} }
} }
return suitablePools; return suitablePools;
} }
@Override @Override
protected List<StoragePool> reorderPoolsByNumberOfVolumes(DeploymentPlan plan, List<StoragePool> pools, protected List<StoragePool> reorderPoolsByNumberOfVolumes(DeploymentPlan plan, List<StoragePool> pools,
Account account) { Account account) {

View File

@ -932,15 +932,36 @@ public class DeploymentPlanningManagerImpl extends ManagerBase implements Deploy
if (!allocatorAvoidOutput.shouldAvoid(host)) { if (!allocatorAvoidOutput.shouldAvoid(host)) {
// there's some host in the cluster that is not yet in avoid set // there's some host in the cluster that is not yet in avoid set
avoidAllHosts = false; avoidAllHosts = false;
break;
} }
} }
List<StoragePoolVO> allPoolsInCluster = _storagePoolDao.findPoolsByTags(clusterVO.getDataCenterId(), // Cluster can be put in avoid set in following scenarios:
clusterVO.getPodId(), clusterVO.getId(), null); // 1. If storage allocators haven't put any pools in avoid set means either no pools in cluster
for (StoragePoolVO pool : allPoolsInCluster) { // or pools not suitable for the allocators to handle.
if (!allocatorAvoidOutput.shouldAvoid(pool)) { // 2. If all 'shared' or 'local' pools are in avoid set
// there's some pool in the cluster that is not yet in avoid set if (allocatorAvoidOutput.getPoolsToAvoid() != null && !allocatorAvoidOutput.getPoolsToAvoid().isEmpty()) {
avoidAllPools = false; // check shared pools
List<StoragePoolVO> allPoolsInCluster = _storagePoolDao.findPoolsByTags(clusterVO.getDataCenterId(),
clusterVO.getPodId(), clusterVO.getId(), null);
for (StoragePoolVO pool : allPoolsInCluster) {
if (!allocatorAvoidOutput.shouldAvoid(pool)) {
// there's some pool in the cluster that is not yet in avoid set
avoidAllPools = false;
break;
}
}
if (avoidAllPools) {
// check local pools
List<StoragePoolVO> allLocalPoolsInCluster = _storagePoolDao.findLocalStoragePoolsByTags(clusterVO.getDataCenterId(),
clusterVO.getPodId(), clusterVO.getId(), null);
for (StoragePoolVO pool : allLocalPoolsInCluster) {
if (!allocatorAvoidOutput.shouldAvoid(pool)) {
// there's some pool in the cluster that is not yet in avoid set
avoidAllPools = false;
break;
}
}
} }
} }