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.
This commit is contained in:
Sid Kattoju 2019-07-24 02:29:51 -04:00 committed by Rohit Yadav
parent d930982a1c
commit c1d3f98775
4 changed files with 31 additions and 3 deletions

View File

@ -46,6 +46,8 @@ public interface VolumeDao extends GenericDao<VolumeVO, Long>, StateDao<Volume.S
List<VolumeVO> findByInstanceAndType(long id, Volume.Type vType);
List<VolumeVO> findByInstanceIdAndPoolId(long instanceId, long poolId);
List<VolumeVO> findByInstanceIdDestroyed(long vmId);
List<VolumeVO> findByPod(long podId);

View File

@ -127,6 +127,15 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol
return listBy(sc);
}
@Override
public List<VolumeVO> findByInstanceIdAndPoolId(long instanceId, long poolId) {
SearchCriteria<VolumeVO> 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<VolumeVO> sc = AllFieldsSearch.create();

View File

@ -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;
}

View File

@ -1938,14 +1938,24 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
}
@Override
public HashMap<String, VolumeStatsEntry> getVolumeStatistics(long clusterId, String poolUuid, StoragePoolType poolType, List<String> volumeLocator, int timeout) {
public HashMap<String, VolumeStatsEntry> getVolumeStatistics(long clusterId, String poolUuid, StoragePoolType poolType, List<String> volumeLocators, int timeout) {
List<HostVO> 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<String> getVolumesByHost(HostVO host, StoragePool pool){
List<UserVmVO> 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 {