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(a)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