Allow storage plugins to get storage/volume stats without sending commands to hosts (#4826)

* Allow storage plugins to use storage/volume stats

Allow the rest of the storage plugins, not only ScaleIO to implement and
use the storage/volume statistics directly instead of sending cmd to
hosts

* Get the store driver from pool instead of passing it as argument

required change from code review to pick the store driver from pool not
to pass it as argument
This commit is contained in:
slavkap 2021-09-28 22:17:34 +03:00 committed by GitHub
parent e573d0ddcb
commit 75c15fd0d6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 38 additions and 36 deletions

View File

@ -465,11 +465,14 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
@Override
public Answer sendToPool(StoragePool pool, Command cmd) throws StorageUnavailableException {
if (cmd instanceof GetStorageStatsCommand && pool.getPoolType() == StoragePoolType.PowerFlex) {
if (cmd instanceof GetStorageStatsCommand) {
DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(pool.getStorageProviderName());
DataStoreDriver storeDriver = storeProvider.getDataStoreDriver();
if (storeDriver instanceof PrimaryDataStoreDriver && ((PrimaryDataStoreDriver)storeDriver).canProvideStorageStats()) {
// Get stats from the pool directly instead of sending cmd to host
// Added support for ScaleIO/PowerFlex pool only
return getStoragePoolStats(pool, (GetStorageStatsCommand) cmd);
}
}
Answer[] answers = sendToPool(pool, new Commands(cmd));
if (answers == null) {
@ -479,11 +482,10 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
}
private GetStorageStatsAnswer getStoragePoolStats(StoragePool pool, GetStorageStatsCommand cmd) {
DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(pool.getStorageProviderName());
DataStoreDriver storeDriver = storeProvider.getDataStoreDriver();
GetStorageStatsAnswer answer = null;
if (storeDriver instanceof PrimaryDataStoreDriver && ((PrimaryDataStoreDriver)storeDriver).canProvideStorageStats()) {
DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(pool.getStorageProviderName());
DataStoreDriver storeDriver = storeProvider.getDataStoreDriver();
PrimaryDataStoreDriver primaryStoreDriver = (PrimaryDataStoreDriver) storeDriver;
Pair<Long, Long> storageStats = primaryStoreDriver.getStorageStats(pool);
if (storageStats == null) {
@ -491,39 +493,31 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
} else {
answer = new GetStorageStatsAnswer((GetStorageStatsCommand) cmd, storageStats.first(), storageStats.second());
}
}
return answer;
}
@Override
public Answer getVolumeStats(StoragePool pool, Command cmd) {
if (!(cmd instanceof GetVolumeStatsCommand)) {
return null;
}
DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(pool.getStorageProviderName());
DataStoreDriver storeDriver = storeProvider.getDataStoreDriver();
if (storeDriver instanceof PrimaryDataStoreDriver && ((PrimaryDataStoreDriver)storeDriver).canProvideVolumeStats()) {
PrimaryDataStoreDriver primaryStoreDriver = (PrimaryDataStoreDriver) storeDriver;
HashMap<String, VolumeStatsEntry> statEntry = new HashMap<String, VolumeStatsEntry>();
GetVolumeStatsCommand getVolumeStatsCommand = (GetVolumeStatsCommand) cmd;
for (String volumeUuid : getVolumeStatsCommand.getVolumeUuids()) {
Pair<Long, Long> volumeStats = primaryStoreDriver.getVolumeStats(pool, volumeUuid);
if (volumeStats == null) {
return new GetVolumeStatsAnswer(getVolumeStatsCommand, "Failed to get stats for volume: " + volumeUuid, null);
return new GetVolumeStatsAnswer(getVolumeStatsCommand, "Failed to get stats for volume: " + volumeUuid,
null);
} else {
VolumeStatsEntry volumeStatsEntry = new VolumeStatsEntry(volumeUuid, volumeStats.first(), volumeStats.second());
VolumeStatsEntry volumeStatsEntry = new VolumeStatsEntry(volumeUuid, volumeStats.first(),
volumeStats.second());
statEntry.put(volumeUuid, volumeStatsEntry);
}
}
return new GetVolumeStatsAnswer(getVolumeStatsCommand, "", statEntry);
}
return null;
}
public Long chooseHostForStoragePool(StoragePoolVO poolVO, List<Long> avoidHosts, boolean sendToVmResidesOn, Long vmId) {
if (sendToVmResidesOn) {
if (vmId != null) {

View File

@ -95,8 +95,12 @@ import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationSe
import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
import org.apache.cloudstack.engine.service.api.OrchestrationService;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManager;
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore;
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
@ -532,6 +536,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
@Inject
private UserVmDeployAsIsDetailsDao userVmDeployAsIsDetailsDao;
@Inject
private DataStoreProviderManager _dataStoreProviderMgr;
private StorageManager storageManager;
@Inject
private ServiceOfferingJoinDao serviceOfferingJoinDao;
@ -2108,9 +2113,12 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
GetVolumeStatsCommand cmd = new GetVolumeStatsCommand(poolType, poolUuid, volumeLocators);
Answer answer = null;
if (poolType == StoragePoolType.PowerFlex) {
DataStoreProvider storeProvider = _dataStoreProviderMgr
.getDataStoreProvider(storagePool.getStorageProviderName());
DataStoreDriver storeDriver = storeProvider.getDataStoreDriver();
if (storeDriver instanceof PrimaryDataStoreDriver && ((PrimaryDataStoreDriver) storeDriver).canProvideVolumeStats()) {
// Get volume stats from the pool directly instead of sending cmd to host
// Added support for ScaleIO/PowerFlex pool only
answer = storageManager.getVolumeStats(storagePool, cmd);
} else {
if (timeout > 0) {