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

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.orchestration.service.VolumeOrchestrationService;
import org.apache.cloudstack.engine.service.api.OrchestrationService; 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.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.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.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.VolumeDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
@ -532,6 +536,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
@Inject @Inject
private UserVmDeployAsIsDetailsDao userVmDeployAsIsDetailsDao; private UserVmDeployAsIsDetailsDao userVmDeployAsIsDetailsDao;
@Inject @Inject
private DataStoreProviderManager _dataStoreProviderMgr;
private StorageManager storageManager; private StorageManager storageManager;
@Inject @Inject
private ServiceOfferingJoinDao serviceOfferingJoinDao; private ServiceOfferingJoinDao serviceOfferingJoinDao;
@ -2108,9 +2113,12 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
GetVolumeStatsCommand cmd = new GetVolumeStatsCommand(poolType, poolUuid, volumeLocators); GetVolumeStatsCommand cmd = new GetVolumeStatsCommand(poolType, poolUuid, volumeLocators);
Answer answer = null; 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 // 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); answer = storageManager.getVolumeStats(storagePool, cmd);
} else { } else {
if (timeout > 0) { if (timeout > 0) {