From c1d3f987753d99d27ed4a2e69fba656c76f27372 Mon Sep 17 00:00:00 2001 From: Sid Kattoju <45833770+skattoju4@users.noreply.github.com> Date: Wed, 24 Jul 2019 02:29:51 -0400 Subject: [PATCH] server: filter volumes by host when refreshing stats (#3486) Currently when refreshing disk usage stats all kvm agents are asked to collect stats for all volumes. In setups with multiple kvm hosts where managed storage is used, not all volumes are attached to all kvm hosts, this results in a large number of warnings in the kvm agent logs. This change introduces a filter step in case managed storage is used so that the management server only requests kvm agents for stats about volumes that are connected to each kvm host. --- .../java/com/cloud/storage/dao/VolumeDao.java | 2 ++ .../com/cloud/storage/dao/VolumeDaoImpl.java | 9 ++++++++ .../kvm/storage/IscsiAdmStorageAdaptor.java | 2 +- .../java/com/cloud/vm/UserVmManagerImpl.java | 21 +++++++++++++++++-- 4 files changed, 31 insertions(+), 3 deletions(-) diff --git a/engine/schema/src/main/java/com/cloud/storage/dao/VolumeDao.java b/engine/schema/src/main/java/com/cloud/storage/dao/VolumeDao.java index c0abb564de1..14f48ea06a8 100644 --- a/engine/schema/src/main/java/com/cloud/storage/dao/VolumeDao.java +++ b/engine/schema/src/main/java/com/cloud/storage/dao/VolumeDao.java @@ -46,6 +46,8 @@ public interface VolumeDao extends GenericDao, StateDao findByInstanceAndType(long id, Volume.Type vType); + List findByInstanceIdAndPoolId(long instanceId, long poolId); + List findByInstanceIdDestroyed(long vmId); List findByPod(long podId); diff --git a/engine/schema/src/main/java/com/cloud/storage/dao/VolumeDaoImpl.java b/engine/schema/src/main/java/com/cloud/storage/dao/VolumeDaoImpl.java index fb25c54b2cf..7c63b9c7526 100644 --- a/engine/schema/src/main/java/com/cloud/storage/dao/VolumeDaoImpl.java +++ b/engine/schema/src/main/java/com/cloud/storage/dao/VolumeDaoImpl.java @@ -127,6 +127,15 @@ public class VolumeDaoImpl extends GenericDaoBase implements Vol return listBy(sc); } + @Override + public List findByInstanceIdAndPoolId(long instanceId, long poolId) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("instanceId", instanceId); + sc.setParameters("poolId", poolId); + sc.setParameters("notDestroyed", Volume.State.Destroy); + return listBy(sc); + } + @Override public VolumeVO findByPoolIdName(long poolId, String name) { SearchCriteria sc = AllFieldsSearch.create(); diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java index 8d1ae771b29..bad0151ed8f 100644 --- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java +++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java @@ -242,7 +242,7 @@ public class IscsiAdmStorageAdaptor implements StorageAdaptor { String result = iScsiAdmCmd.execute(parser); if (result != null) { - s_logger.warn("Unable to retrieve the size of device " + deviceByPath); + s_logger.warn("Unable to retrieve the size of device (resource may have moved to a different host)" + deviceByPath); return 0; } diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index 2843d6e456d..1e47e5a90af 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -1938,14 +1938,24 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } @Override - public HashMap getVolumeStatistics(long clusterId, String poolUuid, StoragePoolType poolType, List volumeLocator, int timeout) { + public HashMap getVolumeStatistics(long clusterId, String poolUuid, StoragePoolType poolType, List volumeLocators, int timeout) { List neighbors = _resourceMgr.listHostsInClusterByStatus(clusterId, Status.Up); + StoragePool storagePool = _storagePoolDao.findPoolByUUID(poolUuid); for (HostVO neighbor : neighbors) { - GetVolumeStatsCommand cmd = new GetVolumeStatsCommand(poolType, poolUuid, volumeLocator); + if (storagePool.isManaged()) { + + volumeLocators = getVolumesByHost(neighbor, storagePool); + + } + + GetVolumeStatsCommand cmd = new GetVolumeStatsCommand(poolType, poolUuid, volumeLocators); + if (timeout > 0) { cmd.setWait(timeout/1000); } + Answer answer = _agentMgr.easySend(neighbor.getId(), cmd); + if (answer instanceof GetVolumeStatsAnswer){ GetVolumeStatsAnswer volstats = (GetVolumeStatsAnswer)answer; return volstats.getVolumeStats(); @@ -1954,6 +1964,13 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir return null; } + private List getVolumesByHost(HostVO host, StoragePool pool){ + List vmsPerHost = _vmDao.listByHostId(host.getId()); + return vmsPerHost.stream() + .flatMap(vm -> _volsDao.findByInstanceIdAndPoolId(vm.getId(),pool.getId()).stream().map(vol -> vol.getPath())) + .collect(Collectors.toList()); + } + @Override @DB public UserVm recoverVirtualMachine(RecoverVMCmd cmd) throws ResourceAllocationException, CloudRuntimeException {