From 75c15fd0d6afb10fb243f0870f7c56cfe173c251 Mon Sep 17 00:00:00 2001 From: slavkap <51903378+slavkap@users.noreply.github.com> Date: Tue, 28 Sep 2021 22:17:34 +0300 Subject: [PATCH] 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 --- .../com/cloud/storage/StorageManagerImpl.java | 62 +++++++++---------- .../java/com/cloud/vm/UserVmManagerImpl.java | 12 +++- 2 files changed, 38 insertions(+), 36 deletions(-) diff --git a/server/src/main/java/com/cloud/storage/StorageManagerImpl.java b/server/src/main/java/com/cloud/storage/StorageManagerImpl.java index 07e36689d3c..b53efc4d065 100644 --- a/server/src/main/java/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/main/java/com/cloud/storage/StorageManagerImpl.java @@ -465,10 +465,13 @@ 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) { - // Get stats from the pool directly instead of sending cmd to host - // Added support for ScaleIO/PowerFlex pool only - return getStoragePoolStats(pool, (GetStorageStatsCommand) cmd); + 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 + return getStoragePoolStats(pool, (GetStorageStatsCommand) 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) { - DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(pool.getStorageProviderName()); - DataStoreDriver storeDriver = storeProvider.getDataStoreDriver(); GetStorageStatsAnswer answer = null; - if (storeDriver instanceof PrimaryDataStoreDriver && ((PrimaryDataStoreDriver)storeDriver).canProvideStorageStats()) { - PrimaryDataStoreDriver primaryStoreDriver = (PrimaryDataStoreDriver)storeDriver; - Pair storageStats = primaryStoreDriver.getStorageStats(pool); - if (storageStats == null) { - answer = new GetStorageStatsAnswer((GetStorageStatsCommand) cmd, "Failed to get storage stats for pool: " + pool.getId()); - } else { - answer = new GetStorageStatsAnswer((GetStorageStatsCommand) cmd, storageStats.first(), storageStats.second()); - } + DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(pool.getStorageProviderName()); + DataStoreDriver storeDriver = storeProvider.getDataStoreDriver(); + PrimaryDataStoreDriver primaryStoreDriver = (PrimaryDataStoreDriver) storeDriver; + Pair storageStats = primaryStoreDriver.getStorageStats(pool); + if (storageStats == null) { + answer = new GetStorageStatsAnswer((GetStorageStatsCommand) cmd, "Failed to get storage stats for pool: " + pool.getId()); + } else { + answer = new GetStorageStatsAnswer((GetStorageStatsCommand) cmd, storageStats.first(), storageStats.second()); } return answer; @@ -498,30 +499,23 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C @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 statEntry = new HashMap(); - GetVolumeStatsCommand getVolumeStatsCommand = (GetVolumeStatsCommand) cmd; - for (String volumeUuid : getVolumeStatsCommand.getVolumeUuids()) { - Pair volumeStats = primaryStoreDriver.getVolumeStats(pool, volumeUuid); - if (volumeStats == null) { - return new GetVolumeStatsAnswer(getVolumeStatsCommand, "Failed to get stats for volume: " + volumeUuid, null); - } else { - VolumeStatsEntry volumeStatsEntry = new VolumeStatsEntry(volumeUuid, volumeStats.first(), volumeStats.second()); - statEntry.put(volumeUuid, volumeStatsEntry); - } + PrimaryDataStoreDriver primaryStoreDriver = (PrimaryDataStoreDriver) storeDriver; + HashMap statEntry = new HashMap(); + GetVolumeStatsCommand getVolumeStatsCommand = (GetVolumeStatsCommand) cmd; + for (String volumeUuid : getVolumeStatsCommand.getVolumeUuids()) { + Pair volumeStats = primaryStoreDriver.getVolumeStats(pool, volumeUuid); + if (volumeStats == null) { + return new GetVolumeStatsAnswer(getVolumeStatsCommand, "Failed to get stats for volume: " + volumeUuid, + null); + } else { + VolumeStatsEntry volumeStatsEntry = new VolumeStatsEntry(volumeUuid, volumeStats.first(), + volumeStats.second()); + statEntry.put(volumeUuid, volumeStatsEntry); } - return new GetVolumeStatsAnswer(getVolumeStatsCommand, "", statEntry); } - - return null; + return new GetVolumeStatsAnswer(getVolumeStatsCommand, "", statEntry); } public Long chooseHostForStoragePool(StoragePoolVO poolVO, List avoidHosts, boolean sendToVmResidesOn, Long vmId) { diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index d9ebe66bb02..6a5054f60eb 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -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) {