-
Notifications
You must be signed in to change notification settings - Fork 1.3k
engine, server, services: fix for respecting secondary storage threshold limit #3480
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
ac01241
dec6602
410c1bd
9b8c8d2
f3be50b
e4966ea
e9e0415
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,17 +20,14 @@ | |
|
|
||
| import java.util.ArrayList; | ||
| import java.util.Collections; | ||
| import java.util.Comparator; | ||
| import java.util.HashMap; | ||
| import java.util.Iterator; | ||
| import java.util.List; | ||
| import java.util.Map; | ||
|
|
||
| import javax.annotation.PostConstruct; | ||
| import javax.inject.Inject; | ||
|
|
||
| import org.apache.log4j.Logger; | ||
| import org.springframework.stereotype.Component; | ||
|
|
||
| import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; | ||
| import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManager; | ||
| import org.apache.cloudstack.engine.subsystem.api.storage.ImageStoreProvider; | ||
|
|
@@ -42,6 +39,8 @@ | |
| import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity; | ||
| import org.apache.cloudstack.storage.image.datastore.ImageStoreProviderManager; | ||
| import org.apache.cloudstack.storage.image.store.ImageStoreImpl; | ||
| import org.apache.log4j.Logger; | ||
| import org.springframework.stereotype.Component; | ||
|
|
||
| import com.cloud.server.StatsCollector; | ||
| import com.cloud.storage.ScopeType; | ||
|
|
@@ -144,19 +143,56 @@ public List<DataStore> listImageCacheStores(Scope scope) { | |
| } | ||
|
|
||
| @Override | ||
| public DataStore getImageStore(List<DataStore> imageStores) { | ||
| public DataStore getRandomImageStore(List<DataStore> imageStores) { | ||
| if (imageStores.size() > 1) { | ||
| Collections.shuffle(imageStores); | ||
| } | ||
| return imageStores.get(0); | ||
| } | ||
|
|
||
| @Override | ||
| public DataStore getImageStoreWithFreeCapacity(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(); | ||
| imageStores.sort(new Comparator<DataStore>() { // Sort data stores based on free capacity | ||
| @Override | ||
| public int compare(DataStore store1, DataStore store2) { | ||
| return Long.compare(_statsCollector.imageStoreCurrentFreeCapacity(store1), | ||
| _statsCollector.imageStoreCurrentFreeCapacity(store2)); | ||
| } | ||
| }); | ||
| for (DataStore imageStore : imageStores) { | ||
| // Return image store if used percentage is less then threshold value i.e. 90%. | ||
| if (_statsCollector.imageStoreHasEnoughCapacity(imageStore)) { | ||
| return imageStore; | ||
| } | ||
| } | ||
| } else if (imageStores.size() == 1) { | ||
| if (_statsCollector.imageStoreHasEnoughCapacity(imageStores.get(0))) { | ||
| return imageStores.get(0); | ||
| } | ||
| } | ||
| return imageStores.get(0); | ||
|
|
||
| // No store with space found | ||
| s_logger.error(String.format("Can't find an image storage in zone with less than %d usage", | ||
| Math.round(_statsCollector.getImageStoreCapacityThreshold()*100))); | ||
| return null; | ||
| } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Besides checking for whether the store is below the threshold, are you also considering doing a check if the image will fit in the imagestore and what capacity remains afterwards....for example, if the current used capacity is at 89% and the image might move it to even upto 99%....or is that check happening on a separate method?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @kioie I'm not sure that is possible to implement for scenarios at this point with the current design. For example, while registering a template through URL we don't know actual size after download and install.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's okay, just wanted to know the possibility of it happening |
||
|
|
||
| @Override | ||
| public List<DataStore> listImageStoresWithFreeCapacity(List<DataStore> imageStores) { | ||
| List<DataStore> stores = new ArrayList<>(); | ||
| for (DataStore imageStore : imageStores) { | ||
| // Return image store if used percentage is less then threshold value i.e. 90%. | ||
| if (_statsCollector.imageStoreHasEnoughCapacity(imageStore)) { | ||
| stores.add(imageStore); | ||
| } | ||
| } | ||
|
|
||
| // No store with space found | ||
| if (stores.isEmpty()) { | ||
| s_logger.error(String.format("Can't find image storage in zone with less than %d usage", | ||
| Math.round(_statsCollector.getImageStoreCapacityThreshold() * 100))); | ||
| } | ||
| return stores; | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rhtyd Throwing an exception or returning null for Image store can fail this. This might not be needing a sec store for writing. Maybe need to handle this separately?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this be the reason you are using
(sourceTemplateDataStore != null)? If so, you might need an else at the end to manage the nullsThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kioie It should never be getting null value for image store as it needs the store only for reading and threshold limit shouldn't be affecting this. Will have to make changes for it.