[libvirt] [PATCH 2/2] rbd: optionally disable actual disk-usage during pool/volume refresh

jdillama at redhat.com jdillama at redhat.com
Mon Mar 11 15:39:55 UTC 2019


From: Jason Dillaman <dillaman at redhat.com>

For pools with numerous volumes or very large volumes, the disk-usage
calculation can take a non-trivial amount of time even with the
fast-diff feature enabled (especially since the the usage is calculated
serially for each image in the pool).

The "rbd:config_opts" node now supports a new libvirt-internal
"libvirt_calculate_disk_usage" option which can be set to false to
disable this calculation as needed.

Signed-off-by: Jason Dillaman <dillaman at redhat.com>
---
 docs/formatstorage.html.in        | 13 ++++++++--
 src/storage/storage_backend_rbd.c | 41 ++++++++++++++++++++++++++++---
 2 files changed, 48 insertions(+), 6 deletions(-)

diff --git a/docs/formatstorage.html.in b/docs/formatstorage.html.in
index 968651330f..eb65edc4d4 100644
--- a/docs/formatstorage.html.in
+++ b/docs/formatstorage.html.in
@@ -613,12 +613,21 @@
     <rbd:option name='client_mount_timeout' value='45'/>
     <rbd:option name='rados_mon_op_timeout' value='20'/>
     <rbd:option name='rados_osd_op_timeout' value='10'/>
+    <rbd:option name='libvirt_calculate_disk_usage' value='false'/>
   </rbd:config_opts>
 </pool>
 </pre>
 
-      <span class="since">Since 5.1.0.</span></dd>
-
+      <span class="since">Since 5.1.0.</span>
+      <dl>
+        <dt><code>libvirt_calculate_disk_usage</code></dt>
+        <dd>Disable calculating the actual disk usage of RBD volumes when
+         set to <code>false</code>. This will speed up pool and volume
+         refresh operations for pools with many volumes or pools with
+         large images.
+        </dd>
+      </dl>
+      </dd>
     </dl>
 
     <h2><a id="StorageVol">Storage volume XML</a></h2>
diff --git a/src/storage/storage_backend_rbd.c b/src/storage/storage_backend_rbd.c
index e67911f928..07ab72f97c 100644
--- a/src/storage/storage_backend_rbd.c
+++ b/src/storage/storage_backend_rbd.c
@@ -61,6 +61,9 @@ struct _virStoragePoolRBDConfigOptionsDef {
 
 #define STORAGE_POOL_RBD_NAMESPACE_HREF "http://libvirt.org/schemas/storagepool/rbd/1.0"
 
+#define CONFIG_OPTION_INTERNAL_PREFIX "libvirt_"
+#define CONFIG_OPTION_CALCULATE_DISK_USAGE CONFIG_OPTION_INTERNAL_PREFIX "calculate_disk_usage"
+
 static void
 virStoragePoolDefRBDNamespaceFree(void *nsdata)
 {
@@ -321,6 +324,9 @@ virStorageBackendRBDOpenRADOSConn(virStorageBackendRBDStatePtr ptr,
         char uuidstr[VIR_UUID_STRING_BUFLEN];
 
         for (i = 0; i < cmdopts->noptions; i++) {
+            if (STRPREFIX(cmdopts->names[i], CONFIG_OPTION_INTERNAL_PREFIX))
+                continue;
+
             if (virStorageBackendRBDRADOSConfSet(ptr->cluster,
                                                  cmdopts->names[i],
                                                  cmdopts->values[i]) < 0)
@@ -527,10 +533,30 @@ virStorageBackendRBDSetAllocation(virStorageVolDefPtr vol ATTRIBUTE_UNUSED,
 }
 #endif
 
+static bool
+virStorageBackendRBDCalculateDiskUsage(virStoragePoolDefPtr def)
+{
+    size_t i;
+    bool calculate_disk_usage = true;
+
+    if (def->namespaceData) {
+        virStoragePoolRBDConfigOptionsDefPtr cmdopts = def->namespaceData;
+
+        for (i = 0; i < cmdopts->noptions; i++) {
+            if (STREQ(cmdopts->names[i], CONFIG_OPTION_CALCULATE_DISK_USAGE)) {
+                calculate_disk_usage = STRCASEEQ(cmdopts->values[i], "true");
+                break;
+            }
+        }
+    }
+    return calculate_disk_usage;
+}
+
 static int
 volStorageBackendRBDRefreshVolInfo(virStorageVolDefPtr vol,
                                    virStoragePoolObjPtr pool,
-                                   virStorageBackendRBDStatePtr ptr)
+                                   virStorageBackendRBDStatePtr ptr,
+                                   bool calculate_disk_usage)
 {
     int ret = -1;
     virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool);
@@ -564,7 +590,8 @@ volStorageBackendRBDRefreshVolInfo(virStorageVolDefPtr vol,
     vol->type = VIR_STORAGE_VOL_NETWORK;
     vol->target.format = VIR_STORAGE_FILE_RAW;
 
-    if (volStorageBackendRBDUseFastDiff(features, flags)) {
+    if (calculate_disk_usage &&
+        volStorageBackendRBDUseFastDiff(features, flags)) {
         VIR_DEBUG("RBD image %s/%s has fast-diff feature enabled. "
                   "Querying for actual allocation",
                   def->source.name, vol->name);
@@ -610,8 +637,10 @@ virStorageBackendRBDRefreshPool(virStoragePoolObjPtr pool)
     virStorageBackendRBDStatePtr ptr = NULL;
     struct rados_cluster_stat_t clusterstat;
     struct rados_pool_stat_t poolstat;
+    bool calculate_disk_usage = virStorageBackendRBDCalculateDiskUsage(def);
     VIR_AUTOFREE(char *) names = NULL;
 
+
     if (!(ptr = virStorageBackendRBDNewState(pool)))
         goto cleanup;
 
@@ -663,7 +692,8 @@ virStorageBackendRBDRefreshPool(virStoragePoolObjPtr pool)
 
         name += strlen(name) + 1;
 
-        r = volStorageBackendRBDRefreshVolInfo(vol, pool, ptr);
+        r = volStorageBackendRBDRefreshVolInfo(vol, pool, ptr,
+                                               calculate_disk_usage);
 
         /* It could be that a volume has been deleted through a different route
          * then libvirt and that will cause a -ENOENT to be returned.
@@ -1238,12 +1268,15 @@ virStorageBackendRBDRefreshVol(virStoragePoolObjPtr pool,
                                virStorageVolDefPtr vol)
 {
     virStorageBackendRBDStatePtr ptr = NULL;
+    virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool);
+    bool calculate_disk_usage = virStorageBackendRBDCalculateDiskUsage(def);
     int ret = -1;
 
     if (!(ptr = virStorageBackendRBDNewState(pool)))
         goto cleanup;
 
-    if (volStorageBackendRBDRefreshVolInfo(vol, pool, ptr) < 0)
+    if (volStorageBackendRBDRefreshVolInfo(vol, pool, ptr,
+                                           calculate_disk_usage) < 0)
         goto cleanup;
 
     ret = 0;
-- 
2.20.1




More information about the libvir-list mailing list