CLOUDSTACK-7641: Do not always ask libvirt to refresh a storage pool

On larger (especially RBD) storage pools this can take a lot of
time slowing operations like creating volumes down.

The getStorageStats command will still ask a pool to be refreshed so
that the management server has accurate information about the storage pools.

On larger deployments, with thousands of volumes in one pool, this should
significantly improve storage related operations
This commit is contained in:
Wido den Hollander 2014-09-28 11:55:25 +02:00
parent 59b0103a53
commit b53a9dcc9f
5 changed files with 34 additions and 3 deletions

View File

@ -2654,7 +2654,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
protected GetStorageStatsAnswer execute(final GetStorageStatsCommand cmd) {
try {
KVMStoragePool sp = _storagePoolMgr.getStoragePool(cmd.getPooltype(), cmd.getStorageId());
KVMStoragePool sp = _storagePoolMgr.getStoragePool(cmd.getPooltype(), cmd.getStorageId(), true);
return new GetStorageStatsAnswer(cmd, sp.getCapacity(), sp.getUsed());
} catch (CloudRuntimeException e) {
return new GetStorageStatsAnswer(cmd, e.toString());

View File

@ -52,6 +52,11 @@ public class IscsiAdmStorageAdaptor implements StorageAdaptor {
return MapStorageUuidToStoragePool.get(uuid);
}
@Override
public KVMStoragePool getStoragePool(String uuid, boolean refreshInfo) {
return MapStorageUuidToStoragePool.get(uuid);
}
@Override
public boolean deleteStoragePool(String uuid) {
return MapStorageUuidToStoragePool.remove(uuid) != null;

View File

@ -195,11 +195,15 @@ public class KVMStoragePoolManager {
}
public KVMStoragePool getStoragePool(StoragePoolType type, String uuid) {
return this.getStoragePool(type, uuid, false);
}
public KVMStoragePool getStoragePool(StoragePoolType type, String uuid, boolean refreshInfo) {
StorageAdaptor adaptor = getStorageAdaptor(type);
KVMStoragePool pool = null;
try {
pool = adaptor.getStoragePool(uuid);
pool = adaptor.getStoragePool(uuid, refreshInfo);
} catch (Exception e) {
StoragePoolInformation info = _storagePools.get(uuid);
if (info != null) {

View File

@ -338,6 +338,11 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
@Override
public KVMStoragePool getStoragePool(String uuid) {
return this.getStoragePool(uuid, false);
}
@Override
public KVMStoragePool getStoragePool(String uuid, boolean refreshInfo) {
s_logger.debug("Trying to fetch storage pool " + uuid + " from libvirt");
StoragePool storage = null;
try {
@ -383,7 +388,21 @@ public class LibvirtStorageAdaptor implements StorageAdaptor {
}
}
pool.refresh();
/**
* On large (RBD) storage pools it can take up to a couple of minutes
* for libvirt to refresh the pool.
*
* Refreshing a storage pool means that libvirt will have to iterate the whole pool
* and fetch information of each volume in there
*
* It is not always required to refresh a pool. So we can control if we want to or not
*
* By default only the getStorageStats call in the LibvirtComputingResource will ask to
* refresh the pool
*/
if (refreshInfo) {
pool.refresh();
}
pool.setCapacity(storage.getInfo().capacity);
pool.setUsed(storage.getInfo().allocation);
pool.setAvailable(storage.getInfo().available);

View File

@ -28,6 +28,9 @@ public interface StorageAdaptor {
public KVMStoragePool getStoragePool(String uuid);
// Get the storage pool from libvirt, but control if libvirt should refresh the pool (can take a long time)
public KVMStoragePool getStoragePool(String uuid, boolean refreshInfo);
// given disk path (per database) and pool, create new KVMPhysicalDisk, populate
// it with info from local disk, and return it
public KVMPhysicalDisk getPhysicalDisk(String volumeUuid, KVMStoragePool pool);