From b53a9dcc9f3ee95d40761b9c2c860f821595a661 Mon Sep 17 00:00:00 2001 From: Wido den Hollander Date: Sun, 28 Sep 2014 11:55:25 +0200 Subject: [PATCH] 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 --- .../resource/LibvirtComputingResource.java | 2 +- .../kvm/storage/IscsiAdmStorageAdaptor.java | 5 +++++ .../kvm/storage/KVMStoragePoolManager.java | 6 +++++- .../kvm/storage/LibvirtStorageAdaptor.java | 21 ++++++++++++++++++- .../kvm/storage/StorageAdaptor.java | 3 +++ 5 files changed, 34 insertions(+), 3 deletions(-) diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java index 1dc1955c2e1..7624034b1b3 100755 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java @@ -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()); diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java index 2ea17e79143..f7a8cf715d0 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java @@ -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; diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStoragePoolManager.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStoragePoolManager.java index ab819b25729..583db0f4a36 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStoragePoolManager.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStoragePoolManager.java @@ -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) { diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java index ffd44230d3f..26237ba69b2 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java @@ -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); diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/StorageAdaptor.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/StorageAdaptor.java index 38ee3e6ed94..dceb2910c57 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/StorageAdaptor.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/StorageAdaptor.java @@ -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);