[libvirt] [PATCH] Add qcow2 cache configuration

Liu Qing liuqing at huayun.com
Wed Aug 30 08:07:16 UTC 2017


Random write IOPS will drop dramatically if qcow2 l2 cache could not
cover the whole disk. This patch give libvirt user a chance to adjust
the qcow2 cache configuration.

Signed-off-by: Liu Qing <liuqing at huayun.com>
---
 src/conf/domain_conf.c    | 30 ++++++++++++++++++++++++++++++
 src/qemu/qemu_command.c   |  6 ++++++
 src/util/virstoragefile.c |  3 +++
 src/util/virstoragefile.h |  4 ++++
 4 files changed, 43 insertions(+)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index d97aab4..06ca1de 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -8590,6 +8590,30 @@ virDomainDiskDefDriverParseXML(virDomainDiskDefPtr def,
         VIR_FREE(tmp);
     }
 
+    if ((tmp = virXMLPropString(cur, "l2-cache-size")) &&
+        (virStrToLong_ui(tmp, NULL, 10, &def->src->l2_cache_size) < 0)) {
+        virReportError(VIR_ERR_XML_ERROR,
+                       _("Invalid l2-cache-size attribute in disk driver element: %s"),
+                       tmp);
+        goto cleanup;
+    }
+
+    if ((tmp = virXMLPropString(cur, "refcount-cache-size")) &&
+        (virStrToLong_ui(tmp, NULL, 10, &def->src->refcount_cache_size) < 0)) {
+        virReportError(VIR_ERR_XML_ERROR,
+                       _("Invalid refcount-cache-size attribute in disk driver element: %s"),
+                       tmp);
+        goto cleanup;
+    }
+
+    if ((tmp = virXMLPropString(cur, "cache-clean-interval")) &&
+        (virStrToLong_ui(tmp, NULL, 10, &def->src->cache_clean_interval) < 0)) {
+        virReportError(VIR_ERR_XML_ERROR,
+                       _("Invalid cache-clean-interval attribute in disk driver element: %s"),
+                       tmp);
+        goto cleanup;
+    }
+
     if ((tmp = virXMLPropString(cur, "detect_zeroes")) &&
         (def->detect_zeroes = virDomainDiskDetectZeroesTypeFromString(tmp)) <= 0) {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
@@ -21887,6 +21911,12 @@ virDomainDiskDefFormat(virBufferPtr buf,
         virBufferAsprintf(&driverBuf, " iothread='%u'", def->iothread);
     if (def->detect_zeroes)
         virBufferAsprintf(&driverBuf, " detect_zeroes='%s'", detect_zeroes);
+    if (def->src->l2_cache_size > 0)
+        virBufferAsprintf(&driverBuf, " l2-cache-size='%u'", def->src->l2_cache_size);
+    if (def->src->refcount_cache_size > 0)
+        virBufferAsprintf(&driverBuf, " refcount-cache-size='%u'", def->src->refcount_cache_size);
+    if (def->src->cache_clean_interval > 0)
+        virBufferAsprintf(&driverBuf, " cache-clean-interval='%u'", def->src->cache_clean_interval);
 
     virDomainVirtioOptionsFormat(&driverBuf, def->virtio);
 
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 9a27987..7996eed 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -1430,6 +1430,12 @@ qemuBuildDriveSourceStr(virDomainDiskDefPtr disk,
             qemuformat = "luks";
         virBufferAsprintf(buf, "format=%s,", qemuformat);
     }
+    if (disk->src->format == VIR_STORAGE_FILE_QCOW2 && disk->src->l2_cache_size > 0)
+        virBufferAsprintf(buf, "l2-cache-size=%u,", disk->src->l2_cache_size);
+    if (disk->src->format == VIR_STORAGE_FILE_QCOW2 && disk->src->refcount_cache_size > 0)
+        virBufferAsprintf(buf, "refcount-cache-size=%u,", disk->src->refcount_cache_size);
+    if (disk->src->format == VIR_STORAGE_FILE_QCOW2 && disk->src->cache_clean_interval > 0)
+        virBufferAsprintf(buf, "cache-clean-interval=%u,", disk->src->cache_clean_interval);
 
     ret = 0;
 
diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
index fbc8245..c685331 100644
--- a/src/util/virstoragefile.c
+++ b/src/util/virstoragefile.c
@@ -2038,6 +2038,9 @@ virStorageSourceCopy(const virStorageSource *src,
     ret->physical = src->physical;
     ret->readonly = src->readonly;
     ret->shared = src->shared;
+    ret->l2_cache_size = src->l2_cache_size;
+    ret->refcount_cache_size = src->refcount_cache_size;
+    ret->cache_clean_interval = src->cache_clean_interval;
 
     /* storage driver metadata are not copied */
     ret->drv = NULL;
diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h
index 6c388b1..e7889d9 100644
--- a/src/util/virstoragefile.h
+++ b/src/util/virstoragefile.h
@@ -280,6 +280,10 @@ struct _virStorageSource {
     /* metadata that allows identifying given storage source */
     char *nodeformat;  /* name of the format handler object */
     char *nodestorage; /* name of the storage object */
+
+    unsigned l2_cache_size; /* qcow2 l2 cache size */
+    unsigned refcount_cache_size; /* qcow2 reference count table cache size */
+    unsigned cache_clean_interval; /* clean unused cache entries interval */
 };
 
 
-- 
1.8.3.1




More information about the libvir-list mailing list