From: Dujiancheng <dujiancheng10(a)gmail.com>
dujiancheng (1):
qemu: Added support L2 table cache for qcow2 disk.
L2 table cache can be set by the new element diskCache.
Use the following methods to set the L2 table cache
and cache clean interval:
<diskCache>
<cache level='2'>
<size unit='KiB'>10240</size>
</cache>
<clean interval='900'/>
</diskCache>
Signed-off-by: dujiancheng <dujiancheng10(a)gmail.com>
---
docs/formatdomain.html.in | 25 +++++++++++++
docs/schemas/domaincommon.rng | 26 ++++++++++++++
src/conf/domain_conf.c | 63 ++++++++++++++++++++++++++++++++-
src/conf/domain_conf.h | 5 +++
src/qemu/qemu_command.c | 6 ++++
src/qemu/qemu_domain.c | 6 ++++
tests/qemuxml2argvdata/disk-cache.args | 30 ++++++++++++++++
tests/qemuxml2argvdata/disk-cache.xml | 40 +++++++++++++++++++++
tests/qemuxml2argvtest.c | 1 +
tests/qemuxml2xmloutdata/disk-cache.xml | 46 ++++++++++++++++++++++++
tests/qemuxml2xmltest.c | 1 +
11 files changed, 248 insertions(+), 1 deletion(-)
create mode 100644 tests/qemuxml2argvdata/disk-cache.args
create mode 100644 tests/qemuxml2argvdata/disk-cache.xml
create mode 100644 tests/qemuxml2xmloutdata/disk-cache.xml
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 0d68596..2afeb2b 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -2719,6 +2719,12 @@
<backingStore type='file'>
<format type='qcow2'/>
<source file='/var/lib/libvirt/images/snapshot.qcow'/>
+ <diskCache>
+ <cache level='2'>
+ <size unit='KiB'>128</size>
+ </cache>
+ <clean interval='8'/>
+ </diskCache>
<backingStore type='block'>
<format type='raw'/>
<source dev='/dev/mapper/base'/>
@@ -3582,6 +3588,25 @@
</dd>
</dl>
</dd>
+ <dt><code>diskCache</code></dt>
+ <dd>The <code>diskCache</code> allows setting the L2 cache
+ and cache clean interval values of the qcow2 image with
+ the following properties.
+ <span class="since">Since 2.5(QEMU and KVM)</span>
+ <dl>
+ <dt><code>cache</code></dt>
+ <dd>The <code>level</code> attribute allows you to set the
+ level of the cache, temporarily only supports level 2 cache.
+ The <code>size</code> allows you to set the size of the cache
+ and can specify the unit
+ </dd>
+ <dt><code>clean</code></dt>
+ <dd>The <code>interval</code> allow setting cache expiration
time
+ in seconds
+ </dd>
+ </dl>
+
+ </dd>
</dl>
<h4><a
id="elementsFilesystems">Filesystems</a></h4>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index f46145c..04bc9e1 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -1388,8 +1388,34 @@
</data>
</element>
</optional>
+ <optional>
+ <ref name="diskCache"/>
+ </optional>
</interleave>
</define>
+<define name="diskCache">
+ <element name="diskCache">
+ <interleave>
+ <optional>
+ <element name="cache">
+ <attribute name="level">
+ <ref name="unsignedInt"/>
+ </attribute>
+ <element name="size">
+ <ref name='scaledInteger'/>
+ </element>
+ </element>
+ </optional>
+ <optional>
+ <element name="clean">
+ <attribute name="interval">
+ <ref name="unsignedInt"/>
+ </attribute>
+ </element>
+ </optional>
+ </interleave>
+ </element>
+</define>
<define name="snapshot">
<attribute name="snapshot">
<choice>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index b8b5345..9b6f445 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -8894,6 +8894,37 @@ virDomainDiskSourceParse(xmlNodePtr node,
return 0;
}
+static int
+virDomainDiskCacheParse(xmlNodePtr node,
+ xmlXPathContextPtr ctxt,
+ virDomainDiskDefPtr def)
+{
+ int ret = -1;
+ xmlNodePtr saveNode = ctxt->node;
+ ctxt->node = node;
+ if (virXPathUInt("string(./clean/@interval)", ctxt,
&def->disk_cache.clean_interval) < -1) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("malformed disk cache clean interval"));
+ goto cleanup;
+ }
+
+ if (virXPathUInt("string(./cache/@level)", ctxt,
&def->disk_cache.cache_level) < -1) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("malformed disk cache level"));
+ goto cleanup;
+ }
+
+ if (virDomainParseMemory("./cache/size", NULL, ctxt,
+ &def->disk_cache.cache_size, false, true) < 0)
+ goto cleanup;
+
+ ret = 0;
+
+ cleanup:
+ ctxt->node = saveNode;
+ return ret;
+
+}
static int
virDomainDiskBackingStoreParse(xmlXPathContextPtr ctxt,
@@ -9701,6 +9732,10 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
}
} else if (virXMLNodeNameEqual(cur, "boot")) {
/* boot is parsed as part of virDomainDeviceInfoParseXML */
+ } else if (virXMLNodeNameEqual(cur, "diskCache")) {
+
+ if (virDomainDiskCacheParse(cur, ctxt, def) < 0)
+ goto error;
}
}
@@ -23369,7 +23404,32 @@ virDomainDiskBlockIoDefFormat(virBufferPtr buf,
virBufferAddLit(buf, "/>\n");
}
}
-
+static void
+virDomainDiskCacheDefFormat(virBufferPtr buf,
+ virDomainDiskDefPtr def)
+{
+ if (def->disk_cache.cache_size > 0 ||
+ def->disk_cache.clean_interval > 0) {
+ virBufferAddLit(buf, "<diskCache>\n");
+ virBufferAdjustIndent(buf, 2);
+ if (def->disk_cache.cache_level == 2 && def->disk_cache.cache_size
> 0) {
+ virBufferAddLit(buf, "<cache level='2'>\n");
+ virBufferAdjustIndent(buf, 2);
+ virBufferAsprintf(buf,
+ "<size
unit='KiB'>%llu</size>\n",
+ def->disk_cache.cache_size);
+ virBufferAdjustIndent(buf, -2);
+ virBufferAddLit(buf, "</cache>\n");
+ }
+ if (def->disk_cache.clean_interval > 0) {
+ virBufferAsprintf(buf,
+ "<clean interval='%u'/>\n",
+ def->disk_cache.clean_interval);
+ }
+ virBufferAdjustIndent(buf, -2);
+ virBufferAddLit(buf, "</diskCache>\n");
+ }
+}
static void
virDomainSourceDefFormatSeclabel(virBufferPtr buf,
@@ -23869,6 +23929,7 @@ virDomainDiskDefFormat(virBufferPtr buf,
virDomainDiskGeometryDefFormat(buf, def);
virDomainDiskBlockIoDefFormat(buf, def);
+ virDomainDiskCacheDefFormat(buf, def);
if (virDomainDiskDefFormatMirror(buf, def, flags, xmlopt) < 0)
return -1;
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 71437dc..7f87a1a 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -647,6 +647,11 @@ struct _virDomainDiskDef {
unsigned int physical_block_size;
} blockio;
+ struct {
+ unsigned int cache_level;
+ unsigned long long cache_size;
+ unsigned int clean_interval;
+ } disk_cache;
virDomainBlockIoTuneInfo blkdeviotune;
char *driverName;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 4fc3176..54fc642 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -1637,6 +1637,12 @@ qemuBuildDriveStr(virDomainDiskDefPtr disk,
if (qemuBuildDriveSourceStr(disk, qemuCaps, &opt) < 0)
goto error;
+ if (disk->disk_cache.cache_level == 2 && disk->disk_cache.cache_size
> 0)
+ virBufferAsprintf(&opt, "l2-cache-size=%llu,",
+ disk->disk_cache.cache_size);
+ if (disk->disk_cache.clean_interval > 0)
+ virBufferAsprintf(&opt, "cache-clean-interval=%u,",
+ disk->disk_cache.clean_interval);
if (qemuDiskBusNeedsDeviceArg(disk->bus)) {
char *drivealias = qemuAliasDiskDriveFromDisk(disk);
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index fee4481..cca78fc 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -8627,6 +8627,12 @@ qemuDomainDiskChangeSupported(virDomainDiskDefPtr disk,
CHECK_EQ(ioeventfd, "ioeventfd", true);
CHECK_EQ(event_idx, "event_idx", true);
CHECK_EQ(copy_on_read, "copy_on_read", true);
+ CHECK_EQ(disk_cache.cache_level,
+ "diskCache cache_level", true);
+ CHECK_EQ(disk_cache.cache_size,
+ "diskCache cache_size", true);
+ CHECK_EQ(disk_cache.clean_interval,
+ "diskCache clean_interval", true);
/* "snapshot" is a libvirt internal field and thus can be changed */
/* startupPolicy is allowed to be updated. Therefore not checked here. */
CHECK_EQ(transient, "transient", true);
diff --git a/tests/qemuxml2argvdata/disk-cache.args
b/tests/qemuxml2argvdata/disk-cache.args
new file mode 100644
index 0000000..bbc61e4
--- /dev/null
+++ b/tests/qemuxml2argvdata/disk-cache.args
@@ -0,0 +1,30 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu-system-i686 \
+-name QEMUGuest1 \
+-S \
+-machine pc,accel=tcg,usb=off,dump-guest-core=off \
+-m 214 \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\
+server,nowait \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-no-acpi \
+-boot c \
+-usb \
+-drive
file=/tmp/data.img,format=raw,l2-cache-size=10240,cache-clean-interval=900,if=none,id=drive-virtio-disk0
\
+-device virtio-blk-pci,bus=pci.0,addr=0x3,drive=drive-virtio-disk0,\
+id=virtio-disk0 \
+-drive file=/tmp/logs.img,format=raw,if=none,id=drive-virtio-disk1 \
+-device virtio-blk-pci,bus=pci.0,addr=0x4,drive=drive-virtio-disk1,\
+id=virtio-disk1
diff --git a/tests/qemuxml2argvdata/disk-cache.xml
b/tests/qemuxml2argvdata/disk-cache.xml
new file mode 100644
index 0000000..54cfa6c
--- /dev/null
+++ b/tests/qemuxml2argvdata/disk-cache.xml
@@ -0,0 +1,40 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-i686</emulator>
+ <disk type='file' device='disk'>
+ <driver name='qemu' type='raw'/>
+ <source file='/tmp/data.img'/>
+ <diskCache>
+ <cache level='2'>
+ <size unit='KiB'>10240</size>
+ </cache>
+ <clean interval='900'/>
+ </diskCache>
+ <target dev='vda' bus='virtio'/>
+ </disk>
+ <disk type='file' device='disk'>
+ <driver name='qemu' type='raw'/>
+ <source file='/tmp/logs.img'/>
+ <target dev='vdb' bus='virtio'/>
+ </disk>
+ <controller type='usb' index='0'/>
+ <controller type='ide' index='0'/>
+ <controller type='pci' index='0' model='pci-root'/>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <memballoon model='none'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index c279ac4..994afc4 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -1008,6 +1008,7 @@ mymain(void)
QEMU_CAPS_VIRTIO_S390);
DO_TEST("disk-many", NONE);
DO_TEST("disk-virtio", QEMU_CAPS_DRIVE_BOOT);
+ DO_TEST("disk-cache", NONE);
DO_TEST("disk-virtio-ccw",
QEMU_CAPS_CCW, QEMU_CAPS_VIRTIO_S390);
DO_TEST("disk-virtio-ccw-many",
diff --git a/tests/qemuxml2xmloutdata/disk-cache.xml
b/tests/qemuxml2xmloutdata/disk-cache.xml
new file mode 100644
index 0000000..015ca3e
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/disk-cache.xml
@@ -0,0 +1,46 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-i686</emulator>
+ <disk type='file' device='disk'>
+ <driver name='qemu' type='raw'/>
+ <source file='/tmp/data.img'/>
+ <diskCache>
+ <cache level='2'>
+ <size unit='KiB'>10240</size>
+ </cache>
+ <clean interval='900'/>
+ </diskCache>
+ <target dev='vda' bus='virtio'/>
+ <address type='pci' domain='0x0000' bus='0x00'
slot='0x03' function='0x0'/>
+ </disk>
+ <disk type='file' device='disk'>
+ <driver name='qemu' type='raw'/>
+ <source file='/tmp/logs.img'/>
+ <target dev='vdb' bus='virtio'/>
+ <address type='pci' domain='0x0000' bus='0x00'
slot='0x04' function='0x0'/>
+ </disk>
+ <controller type='usb' index='0'>
+ <address type='pci' domain='0x0000' bus='0x00'
slot='0x01' function='0x2'/>
+ </controller>
+ <controller type='ide' index='0'>
+ <address type='pci' domain='0x0000' bus='0x00'
slot='0x01' function='0x1'/>
+ </controller>
+ <controller type='pci' index='0' model='pci-root'/>
+ <input type='mouse' bus='ps2'/>
+ <input type='keyboard' bus='ps2'/>
+ <memballoon model='none'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index eac6d5b..7f6340d 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -404,6 +404,7 @@ mymain(void)
QEMU_CAPS_SCSI_DISK_WWN);
DO_TEST("disk-mirror-old", NONE);
DO_TEST("disk-mirror", NONE);
+ DO_TEST("disk-cache", NONE);
DO_TEST_FULL("disk-active-commit", WHEN_ACTIVE, GIC_NONE, NONE);
DO_TEST("graphics-listen-network", NONE);
DO_TEST("graphics-vnc", NONE);
--
1.8.3.1