mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
CLOUDSTACK-8386: CS is returning sec. storage even if it is full and there are other sec. storage with free space.
This commit is contained in:
parent
8f4abbc7bd
commit
30604e973a
@ -18,7 +18,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.cloudstack.storage.cache.allocator;
|
package org.apache.cloudstack.storage.cache.allocator;
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
@ -33,7 +32,9 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
|
|||||||
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
|
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
|
import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
|
||||||
import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager;
|
import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager;
|
||||||
|
import org.apache.cloudstack.storage.image.datastore.ImageStoreProviderManager;
|
||||||
|
|
||||||
|
import com.cloud.server.StatsCollector;
|
||||||
import com.cloud.storage.ScopeType;
|
import com.cloud.storage.ScopeType;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@ -43,6 +44,10 @@ public class StorageCacheRandomAllocator implements StorageCacheAllocator {
|
|||||||
DataStoreManager dataStoreMgr;
|
DataStoreManager dataStoreMgr;
|
||||||
@Inject
|
@Inject
|
||||||
ObjectInDataStoreManager objectInStoreMgr;
|
ObjectInDataStoreManager objectInStoreMgr;
|
||||||
|
@Inject
|
||||||
|
ImageStoreProviderManager imageStoreMgr;
|
||||||
|
@Inject
|
||||||
|
StatsCollector statsCollector;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DataStore getCacheStore(Scope scope) {
|
public DataStore getCacheStore(Scope scope) {
|
||||||
@ -57,8 +62,7 @@ public class StorageCacheRandomAllocator implements StorageCacheAllocator {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Collections.shuffle(cacheStores);
|
return imageStoreMgr.getImageStore(cacheStores);
|
||||||
return cacheStores.get(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -78,18 +82,12 @@ public class StorageCacheRandomAllocator implements StorageCacheAllocator {
|
|||||||
if (cacheStores.size() > 1) {
|
if (cacheStores.size() > 1) {
|
||||||
for (DataStore store : cacheStores) {
|
for (DataStore store : cacheStores) {
|
||||||
DataObjectInStore obj = objectInStoreMgr.findObject(data, store);
|
DataObjectInStore obj = objectInStoreMgr.findObject(data, store);
|
||||||
if (obj != null && obj.getState() == ObjectInDataStoreStateMachine.State.Ready) {
|
if (obj != null && obj.getState() == ObjectInDataStoreStateMachine.State.Ready && statsCollector.imageStoreHasEnoughCapacity(store)) {
|
||||||
s_logger.debug("pick the cache store " + store.getId() + " where data is already there");
|
s_logger.debug("pick the cache store " + store.getId() + " where data is already there");
|
||||||
return store;
|
return store;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// otherwise, just random pick one
|
|
||||||
Collections.shuffle(cacheStores);
|
|
||||||
}
|
}
|
||||||
return cacheStores.get(0);
|
return imageStoreMgr.getImageStore(cacheStores);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,7 +19,9 @@
|
|||||||
package org.apache.cloudstack.storage.image.manager;
|
package org.apache.cloudstack.storage.image.manager;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@ -41,6 +43,7 @@ import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity;
|
|||||||
import org.apache.cloudstack.storage.image.datastore.ImageStoreProviderManager;
|
import org.apache.cloudstack.storage.image.datastore.ImageStoreProviderManager;
|
||||||
import org.apache.cloudstack.storage.image.store.ImageStoreImpl;
|
import org.apache.cloudstack.storage.image.store.ImageStoreImpl;
|
||||||
|
|
||||||
|
import com.cloud.server.StatsCollector;
|
||||||
import com.cloud.storage.ScopeType;
|
import com.cloud.storage.ScopeType;
|
||||||
import com.cloud.storage.dao.VMTemplateDao;
|
import com.cloud.storage.dao.VMTemplateDao;
|
||||||
|
|
||||||
@ -53,6 +56,8 @@ public class ImageStoreProviderManagerImpl implements ImageStoreProviderManager
|
|||||||
VMTemplateDao imageDataDao;
|
VMTemplateDao imageDataDao;
|
||||||
@Inject
|
@Inject
|
||||||
DataStoreProviderManager providerManager;
|
DataStoreProviderManager providerManager;
|
||||||
|
@Inject
|
||||||
|
StatsCollector _statsCollector;
|
||||||
Map<String, ImageStoreDriver> driverMaps;
|
Map<String, ImageStoreDriver> driverMaps;
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
@ -137,4 +142,21 @@ public class ImageStoreProviderManagerImpl implements ImageStoreProviderManager
|
|||||||
}
|
}
|
||||||
return imageStores;
|
return imageStores;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataStore getImageStore(List<DataStore> imageStores) {
|
||||||
|
if (imageStores.size() > 1) {
|
||||||
|
Collections.shuffle(imageStores); // Randomize image store list.
|
||||||
|
Iterator<DataStore> i = imageStores.iterator();
|
||||||
|
DataStore imageStore = null;
|
||||||
|
while(i.hasNext()) {
|
||||||
|
imageStore = i.next();
|
||||||
|
// Return image store if used percentage is less then threshold value i.e. 90%.
|
||||||
|
if (_statsCollector.imageStoreHasEnoughCapacity(imageStore)) {
|
||||||
|
return imageStore;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return imageStores.get(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,7 +18,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.cloudstack.storage.datastore;
|
package org.apache.cloudstack.storage.datastore;
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
@ -79,8 +78,7 @@ public class DataStoreManagerImpl implements DataStoreManager {
|
|||||||
if (stores == null || stores.size() == 0) {
|
if (stores == null || stores.size() == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Collections.shuffle(stores);
|
return imageDataStoreMgr.getImageStore(stores);
|
||||||
return stores.get(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -112,8 +110,7 @@ public class DataStoreManagerImpl implements DataStoreManager {
|
|||||||
if (stores == null || stores.size() == 0) {
|
if (stores == null || stores.size() == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Collections.shuffle(stores);
|
return imageDataStoreMgr.getImageStore(stores);
|
||||||
return stores.get(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -41,4 +41,6 @@ public interface ImageStoreProviderManager {
|
|||||||
List<DataStore> listImageCacheStores(Scope scope);
|
List<DataStore> listImageCacheStores(Scope scope);
|
||||||
|
|
||||||
boolean registerDriver(String uuid, ImageStoreDriver driver);
|
boolean registerDriver(String uuid, ImageStoreDriver driver);
|
||||||
|
|
||||||
|
DataStore getImageStore(List<DataStore> imageStores);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -212,6 +212,7 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc
|
|||||||
long autoScaleStatsInterval = -1L;
|
long autoScaleStatsInterval = -1L;
|
||||||
int vmDiskStatsInterval = 0;
|
int vmDiskStatsInterval = 0;
|
||||||
List<Long> hostIds = null;
|
List<Long> hostIds = null;
|
||||||
|
private double _imageStoreCapacityThreshold = 0.90;
|
||||||
|
|
||||||
String externalStatsPrefix = "";
|
String externalStatsPrefix = "";
|
||||||
String externalStatsHost = null;
|
String externalStatsHost = null;
|
||||||
@ -1045,6 +1046,14 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean imageStoreHasEnoughCapacity(DataStore imageStore) {
|
||||||
|
StorageStats imageStoreStats = _storageStats.get(imageStore.getId());
|
||||||
|
if (imageStoreStats != null && (imageStoreStats.getByteUsed()/(imageStoreStats.getCapacityBytes()*1.0)) <= _imageStoreCapacityThreshold) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public StorageStats getStorageStats(long id) {
|
public StorageStats getStorageStats(long id) {
|
||||||
return _storageStats.get(id);
|
return _storageStats.get(id);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -60,6 +60,7 @@ import com.cloud.event.UsageEventUtils;
|
|||||||
import com.cloud.exception.InvalidParameterValueException;
|
import com.cloud.exception.InvalidParameterValueException;
|
||||||
import com.cloud.exception.ResourceAllocationException;
|
import com.cloud.exception.ResourceAllocationException;
|
||||||
import com.cloud.org.Grouping;
|
import com.cloud.org.Grouping;
|
||||||
|
import com.cloud.server.StatsCollector;
|
||||||
import com.cloud.storage.ScopeType;
|
import com.cloud.storage.ScopeType;
|
||||||
import com.cloud.storage.Storage.ImageFormat;
|
import com.cloud.storage.Storage.ImageFormat;
|
||||||
import com.cloud.storage.Storage.TemplateType;
|
import com.cloud.storage.Storage.TemplateType;
|
||||||
@ -83,8 +84,10 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase {
|
|||||||
DownloadMonitor _downloadMonitor;
|
DownloadMonitor _downloadMonitor;
|
||||||
@Inject
|
@Inject
|
||||||
AgentManager _agentMgr;
|
AgentManager _agentMgr;
|
||||||
|
@Inject
|
||||||
@Inject TemplateDataStoreDao templateDataStoreDao;
|
StatsCollector _statsCollector;
|
||||||
|
@Inject
|
||||||
|
TemplateDataStoreDao templateDataStoreDao;
|
||||||
@Inject
|
@Inject
|
||||||
DataStoreManager storeMgr;
|
DataStoreManager storeMgr;
|
||||||
@Inject
|
@Inject
|
||||||
@ -164,13 +167,17 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if image store has enough capacity for template
|
||||||
|
if (!_statsCollector.imageStoreHasEnoughCapacity(imageStore)) {
|
||||||
|
s_logger.info("Image store doesn't has enough capacity, so skip downloading template to this image store " + imageStore.getId());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
// We want to download private template to one of the image store in a zone
|
// We want to download private template to one of the image store in a zone
|
||||||
if(isPrivateTemplate(template) && zoneSet.contains(zoneId)){
|
if(isPrivateTemplate(template) && zoneSet.contains(zoneId)){
|
||||||
continue;
|
continue;
|
||||||
}else {
|
}else {
|
||||||
zoneSet.add(zoneId);
|
zoneSet.add(zoneId);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TemplateInfo tmpl = imageFactory.getTemplate(template.getId(), imageStore);
|
TemplateInfo tmpl = imageFactory.getTemplate(template.getId(), imageStore);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user