[libvirt] [PATCH v3 0/2] Add support for qcow2 cache

changes since v2: Patch 1 - a) add new element qcow2 as drive's child, if any qcow2 specific configuration exists. b) merge the three test cases to one. c) update docs. cache size only support bytes. d) move the parameters checking to virDomainDiskDefParseValidate Patch 2 - a) use QMP instead of qemu version to identify qemu capabilities. b) change capablity names with prefix drive.qcow2. c) merge the three test cases to one. Liu Qing (2): conf, docs: Add qcow2 cache configuration support qemu: add capability checking for qcow2 cache configuration docs/formatdomain.html.in | 43 ++++++++++ docs/schemas/domaincommon.rng | 35 ++++++++ src/conf/domain_conf.c | 95 +++++++++++++++++++++- src/qemu/qemu_capabilities.c | 9 ++ src/qemu/qemu_capabilities.h | 3 + src/qemu/qemu_command.c | 33 ++++++++ src/util/virstoragefile.c | 3 + src/util/virstoragefile.h | 6 ++ tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml | 3 + .../caps_2.6.0-gicv2.aarch64.xml | 3 + .../caps_2.6.0-gicv3.aarch64.xml | 3 + tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.xml | 3 + tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml | 3 + tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml | 3 + tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml | 3 + tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml | 3 + tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml | 3 + tests/qemucapabilitiesdata/caps_2.9.0.ppc64le.xml | 3 + tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml | 3 + tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml | 3 + .../qemuxml2argv-disk-drive-qcow2-cache.args | 28 +++++++ .../qemuxml2argv-disk-drive-qcow2-cache.xml | 43 ++++++++++ tests/qemuxml2argvtest.c | 4 + .../qemuxml2xmlout-disk-drive-qcow2-cache.xml | 43 ++++++++++ tests/qemuxml2xmltest.c | 1 + 25 files changed, 381 insertions(+), 1 deletion(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-qcow2-cache.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-qcow2-cache.xml create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-disk-drive-qcow2-cache.xml -- 1.8.3.1

Random write IOPS will drop dramatically if qcow2 l2 cache could not cover the whole disk. This patch gives libvirt user a chance to adjust the qcow2 cache configuration. Three new qcow2 driver parameters are added. They are l2-cache-size, refcount-cache-size and cache-clean-interval. The following are from qcow2-cache.txt. The amount of virtual disk that can be mapped by the L2 and refcount caches (in bytes) is: disk_size = l2_cache_size * cluster_size / 8 disk_size = refcount_cache_size * cluster_size * 8 / refcount_bits The parameter "cache-clean-interval" defines an interval (in seconds). All cache entries that haven't been accessed during that interval are removed from memory. Signed-off-by: Liu Qing <liuqing@huayun.com> --- a) add new element qcow2 as drive's child, if any qcow2 specific configuration exists. b) merge the three test cases to one. c) update docs. cache size only support bytes. d) move the parameters checking to virDomainDiskDefParseValidate docs/formatdomain.html.in | 43 ++++++++++ docs/schemas/domaincommon.rng | 35 ++++++++ src/conf/domain_conf.c | 95 +++++++++++++++++++++- src/qemu/qemu_command.c | 6 ++ src/util/virstoragefile.c | 3 + src/util/virstoragefile.h | 6 ++ .../qemuxml2argv-disk-drive-qcow2-cache.xml | 43 ++++++++++ .../qemuxml2xmlout-disk-drive-qcow2-cache.xml | 43 ++++++++++ tests/qemuxml2xmltest.c | 1 + 9 files changed, 274 insertions(+), 1 deletion(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-qcow2-cache.xml create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-disk-drive-qcow2-cache.xml diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 8ca7637..245d5c4 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -3036,6 +3036,49 @@ set. (<span class="since">Since 3.5.0</span>) </li> </ul> + The <code>drive</code> element may contain a qcow2 sub element, which + allows to specifying further details related to qcow2 driver type. + <span class="since">Since 3.8.0</span> + <ul> + <li> + The optional <code>l2_cache_size</code> attribute controls how much + memory will be consumed by qcow2 l2 table cache in bytes. This + option is only valid when the driver type is qcow2. The default + size is 2097152. The amount of virtual disk that can be mapped by + the L2 caches (in bytes) is: + disk_size = l2_cache_size * cluster_size / 8 + <span class='since'>Since 3.8.0</span> + + <b>In general you should leave this option alone, unless you + are very certain you know what you are doing.</b> + </li> + <li> + The optional <code>refcount_cache_size</code> attribute controls + how much memory will be consumed by qcow2 reference count table + cache in bytes. This option is only valid when the driver type is + qcow2. The default size is 262144. The amount of virtual disk that + can be mapped by the refcount caches (in bytes) is: + disk_size = refcount_cache_size * cluster_size * 8 / refcount_bits + <span class='since'>Since 3.8.0</span> + + <b>In general you should leave this option alone, unless you + are very certain you know what you are doing.</b> + </li> + <li> + The optional <code>cache_clean_interval</code> attribute defines + an interval (in seconds). All cache entries that haven't been + accessed during that interval are removed from memory. This option + is only valid when the driver type is qcow2. The default + value is 0, which disables this feature. If the interval is too + short, it will cause frequent cache write back and load, which + impact performance. If the interval is too long, unused cache + will still consume memory until it's been written back to disk. + <span class='since'>Since 3.8.0</span> + + <b>In general you should leave this option alone, unless you + are very certain you know what you are doing.</b> + </li> + </ul> </dd> <dt><code>backenddomain</code></dt> <dd>The optional <code>backenddomain</code> element allows specifying a diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 06c5a91..ec44e58 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -1762,6 +1762,23 @@ </element> </define> <!-- + Parameters for qcow2 driver + --> + <define name="qcow2Driver"> + <element name="qcow2"> + <optional> + <ref name="qcow2_l2_cache_size"/> + </optional> + <optional> + <ref name="qcow2_refcount_cache_size"/> + </optional> + <optional> + <ref name="qcow2_cache_clean_interval"/> + </optional> + </element> + </define> + + <!-- Disk may use a special driver for access. --> <define name="diskDriver"> @@ -1800,6 +1817,9 @@ <ref name="detect_zeroes"/> </optional> <ref name="virtioOptions"/> + <zeroOrMore> + <ref name="qcow2Driver"/> + </zeroOrMore> <empty/> </element> </define> @@ -1895,6 +1915,21 @@ </choice> </attribute> </define> + <define name="qcow2_l2_cache_size"> + <attribute name='l2_cache_size'> + <ref name="unsignedInt"/> + </attribute> + </define> + <define name="qcow2_refcount_cache_size"> + <attribute name='refcount_cache_size'> + <ref name="unsignedInt"/> + </attribute> + </define> + <define name="qcow2_cache_clean_interval"> + <attribute name='cache_clean_interval'> + <ref name="unsignedInt"/> + </attribute> + </define> <define name="controller"> <element name="controller"> <optional> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 2fc1fc3..c7d4b9b 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -5673,6 +5673,28 @@ virDomainDeviceLoadparmIsValid(const char *loadparm) static void +virDoaminQcow2CacheOptionsFormat(virBufferPtr buf, + virDomainDiskDefPtr def) +{ + virBuffer qcow2Buff = VIR_BUFFER_INITIALIZER; + if (def->src->l2_cache_size > 0) + virBufferAsprintf(&qcow2Buff, " l2_cache_size='%llu'", + def->src->l2_cache_size); + if (def->src->refcount_cache_size > 0) + virBufferAsprintf(&qcow2Buff, " refcount_cache_size='%llu'", + def->src->refcount_cache_size); + if (def->src->cache_clean_interval > 0) + virBufferAsprintf(&qcow2Buff, " cache_clean_interval='%llu'", + def->src->cache_clean_interval); + + if (virBufferUse(&qcow2Buff)) { + virBufferAddLit(buf, "<qcow2"); + virBufferAddBuffer(buf, &qcow2Buff); + virBufferAddLit(buf, "/>\n"); + } +} + +static void virDomainVirtioOptionsFormat(virBufferPtr buf, virDomainVirtioOptionsPtr virtio) { @@ -8511,15 +8533,69 @@ virDomainDiskDefParseValidate(const virDomainDiskDef *def) } } + if (def->src->format != VIR_STORAGE_FILE_QCOW2 && + (def->src->l2_cache_size > 0 || def->src->refcount_cache_size > 0 || + def->src->cache_clean_interval > 0)) { + virReportError(VIR_ERR_XML_ERROR, + _("Setting l2_cache_size, refcount_cache_size, " + "cache_clean_interval is not allowed for types " + "other than QCOW2")); + return -1; + } + return 0; } static int +virDomainDiskDefQcow2ParseXML(virDomainDiskDefPtr def, + xmlNodePtr cur) +{ + char *tmp = NULL; + int ret = -1; + + if ((tmp = virXMLPropString(cur, "l2_cache_size")) && + (virStrToLong_ullp(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; + } + VIR_FREE(tmp); + + if ((tmp = virXMLPropString(cur, "refcount_cache_size")) && + (virStrToLong_ullp(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; + } + VIR_FREE(tmp); + + if ((tmp = virXMLPropString(cur, "cache_clean_interval")) && + (virStrToLong_ullp(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; + } + VIR_FREE(tmp); + + ret = 0; + + cleanup: + VIR_FREE(tmp); + + return ret; +} + + +static int virDomainDiskDefDriverParseXML(virDomainDiskDefPtr def, xmlNodePtr cur) { char *tmp = NULL; + xmlNodePtr child; int ret = -1; def->src->driverName = virXMLPropString(cur, "name"); @@ -8622,6 +8698,12 @@ virDomainDiskDefDriverParseXML(virDomainDiskDefPtr def, } VIR_FREE(tmp); + for (child = cur->children; child != NULL; child = child->next) { + if (virXMLNodeNameEqual(child, "qcow2") && + virDomainDiskDefQcow2ParseXML(def, child) < 0) { + goto cleanup; + } + } ret = 0; cleanup: @@ -21908,7 +21990,18 @@ virDomainDiskDefFormat(virBufferPtr buf, if (virBufferUse(&driverBuf)) { virBufferAddLit(buf, "<driver"); virBufferAddBuffer(buf, &driverBuf); - virBufferAddLit(buf, "/>\n"); + + if (def->src->l2_cache_size == 0 && + def->src->refcount_cache_size == 0 && + def->src->cache_clean_interval == 0) { + virBufferAddLit(buf, "/>\n"); + } else { + virBufferAddLit(buf, ">\n"); + virBufferAdjustIndent(buf, 2); + virDoaminQcow2CacheOptionsFormat(buf, def); + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</driver>\n"); + } } if (def->src->auth) { diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index ed8cb6e..391aaba 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -1433,6 +1433,12 @@ qemuBuildDriveSourceStr(virDomainDiskDefPtr disk, qemuformat = "luks"; virBufferAsprintf(buf, "format=%s,", qemuformat); } + if (disk->src->l2_cache_size > 0) + virBufferAsprintf(buf, "l2-cache-size=%llu,", disk->src->l2_cache_size); + if (disk->src->refcount_cache_size > 0) + virBufferAsprintf(buf, "refcount-cache-size=%llu,", disk->src->refcount_cache_size); + if (disk->src->cache_clean_interval > 0) + virBufferAsprintf(buf, "cache-clean-interval=%llu,", 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..9b5a5f3 100644 --- a/src/util/virstoragefile.h +++ b/src/util/virstoragefile.h @@ -280,6 +280,12 @@ 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 long long l2_cache_size; /* qcow2 l2 cache size */ + /* qcow2 reference count table cache size */ + unsigned long long refcount_cache_size; + /* clean unused cache entries interval */ + unsigned long long cache_clean_interval; }; diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-qcow2-cache.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-qcow2-cache.xml new file mode 100644 index 0000000..3f464db --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-qcow2-cache.xml @@ -0,0 +1,43 @@ +<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='block' device='disk'> + <driver name='qemu' type='qcow2' cache='none'> + <qcow2 l2_cache_size='2097152' refcount_cache_size='524288' cache_clean_interval='900'/> + </driver> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <disk type='block' device='cdrom'> + <driver name='qemu' type='raw'/> + <source dev='/dev/HostVG/QEMUGuest2'/> + <target dev='hdc' bus='ide'/> + <readonly/> + <address type='drive' controller='0' bus='1' target='0' unit='0'/> + </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/qemuxml2xmloutdata/qemuxml2xmlout-disk-drive-qcow2-cache.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-disk-drive-qcow2-cache.xml new file mode 100644 index 0000000..3f464db --- /dev/null +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-disk-drive-qcow2-cache.xml @@ -0,0 +1,43 @@ +<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='block' device='disk'> + <driver name='qemu' type='qcow2' cache='none'> + <qcow2 l2_cache_size='2097152' refcount_cache_size='524288' cache_clean_interval='900'/> + </driver> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <disk type='block' device='cdrom'> + <driver name='qemu' type='raw'/> + <source dev='/dev/HostVG/QEMUGuest2'/> + <target dev='hdc' bus='ide'/> + <readonly/> + <address type='drive' controller='0' bus='1' target='0' unit='0'/> + </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 97ff36c..1ffb831 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -461,6 +461,7 @@ mymain(void) DO_TEST("disk-drive-cache-v2-none", NONE); DO_TEST("disk-drive-cache-directsync", NONE); DO_TEST("disk-drive-cache-unsafe", NONE); + DO_TEST("disk-drive-qcow2-cache", NONE); DO_TEST("disk-drive-network-nbd", NONE); DO_TEST("disk-drive-network-nbd-export", NONE); DO_TEST("disk-drive-network-nbd-ipv6", NONE); -- 1.8.3.1

On 09/07/2017 02:09 AM, Liu Qing wrote:
Random write IOPS will drop dramatically if qcow2 l2 cache could not cover the whole disk. This patch gives libvirt user a chance to adjust the qcow2 cache configuration.
Three new qcow2 driver parameters are added. They are l2-cache-size, refcount-cache-size and cache-clean-interval.
The following are from qcow2-cache.txt. The amount of virtual disk that can be mapped by the L2 and refcount caches (in bytes) is: disk_size = l2_cache_size * cluster_size / 8 disk_size = refcount_cache_size * cluster_size * 8 / refcount_bits
The parameter "cache-clean-interval" defines an interval (in seconds). All cache entries that haven't been accessed during that interval are removed from memory.
Suggestion, rewrite a bit: Three new qcow2 driver parameters (l2-cache-size, refcount-cache-size and cache-clean-interval) are added as attributes to a new <qcow2> subelement for a <driver name='qemu' type='qcow2'...> of a <disk> element. The QEMU source docs/qcow2-cache.txt provides the guidelines for defining/configuring values for each. ... That is - let's not bother with repeating what's in the document since it can change, but provide enough information that someone with curiosity would know where to look. Question from me: does "cache='none'" need to be set in the <driver> element for this to work properly? Do any of the cache values make sense? If it must be none, then we need to check that. If something doesn't make ense, we need to check that too.
Signed-off-by: Liu Qing <liuqing@huayun.com> ---
a) add new element qcow2 as drive's child, if any qcow2 specific configuration exists. b) merge the three test cases to one. c) update docs. cache size only support bytes. d) move the parameters checking to virDomainDiskDefParseValidate
docs/formatdomain.html.in | 43 ++++++++++ docs/schemas/domaincommon.rng | 35 ++++++++ src/conf/domain_conf.c | 95 +++++++++++++++++++++- src/qemu/qemu_command.c | 6 ++ src/util/virstoragefile.c | 3 + src/util/virstoragefile.h | 6 ++ .../qemuxml2argv-disk-drive-qcow2-cache.xml | 43 ++++++++++ .../qemuxml2xmlout-disk-drive-qcow2-cache.xml | 43 ++++++++++ tests/qemuxml2xmltest.c | 1 + 9 files changed, 274 insertions(+), 1 deletion(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-qcow2-cache.xml create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-disk-drive-qcow2-cache.xml
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 8ca7637..245d5c4 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -3036,6 +3036,49 @@ set. (<span class="since">Since 3.5.0</span>) </li> </ul> + The <code>drive</code> element may contain a qcow2 sub element, which
s/drive/driver/ s/qcow2/<code>qcow2</code>/
+ allows to specifying further details related to qcow2 driver type.
s/allows// s/to qcow2 driver type/to a qcow2 disk./ Then, I'd add: For recommended setting guidelines refer to the QEMU source file <code>docs/qcow2-cache.txt</code>.
+ <span class="since">Since 3.8.0</span> + <ul> + <li> + The optional <code>l2_cache_size</code> attribute controls how much + memory will be consumed by qcow2 l2 table cache in bytes. This + option is only valid when the driver type is qcow2. The default + size is 2097152. The amount of virtual disk that can be mapped by + the L2 caches (in bytes) is: + disk_size = l2_cache_size * cluster_size / 8
The one concern I have about providing an example is that it changes in the qemu source docs and isn't reflected here. Beyond that someone would have to know how to determine their cluster_size or perhaps remember from when the volume was created.
+ <span class='since'>Since 3.8.0</span> + + <b>In general you should leave this option alone, unless you + are very certain you know what you are doing.</b> + </li> + <li> + The optional <code>refcount_cache_size</code> attribute controls + how much memory will be consumed by qcow2 reference count table + cache in bytes. This option is only valid when the driver type is + qcow2. The default size is 262144. The amount of virtual disk that + can be mapped by the refcount caches (in bytes) is: + disk_size = refcount_cache_size * cluster_size * 8 / refcount_bits
Similar here and here you introduce refcount_bits which kind of doesn't make much sense.
+ <span class='since'>Since 3.8.0</span> + + <b>In general you should leave this option alone, unless you + are very certain you know what you are doing.</b> + </li> + <li> + The optional <code>cache_clean_interval</code> attribute defines + an interval (in seconds). All cache entries that haven't been + accessed during that interval are removed from memory. This option + is only valid when the driver type is qcow2. The default + value is 0, which disables this feature. If the interval is too + short, it will cause frequent cache write back and load, which + impact performance. If the interval is too long, unused cache + will still consume memory until it's been written back to disk. + <span class='since'>Since 3.8.0</span> + + <b>In general you should leave this option alone, unless you + are very certain you know what you are doing.</b> + </li> + </ul> </dd> <dt><code>backenddomain</code></dt> <dd>The optional <code>backenddomain</code> element allows specifying a diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 06c5a91..ec44e58 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -1762,6 +1762,23 @@ </element> </define> <!-- + Parameters for qcow2 driver + --> + <define name="qcow2Driver"> + <element name="qcow2"> + <optional> + <ref name="qcow2_l2_cache_size"/> + </optional> + <optional> + <ref name="qcow2_refcount_cache_size"/> + </optional> + <optional> + <ref name="qcow2_cache_clean_interval"/> + </optional> + </element> + </define> + + <!-- Disk may use a special driver for access. --> <define name="diskDriver"> @@ -1800,6 +1817,9 @@ <ref name="detect_zeroes"/> </optional> <ref name="virtioOptions"/> + <zeroOrMore> + <ref name="qcow2Driver"/> + </zeroOrMore>
While multiple <qcow2> sub-elements could be had in the source, only the last setting for any value is used... Thus: <driver name='qemu' type='qcow2' cache='none'> <qcow2 l2_cache_size='2097152' refcount_cache_size='524288' cache_clean_interval='900'/> <qcow2 cache_clean_interval='1'/> </driver> would conceivably overwrite the previous.... I know bad example, but supporting multiple <qcow2> sub elements will be "forever"...
<empty/> </element> </define> @@ -1895,6 +1915,21 @@ </choice> </attribute> </define> + <define name="qcow2_l2_cache_size"> + <attribute name='l2_cache_size'> + <ref name="unsignedInt"/> + </attribute> + </define> + <define name="qcow2_refcount_cache_size"> + <attribute name='refcount_cache_size'> + <ref name="unsignedInt"/> + </attribute> + </define> + <define name="qcow2_cache_clean_interval"> + <attribute name='cache_clean_interval'> + <ref name="unsignedInt"/>> + </attribute> + </define>
These would all be unsignedLong values
<define name="controller"> <element name="controller"> <optional> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 2fc1fc3..c7d4b9b 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -5673,6 +5673,28 @@ virDomainDeviceLoadparmIsValid(const char *loadparm)
static void +virDoaminQcow2CacheOptionsFormat(virBufferPtr buf,
Domain Also, I think if you follow the virDomainDiskSourceFormatInternal model, this changes to take as input a driverQcow2Buf pointer... and the following changes:
+ virDomainDiskDefPtr def) +{ + virBuffer qcow2Buff = VIR_BUFFER_INITIALIZER;
Remove the above, add: + if (def->src->l2_cache_size == 0 && + def->src->refcount_cache_size == 0 && + def->src->cache_clean_interval == 0) + return; + + virBufferAddLit(driverQcow2Buf, "<qcow2"); +
+ if (def->src->l2_cache_size > 0) + virBufferAsprintf(&qcow2Buff, " l2_cache_size='%llu'", + def->src->l2_cache_size); + if (def->src->refcount_cache_size > 0) + virBufferAsprintf(&qcow2Buff, " refcount_cache_size='%llu'", + def->src->refcount_cache_size); + if (def->src->cache_clean_interval > 0) + virBufferAsprintf(&qcow2Buff, " cache_clean_interval='%llu'", + def->src->cache_clean_interval);
Change all the above &qcow2Buff w/ driverQcow2Buf, then alter then remove all the following and replace with: + virBufferAddLit(driverQcow2Buf, "/>\n"); see below [1] for more context
+ + if (virBufferUse(&qcow2Buff)) { + virBufferAddLit(buf, "<qcow2"); + virBufferAddBuffer(buf, &qcow2Buff); + virBufferAddLit(buf, "/>\n");> + } +} +
Another blank line
+static void virDomainVirtioOptionsFormat(virBufferPtr buf, virDomainVirtioOptionsPtr virtio) { @@ -8511,15 +8533,69 @@ virDomainDiskDefParseValidate(const virDomainDiskDef *def) } }
+ if (def->src->format != VIR_STORAGE_FILE_QCOW2 && + (def->src->l2_cache_size > 0 || def->src->refcount_cache_size > 0 || + def->src->cache_clean_interval > 0)) { + virReportError(VIR_ERR_XML_ERROR, + _("Setting l2_cache_size, refcount_cache_size, " + "cache_clean_interval is not allowed for types " + "other than QCOW2")); + return -1; + } +
Consider my earlier comment is there any setting of the cache attribute that needs to also be checked? It's also dawning on me the strangeness of seeing "cache='none'" attribute and the various cache attributes for the qcow2 sub element.
return 0; }
static int +virDomainDiskDefQcow2ParseXML(virDomainDiskDefPtr def, + xmlNodePtr cur) +{ + char *tmp = NULL; + int ret = -1; + + if ((tmp = virXMLPropString(cur, "l2_cache_size")) && + (virStrToLong_ullp(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; + } + VIR_FREE(tmp); + + if ((tmp = virXMLPropString(cur, "refcount_cache_size")) && + (virStrToLong_ullp(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; + } + VIR_FREE(tmp); + + if ((tmp = virXMLPropString(cur, "cache_clean_interval")) && + (virStrToLong_ullp(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; + } + VIR_FREE(tmp);
superfluous, but no big deal
+ + ret = 0; + + cleanup: + VIR_FREE(tmp); + + return ret; +} + + +static int virDomainDiskDefDriverParseXML(virDomainDiskDefPtr def, xmlNodePtr cur) { char *tmp = NULL; + xmlNodePtr child; int ret = -1;
def->src->driverName = virXMLPropString(cur, "name"); @@ -8622,6 +8698,12 @@ virDomainDiskDefDriverParseXML(virDomainDiskDefPtr def, } VIR_FREE(tmp);
+ for (child = cur->children; child != NULL; child = child->next) { + if (virXMLNodeNameEqual(child, "qcow2") && + virDomainDiskDefQcow2ParseXML(def, child) < 0) { + goto cleanup; + } + }
Add a blank line
ret = 0;
cleanup: @@ -21908,7 +21990,18 @@ virDomainDiskDefFormat(virBufferPtr buf,
[1] Add: + virBuffer driverQcow2Buf = VIR_BUFFER_INITIALIZER; below driverBuf and the rest of this changes to: + virBufferSetChildIndent(&driverQcow2Buf, buf); //&driverBuf); + virDomainQcow2CacheOptionsFormat(&driverQcow2Buf, def); + + if (virXMLFormatElement(buf, "driver", &driverBuf, &driverQcow2Buf) < 0) + return -1; Slick and compact!
if (virBufferUse(&driverBuf)) { virBufferAddLit(buf, "<driver"); virBufferAddBuffer(buf, &driverBuf); - virBufferAddLit(buf, "/>\n"); + + if (def->src->l2_cache_size == 0 && + def->src->refcount_cache_size == 0 && + def->src->cache_clean_interval == 0) { + virBufferAddLit(buf, "/>\n"); + } else { + virBufferAddLit(buf, ">\n"); + virBufferAdjustIndent(buf, 2); + virDoaminQcow2CacheOptionsFormat(buf, def); + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</driver>\n"); + } }
if (def->src->auth) { diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index ed8cb6e..391aaba 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -1433,6 +1433,12 @@ qemuBuildDriveSourceStr(virDomainDiskDefPtr disk, qemuformat = "luks"; virBufferAsprintf(buf, "format=%s,", qemuformat); } + if (disk->src->l2_cache_size > 0) + virBufferAsprintf(buf, "l2-cache-size=%llu,", disk->src->l2_cache_size); + if (disk->src->refcount_cache_size > 0) + virBufferAsprintf(buf, "refcount-cache-size=%llu,", disk->src->refcount_cache_size); + if (disk->src->cache_clean_interval > 0) + virBufferAsprintf(buf, "cache-clean-interval=%llu,", disk->src->cache_clean_interval);
These don't belong in this patch, they belong in the next patch. We're not adding the .args here. I can make all the above changes for you - not a problem. But please let me know your thoughts on whether we should keep the sizing recommendation in formatdomain.html.in or just point at the qemu source document. It's a fine line - I like the example, but I also see the downside. John
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..9b5a5f3 100644 --- a/src/util/virstoragefile.h +++ b/src/util/virstoragefile.h @@ -280,6 +280,12 @@ 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 long long l2_cache_size; /* qcow2 l2 cache size */ + /* qcow2 reference count table cache size */ + unsigned long long refcount_cache_size; + /* clean unused cache entries interval */ + unsigned long long cache_clean_interval; };
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-qcow2-cache.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-qcow2-cache.xml new file mode 100644 index 0000000..3f464db --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-qcow2-cache.xml @@ -0,0 +1,43 @@ +<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='block' device='disk'> + <driver name='qemu' type='qcow2' cache='none'> + <qcow2 l2_cache_size='2097152' refcount_cache_size='524288' cache_clean_interval='900'/> + </driver> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <disk type='block' device='cdrom'> + <driver name='qemu' type='raw'/> + <source dev='/dev/HostVG/QEMUGuest2'/> + <target dev='hdc' bus='ide'/> + <readonly/> + <address type='drive' controller='0' bus='1' target='0' unit='0'/> + </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/qemuxml2xmloutdata/qemuxml2xmlout-disk-drive-qcow2-cache.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-disk-drive-qcow2-cache.xml new file mode 100644 index 0000000..3f464db --- /dev/null +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-disk-drive-qcow2-cache.xml @@ -0,0 +1,43 @@ +<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='block' device='disk'> + <driver name='qemu' type='qcow2' cache='none'> + <qcow2 l2_cache_size='2097152' refcount_cache_size='524288' cache_clean_interval='900'/> + </driver> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <disk type='block' device='cdrom'> + <driver name='qemu' type='raw'/> + <source dev='/dev/HostVG/QEMUGuest2'/> + <target dev='hdc' bus='ide'/> + <readonly/> + <address type='drive' controller='0' bus='1' target='0' unit='0'/> + </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 97ff36c..1ffb831 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -461,6 +461,7 @@ mymain(void) DO_TEST("disk-drive-cache-v2-none", NONE); DO_TEST("disk-drive-cache-directsync", NONE); DO_TEST("disk-drive-cache-unsafe", NONE); + DO_TEST("disk-drive-qcow2-cache", NONE); DO_TEST("disk-drive-network-nbd", NONE); DO_TEST("disk-drive-network-nbd-export", NONE); DO_TEST("disk-drive-network-nbd-ipv6", NONE);

On Tue, Sep 12, 2017 at 05:21:53PM -0400, John Ferlan wrote:
On 09/07/2017 02:09 AM, Liu Qing wrote:
Random write IOPS will drop dramatically if qcow2 l2 cache could not cover the whole disk. This patch gives libvirt user a chance to adjust the qcow2 cache configuration.
Three new qcow2 driver parameters are added. They are l2-cache-size, refcount-cache-size and cache-clean-interval.
The following are from qcow2-cache.txt. The amount of virtual disk that can be mapped by the L2 and refcount caches (in bytes) is: disk_size = l2_cache_size * cluster_size / 8 disk_size = refcount_cache_size * cluster_size * 8 / refcount_bits
The parameter "cache-clean-interval" defines an interval (in seconds). All cache entries that haven't been accessed during that interval are removed from memory.
Suggestion, rewrite a bit:
Three new qcow2 driver parameters (l2-cache-size, refcount-cache-size and cache-clean-interval) are added as attributes to a new <qcow2> subelement for a <driver name='qemu' type='qcow2'...> of a <disk> element. The QEMU source docs/qcow2-cache.txt provides the guidelines for defining/configuring values for each.
...
That is - let's not bother with repeating what's in the document since it can change, but provide enough information that someone with curiosity would know where to look.
I am thinking add a web link but afraid of 404 error when the link is not accessable. A indirect link like docs/qcow2-cache.txt is a good idea.
Question from me: does "cache='none'" need to be set in the <driver> element for this to work properly? Do any of the cache values make sense? If it must be none, then we need to check that. If something doesn't make ense, we need to check that too.
The cache attribute in driver element is how qemu will deals with page cache of qcow2 file on the host. When opening a qcow2 file on host, the oflag will be dertimined by cache. L2 and refcount tables are metadatas of qcow2. So cache='xxx' determines how the guest data will be cached, and l2/refcount table cache controls the metadata cache.
if (def->src->auth) { diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index ed8cb6e..391aaba 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -1433,6 +1433,12 @@ qemuBuildDriveSourceStr(virDomainDiskDefPtr disk, qemuformat = "luks"; virBufferAsprintf(buf, "format=%s,", qemuformat); } + if (disk->src->l2_cache_size > 0) + virBufferAsprintf(buf, "l2-cache-size=%llu,", disk->src->l2_cache_size); + if (disk->src->refcount_cache_size > 0) + virBufferAsprintf(buf, "refcount-cache-size=%llu,", disk->src->refcount_cache_size); + if (disk->src->cache_clean_interval > 0) + virBufferAsprintf(buf, "cache-clean-interval=%llu,", disk->src->cache_clean_interval);
These don't belong in this patch, they belong in the next patch. We're not adding the .args here.
I can make all the above changes for you - not a problem. But please let me know your thoughts on whether we should keep the sizing recommendation in formatdomain.html.in or just point at the qemu source document. It's a fine line - I like the example, but I also see the downside. A point to source document is fine. I have done all the modifications in v5. If any missing please let me know. Thanks. Qing
John

Add qemu capabilities QEMU_CAPS_L2_CACHE_SIZE, QEMU_CAPS_REFCOUNT_CACHE_SIZE, QEMU_CAPS_CACHE_CLEAN_INTERVAL. Add testing for the above qemu capabilities. Signed-off-by: Liu Qing <liuqing@huayun.com> --- Patch 2 - a) use QMP instead of qemu version to identify qemu capabilities. b) change capablity names with prefix drive.qcow2. c) merge the three test cases to one. src/qemu/qemu_capabilities.c | 9 +++++ src/qemu/qemu_capabilities.h | 3 ++ src/qemu/qemu_command.c | 39 ++++++++++++++++++---- tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml | 3 ++ .../caps_2.6.0-gicv2.aarch64.xml | 3 ++ .../caps_2.6.0-gicv3.aarch64.xml | 3 ++ tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.xml | 3 ++ tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml | 3 ++ tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml | 3 ++ tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml | 3 ++ tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml | 3 ++ tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml | 3 ++ tests/qemucapabilitiesdata/caps_2.9.0.ppc64le.xml | 3 ++ tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml | 3 ++ tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml | 3 ++ .../qemuxml2argv-disk-drive-qcow2-cache.args | 28 ++++++++++++++++ tests/qemuxml2argvtest.c | 4 +++ 17 files changed, 113 insertions(+), 6 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-qcow2-cache.args diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index e7ea6f4..e8cce38 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -439,6 +439,9 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST, "virtio-net.tx_queue_size", "chardev-reconnect", "virtio-gpu.max_outputs", + "drive.qcow2.l2-cache-size", + "drive.qcow2.refcount-cache-size", + "drive.qcow2.cache-clean-interval", ); @@ -1811,6 +1814,12 @@ static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsIntelIOMMU[] = { static struct virQEMUCapsStringFlags virQEMUCapsQMPSchemaQueries[] = { { "blockdev-add/arg-type/options/+gluster/debug-level", QEMU_CAPS_GLUSTER_DEBUG_LEVEL}, { "blockdev-add/arg-type/+gluster/debug", QEMU_CAPS_GLUSTER_DEBUG_LEVEL}, + { "blockdev-add/arg-type/options/+qcow2/l2-cache-size", QEMU_CAPS_DRIVE_QCOW2_L2_CACHE_SIZE}, + { "blockdev-add/arg-type/options/+qcow2/refcount-cache-size", QEMU_CAPS_DRIVE_QCOW2_REFCOUNT_CACHE_SIZE}, + { "blockdev-add/arg-type/options/+qcow2/cache-clean-interval", QEMU_CAPS_DRIVE_QCOW2_CACHE_CLEAN_INTERVAL}, + { "blockdev-add/arg-type/+qcow2/l2-cache-size", QEMU_CAPS_DRIVE_QCOW2_L2_CACHE_SIZE}, + { "blockdev-add/arg-type/+qcow2/refcount-cache-size", QEMU_CAPS_DRIVE_QCOW2_REFCOUNT_CACHE_SIZE}, + { "blockdev-add/arg-type/+qcow2/cache-clean-interval", QEMU_CAPS_DRIVE_QCOW2_CACHE_CLEAN_INTERVAL}, }; struct virQEMUCapsObjectTypeProps { diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index f32687d..81fb759 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -425,6 +425,9 @@ typedef enum { QEMU_CAPS_VIRTIO_NET_TX_QUEUE_SIZE, /* virtio-net-*.tx_queue_size */ QEMU_CAPS_CHARDEV_RECONNECT, /* -chardev reconnect */ QEMU_CAPS_VIRTIO_GPU_MAX_OUTPUTS, /* -device virtio-(vga|gpu-*),max-outputs= */ + QEMU_CAPS_DRIVE_QCOW2_L2_CACHE_SIZE, /* -drive support qcow2 l2 cache size */ + QEMU_CAPS_DRIVE_QCOW2_REFCOUNT_CACHE_SIZE, /* -drive support qcow2 refcount cache size */ + QEMU_CAPS_DRIVE_QCOW2_CACHE_CLEAN_INTERVAL, /* -drive qcow2 cache clean interval */ QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 391aaba..e2592e0 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -1433,12 +1433,39 @@ qemuBuildDriveSourceStr(virDomainDiskDefPtr disk, qemuformat = "luks"; virBufferAsprintf(buf, "format=%s,", qemuformat); } - if (disk->src->l2_cache_size > 0) - virBufferAsprintf(buf, "l2-cache-size=%llu,", disk->src->l2_cache_size); - if (disk->src->refcount_cache_size > 0) - virBufferAsprintf(buf, "refcount-cache-size=%llu,", disk->src->refcount_cache_size); - if (disk->src->cache_clean_interval > 0) - virBufferAsprintf(buf, "cache-clean-interval=%llu,", disk->src->cache_clean_interval); + + if (disk->src->l2_cache_size > 0) { + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_QCOW2_L2_CACHE_SIZE)) { + virBufferAsprintf(buf, "l2-cache-size=%llu,", + disk->src->l2_cache_size); + } else { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("l2-cache-size is not supported by this QEMU")); + goto cleanup; + } + } + + if (disk->src->refcount_cache_size > 0) { + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_QCOW2_REFCOUNT_CACHE_SIZE)) { + virBufferAsprintf(buf, "refcount-cache-size=%llu,", + disk->src->refcount_cache_size); + } else { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("refcount-cache-size is not supported by this QEMU")); + goto cleanup; + } + } + + if (disk->src->cache_clean_interval > 0) { + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_QCOW2_CACHE_CLEAN_INTERVAL)) { + virBufferAsprintf(buf, "cache-clean-interval=%llu,", + disk->src->cache_clean_interval); + } else { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("cache-clean-interval is not supported by this QEMU")); + goto cleanup; + } + } ret = 0; diff --git a/tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml index 2ba40fc..2ccaca8 100644 --- a/tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml @@ -194,6 +194,9 @@ <flag name='vnc-multi-servers'/> <flag name='chardev-reconnect'/> <flag name='virtio-gpu.max_outputs'/> + <flag name='drive.qcow2.l2-cache-size'/> + <flag name='drive.qcow2.refcount-cache-size'/> + <flag name='drive.qcow2.cache-clean-interval'/> <version>2005000</version> <kvmVersion>0</kvmVersion> <package></package> diff --git a/tests/qemucapabilitiesdata/caps_2.6.0-gicv2.aarch64.xml b/tests/qemucapabilitiesdata/caps_2.6.0-gicv2.aarch64.xml index 0b34fa3..2438de2 100644 --- a/tests/qemucapabilitiesdata/caps_2.6.0-gicv2.aarch64.xml +++ b/tests/qemucapabilitiesdata/caps_2.6.0-gicv2.aarch64.xml @@ -172,6 +172,9 @@ <flag name='vnc-multi-servers'/> <flag name='chardev-reconnect'/> <flag name='virtio-gpu.max_outputs'/> + <flag name='drive.qcow2.l2-cache-size'/> + <flag name='drive.qcow2.refcount-cache-size'/> + <flag name='drive.qcow2.cache-clean-interval'/> <version>2006000</version> <kvmVersion>0</kvmVersion> <package></package> diff --git a/tests/qemucapabilitiesdata/caps_2.6.0-gicv3.aarch64.xml b/tests/qemucapabilitiesdata/caps_2.6.0-gicv3.aarch64.xml index d41d578..b677d40 100644 --- a/tests/qemucapabilitiesdata/caps_2.6.0-gicv3.aarch64.xml +++ b/tests/qemucapabilitiesdata/caps_2.6.0-gicv3.aarch64.xml @@ -172,6 +172,9 @@ <flag name='vnc-multi-servers'/> <flag name='chardev-reconnect'/> <flag name='virtio-gpu.max_outputs'/> + <flag name='drive.qcow2.l2-cache-size'/> + <flag name='drive.qcow2.refcount-cache-size'/> + <flag name='drive.qcow2.cache-clean-interval'/> <version>2006000</version> <kvmVersion>0</kvmVersion> <package></package> diff --git a/tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.xml b/tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.xml index f1c9fc9..a680b62 100644 --- a/tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.xml +++ b/tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.xml @@ -167,6 +167,9 @@ <flag name='vnc-multi-servers'/> <flag name='chardev-reconnect'/> <flag name='virtio-gpu.max_outputs'/> + <flag name='drive.qcow2.l2-cache-size'/> + <flag name='drive.qcow2.refcount-cache-size'/> + <flag name='drive.qcow2.cache-clean-interval'/> <version>2006000</version> <kvmVersion>0</kvmVersion> <package></package> diff --git a/tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml index bdf006f..0ebf8a2 100644 --- a/tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml @@ -204,6 +204,9 @@ <flag name='vnc-multi-servers'/> <flag name='chardev-reconnect'/> <flag name='virtio-gpu.max_outputs'/> + <flag name='drive.qcow2.l2-cache-size'/> + <flag name='drive.qcow2.refcount-cache-size'/> + <flag name='drive.qcow2.cache-clean-interval'/> <version>2006000</version> <kvmVersion>0</kvmVersion> <package></package> diff --git a/tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml index fe7bca9..44bc54c 100644 --- a/tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml +++ b/tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml @@ -134,6 +134,9 @@ <flag name='vnc-multi-servers'/> <flag name='chardev-reconnect'/> <flag name='virtio-gpu.max_outputs'/> + <flag name='drive.qcow2.l2-cache-size'/> + <flag name='drive.qcow2.refcount-cache-size'/> + <flag name='drive.qcow2.cache-clean-interval'/> <version>2007000</version> <kvmVersion>0</kvmVersion> <package></package> diff --git a/tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml index 3fd28f0..3b6c1ed 100644 --- a/tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml @@ -207,6 +207,9 @@ <flag name='vnc-multi-servers'/> <flag name='chardev-reconnect'/> <flag name='virtio-gpu.max_outputs'/> + <flag name='drive.qcow2.l2-cache-size'/> + <flag name='drive.qcow2.refcount-cache-size'/> + <flag name='drive.qcow2.cache-clean-interval'/> <version>2007000</version> <kvmVersion>0</kvmVersion> <package> (v2.7.0)</package> diff --git a/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml index 21bbb82..85f39fb 100644 --- a/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml +++ b/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml @@ -136,6 +136,9 @@ <flag name='vnc-multi-servers'/> <flag name='chardev-reconnect'/> <flag name='virtio-gpu.max_outputs'/> + <flag name='drive.qcow2.l2-cache-size'/> + <flag name='drive.qcow2.refcount-cache-size'/> + <flag name='drive.qcow2.cache-clean-interval'/> <version>2007093</version> <kvmVersion>0</kvmVersion> <package></package> diff --git a/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml index 761f9d1..d673891 100644 --- a/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml @@ -209,6 +209,9 @@ <flag name='vnc-multi-servers'/> <flag name='chardev-reconnect'/> <flag name='virtio-gpu.max_outputs'/> + <flag name='drive.qcow2.l2-cache-size'/> + <flag name='drive.qcow2.refcount-cache-size'/> + <flag name='drive.qcow2.cache-clean-interval'/> <version>2008000</version> <kvmVersion>0</kvmVersion> <package> (v2.8.0)</package> diff --git a/tests/qemucapabilitiesdata/caps_2.9.0.ppc64le.xml b/tests/qemucapabilitiesdata/caps_2.9.0.ppc64le.xml index a373a6d..b093244 100644 --- a/tests/qemucapabilitiesdata/caps_2.9.0.ppc64le.xml +++ b/tests/qemucapabilitiesdata/caps_2.9.0.ppc64le.xml @@ -172,6 +172,9 @@ <flag name='vnc-multi-servers'/> <flag name='chardev-reconnect'/> <flag name='virtio-gpu.max_outputs'/> + <flag name='drive.qcow2.l2-cache-size'/> + <flag name='drive.qcow2.refcount-cache-size'/> + <flag name='drive.qcow2.cache-clean-interval'/> <version>2009000</version> <kvmVersion>0</kvmVersion> <package> (v2.9.0)</package> diff --git a/tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml index e80782c..beba716 100644 --- a/tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml +++ b/tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml @@ -137,6 +137,9 @@ <flag name='vnc-multi-servers'/> <flag name='chardev-reconnect'/> <flag name='virtio-gpu.max_outputs'/> + <flag name='drive.qcow2.l2-cache-size'/> + <flag name='drive.qcow2.refcount-cache-size'/> + <flag name='drive.qcow2.cache-clean-interval'/> <version>2009000</version> <kvmVersion>0</kvmVersion> <package></package> diff --git a/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml index 3641d03..64b99b0 100644 --- a/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml @@ -220,6 +220,9 @@ <flag name='vnc-multi-servers'/> <flag name='chardev-reconnect'/> <flag name='virtio-gpu.max_outputs'/> + <flag name='drive.qcow2.l2-cache-size'/> + <flag name='drive.qcow2.refcount-cache-size'/> + <flag name='drive.qcow2.cache-clean-interval'/> <version>2009000</version> <kvmVersion>0</kvmVersion> <package> (v2.9.0)</package> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-qcow2-cache.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-qcow2-cache.args new file mode 100644 index 0000000..d13be92 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-qcow2-cache.args @@ -0,0 +1,28 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/home/test \ +USER=test \ +LOGNAME=test \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-i686 \ +-name QEMUGuest1 \ +-S \ +-M pc \ +-m 214 \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-nographic \ +-nodefaults \ +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\ +server,nowait \ +-mon chardev=charmonitor,id=monitor,mode=readline \ +-no-acpi \ +-boot c \ +-usb \ +-drive file=/dev/HostVG/QEMUGuest1,format=qcow2,l2-cache-size=2097152,\ +refcount-cache-size=524288,cache-clean-interval=900,if=none,id=drive-ide0-0-0,\ +cache=none \ +-device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \ +-drive file=/dev/HostVG/QEMUGuest2,format=raw,if=none,media=cdrom,\ +id=drive-ide0-1-0,readonly=on \ +-device ide-drive,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0 diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index d6ada22..5baad68 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -910,6 +910,10 @@ mymain(void) QEMU_CAPS_DRIVE_CACHE_UNSAFE); DO_TEST("disk-drive-copy-on-read", QEMU_CAPS_DRIVE_COPY_ON_READ); + DO_TEST("disk-drive-qcow2-cache", + QEMU_CAPS_DRIVE_QCOW2_L2_CACHE_SIZE, + QEMU_CAPS_DRIVE_QCOW2_REFCOUNT_CACHE_SIZE, + QEMU_CAPS_DRIVE_QCOW2_CACHE_CLEAN_INTERVAL); DO_TEST("disk-drive-network-nbd", NONE); DO_TEST("disk-drive-network-nbd-export", NONE); DO_TEST("disk-drive-network-nbd-ipv6", NONE); -- 1.8.3.1

On 09/07/2017 02:09 AM, Liu Qing wrote:
Add qemu capabilities QEMU_CAPS_L2_CACHE_SIZE, QEMU_CAPS_REFCOUNT_CACHE_SIZE, QEMU_CAPS_CACHE_CLEAN_INTERVAL. Add testing for the above qemu capabilities.
Signed-off-by: Liu Qing <liuqing@huayun.com> ---
Patch 2 - a) use QMP instead of qemu version to identify qemu capabilities. b) change capablity names with prefix drive.qcow2. c) merge the three test cases to one.
src/qemu/qemu_capabilities.c | 9 +++++ src/qemu/qemu_capabilities.h | 3 ++ src/qemu/qemu_command.c | 39 ++++++++++++++++++---- tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml | 3 ++ .../caps_2.6.0-gicv2.aarch64.xml | 3 ++ .../caps_2.6.0-gicv3.aarch64.xml | 3 ++ tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.xml | 3 ++ tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml | 3 ++ tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml | 3 ++ tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml | 3 ++ tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml | 3 ++ tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml | 3 ++ tests/qemucapabilitiesdata/caps_2.9.0.ppc64le.xml | 3 ++ tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml | 3 ++ tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml | 3 ++ .../qemuxml2argv-disk-drive-qcow2-cache.args | 28 ++++++++++++++++ tests/qemuxml2argvtest.c | 4 +++ 17 files changed, 113 insertions(+), 6 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-qcow2-cache.args
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index e7ea6f4..e8cce38 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -439,6 +439,9 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST, "virtio-net.tx_queue_size", "chardev-reconnect", "virtio-gpu.max_outputs",
The format of the data has every 5th element counted, so this needs before the following: /* 270 */
+ "drive.qcow2.l2-cache-size", + "drive.qcow2.refcount-cache-size", + "drive.qcow2.cache-clean-interval", );
@@ -1811,6 +1814,12 @@ static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsIntelIOMMU[] = { static struct virQEMUCapsStringFlags virQEMUCapsQMPSchemaQueries[] = { { "blockdev-add/arg-type/options/+gluster/debug-level", QEMU_CAPS_GLUSTER_DEBUG_LEVEL}, { "blockdev-add/arg-type/+gluster/debug", QEMU_CAPS_GLUSTER_DEBUG_LEVEL}, + { "blockdev-add/arg-type/options/+qcow2/l2-cache-size", QEMU_CAPS_DRIVE_QCOW2_L2_CACHE_SIZE}, + { "blockdev-add/arg-type/options/+qcow2/refcount-cache-size", QEMU_CAPS_DRIVE_QCOW2_REFCOUNT_CACHE_SIZE}, + { "blockdev-add/arg-type/options/+qcow2/cache-clean-interval", QEMU_CAPS_DRIVE_QCOW2_CACHE_CLEAN_INTERVAL}, + { "blockdev-add/arg-type/+qcow2/l2-cache-size", QEMU_CAPS_DRIVE_QCOW2_L2_CACHE_SIZE}, + { "blockdev-add/arg-type/+qcow2/refcount-cache-size", QEMU_CAPS_DRIVE_QCOW2_REFCOUNT_CACHE_SIZE}, + { "blockdev-add/arg-type/+qcow2/cache-clean-interval", QEMU_CAPS_DRIVE_QCOW2_CACHE_CLEAN_INTERVAL},
Ugh! I see the first 3 are necessary because of qemu changes similar to the +gluster debug setting, yuck. At least for that one, the argument appears to have changed name as well... Seems qemu 2.8 is the magic inflection point, though.
};
struct virQEMUCapsObjectTypeProps { diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index f32687d..81fb759 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -425,6 +425,9 @@ typedef enum { QEMU_CAPS_VIRTIO_NET_TX_QUEUE_SIZE, /* virtio-net-*.tx_queue_size */ QEMU_CAPS_CHARDEV_RECONNECT, /* -chardev reconnect */ QEMU_CAPS_VIRTIO_GPU_MAX_OUTPUTS, /* -device virtio-(vga|gpu-*),max-outputs= */
Similar formatting comment add before the following group: /* 270 */ Similar to patch1, I don't mind making the changes here. Especially since I already know I have some conflicts queued up in other patches on list that I'm trying to get reviewed/ACK'd. Secondarily, perhaps others may have comments about the new format and I'd rather see them addressed now rather than after pushing... John
+ QEMU_CAPS_DRIVE_QCOW2_L2_CACHE_SIZE, /* -drive support qcow2 l2 cache size */ + QEMU_CAPS_DRIVE_QCOW2_REFCOUNT_CACHE_SIZE, /* -drive support qcow2 refcount cache size */ + QEMU_CAPS_DRIVE_QCOW2_CACHE_CLEAN_INTERVAL, /* -drive qcow2 cache clean interval */
QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 391aaba..e2592e0 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -1433,12 +1433,39 @@ qemuBuildDriveSourceStr(virDomainDiskDefPtr disk, qemuformat = "luks"; virBufferAsprintf(buf, "format=%s,", qemuformat); } - if (disk->src->l2_cache_size > 0) - virBufferAsprintf(buf, "l2-cache-size=%llu,", disk->src->l2_cache_size); - if (disk->src->refcount_cache_size > 0) - virBufferAsprintf(buf, "refcount-cache-size=%llu,", disk->src->refcount_cache_size); - if (disk->src->cache_clean_interval > 0) - virBufferAsprintf(buf, "cache-clean-interval=%llu,", disk->src->cache_clean_interval); + + if (disk->src->l2_cache_size > 0) { + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_QCOW2_L2_CACHE_SIZE)) { + virBufferAsprintf(buf, "l2-cache-size=%llu,", + disk->src->l2_cache_size); + } else { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("l2-cache-size is not supported by this QEMU")); + goto cleanup; + } + } + + if (disk->src->refcount_cache_size > 0) { + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_QCOW2_REFCOUNT_CACHE_SIZE)) { + virBufferAsprintf(buf, "refcount-cache-size=%llu,", + disk->src->refcount_cache_size); + } else { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("refcount-cache-size is not supported by this QEMU")); + goto cleanup; + } + } + + if (disk->src->cache_clean_interval > 0) { + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_QCOW2_CACHE_CLEAN_INTERVAL)) { + virBufferAsprintf(buf, "cache-clean-interval=%llu,", + disk->src->cache_clean_interval); + } else { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("cache-clean-interval is not supported by this QEMU")); + goto cleanup; + } + }
ret = 0;
diff --git a/tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml index 2ba40fc..2ccaca8 100644 --- a/tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml @@ -194,6 +194,9 @@ <flag name='vnc-multi-servers'/> <flag name='chardev-reconnect'/> <flag name='virtio-gpu.max_outputs'/> + <flag name='drive.qcow2.l2-cache-size'/> + <flag name='drive.qcow2.refcount-cache-size'/> + <flag name='drive.qcow2.cache-clean-interval'/> <version>2005000</version> <kvmVersion>0</kvmVersion> <package></package> diff --git a/tests/qemucapabilitiesdata/caps_2.6.0-gicv2.aarch64.xml b/tests/qemucapabilitiesdata/caps_2.6.0-gicv2.aarch64.xml index 0b34fa3..2438de2 100644 --- a/tests/qemucapabilitiesdata/caps_2.6.0-gicv2.aarch64.xml +++ b/tests/qemucapabilitiesdata/caps_2.6.0-gicv2.aarch64.xml @@ -172,6 +172,9 @@ <flag name='vnc-multi-servers'/> <flag name='chardev-reconnect'/> <flag name='virtio-gpu.max_outputs'/> + <flag name='drive.qcow2.l2-cache-size'/> + <flag name='drive.qcow2.refcount-cache-size'/> + <flag name='drive.qcow2.cache-clean-interval'/> <version>2006000</version> <kvmVersion>0</kvmVersion> <package></package> diff --git a/tests/qemucapabilitiesdata/caps_2.6.0-gicv3.aarch64.xml b/tests/qemucapabilitiesdata/caps_2.6.0-gicv3.aarch64.xml index d41d578..b677d40 100644 --- a/tests/qemucapabilitiesdata/caps_2.6.0-gicv3.aarch64.xml +++ b/tests/qemucapabilitiesdata/caps_2.6.0-gicv3.aarch64.xml @@ -172,6 +172,9 @@ <flag name='vnc-multi-servers'/> <flag name='chardev-reconnect'/> <flag name='virtio-gpu.max_outputs'/> + <flag name='drive.qcow2.l2-cache-size'/> + <flag name='drive.qcow2.refcount-cache-size'/> + <flag name='drive.qcow2.cache-clean-interval'/> <version>2006000</version> <kvmVersion>0</kvmVersion> <package></package> diff --git a/tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.xml b/tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.xml index f1c9fc9..a680b62 100644 --- a/tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.xml +++ b/tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.xml @@ -167,6 +167,9 @@ <flag name='vnc-multi-servers'/> <flag name='chardev-reconnect'/> <flag name='virtio-gpu.max_outputs'/> + <flag name='drive.qcow2.l2-cache-size'/> + <flag name='drive.qcow2.refcount-cache-size'/> + <flag name='drive.qcow2.cache-clean-interval'/> <version>2006000</version> <kvmVersion>0</kvmVersion> <package></package> diff --git a/tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml index bdf006f..0ebf8a2 100644 --- a/tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml @@ -204,6 +204,9 @@ <flag name='vnc-multi-servers'/> <flag name='chardev-reconnect'/> <flag name='virtio-gpu.max_outputs'/> + <flag name='drive.qcow2.l2-cache-size'/> + <flag name='drive.qcow2.refcount-cache-size'/> + <flag name='drive.qcow2.cache-clean-interval'/> <version>2006000</version> <kvmVersion>0</kvmVersion> <package></package> diff --git a/tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml index fe7bca9..44bc54c 100644 --- a/tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml +++ b/tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml @@ -134,6 +134,9 @@ <flag name='vnc-multi-servers'/> <flag name='chardev-reconnect'/> <flag name='virtio-gpu.max_outputs'/> + <flag name='drive.qcow2.l2-cache-size'/> + <flag name='drive.qcow2.refcount-cache-size'/> + <flag name='drive.qcow2.cache-clean-interval'/> <version>2007000</version> <kvmVersion>0</kvmVersion> <package></package> diff --git a/tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml index 3fd28f0..3b6c1ed 100644 --- a/tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml @@ -207,6 +207,9 @@ <flag name='vnc-multi-servers'/> <flag name='chardev-reconnect'/> <flag name='virtio-gpu.max_outputs'/> + <flag name='drive.qcow2.l2-cache-size'/> + <flag name='drive.qcow2.refcount-cache-size'/> + <flag name='drive.qcow2.cache-clean-interval'/> <version>2007000</version> <kvmVersion>0</kvmVersion> <package> (v2.7.0)</package> diff --git a/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml index 21bbb82..85f39fb 100644 --- a/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml +++ b/tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml @@ -136,6 +136,9 @@ <flag name='vnc-multi-servers'/> <flag name='chardev-reconnect'/> <flag name='virtio-gpu.max_outputs'/> + <flag name='drive.qcow2.l2-cache-size'/> + <flag name='drive.qcow2.refcount-cache-size'/> + <flag name='drive.qcow2.cache-clean-interval'/> <version>2007093</version> <kvmVersion>0</kvmVersion> <package></package> diff --git a/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml index 761f9d1..d673891 100644 --- a/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml @@ -209,6 +209,9 @@ <flag name='vnc-multi-servers'/> <flag name='chardev-reconnect'/> <flag name='virtio-gpu.max_outputs'/> + <flag name='drive.qcow2.l2-cache-size'/> + <flag name='drive.qcow2.refcount-cache-size'/> + <flag name='drive.qcow2.cache-clean-interval'/> <version>2008000</version> <kvmVersion>0</kvmVersion> <package> (v2.8.0)</package> diff --git a/tests/qemucapabilitiesdata/caps_2.9.0.ppc64le.xml b/tests/qemucapabilitiesdata/caps_2.9.0.ppc64le.xml index a373a6d..b093244 100644 --- a/tests/qemucapabilitiesdata/caps_2.9.0.ppc64le.xml +++ b/tests/qemucapabilitiesdata/caps_2.9.0.ppc64le.xml @@ -172,6 +172,9 @@ <flag name='vnc-multi-servers'/> <flag name='chardev-reconnect'/> <flag name='virtio-gpu.max_outputs'/> + <flag name='drive.qcow2.l2-cache-size'/> + <flag name='drive.qcow2.refcount-cache-size'/> + <flag name='drive.qcow2.cache-clean-interval'/> <version>2009000</version> <kvmVersion>0</kvmVersion> <package> (v2.9.0)</package> diff --git a/tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml b/tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml index e80782c..beba716 100644 --- a/tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml +++ b/tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml @@ -137,6 +137,9 @@ <flag name='vnc-multi-servers'/> <flag name='chardev-reconnect'/> <flag name='virtio-gpu.max_outputs'/> + <flag name='drive.qcow2.l2-cache-size'/> + <flag name='drive.qcow2.refcount-cache-size'/> + <flag name='drive.qcow2.cache-clean-interval'/> <version>2009000</version> <kvmVersion>0</kvmVersion> <package></package> diff --git a/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml index 3641d03..64b99b0 100644 --- a/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml @@ -220,6 +220,9 @@ <flag name='vnc-multi-servers'/> <flag name='chardev-reconnect'/> <flag name='virtio-gpu.max_outputs'/> + <flag name='drive.qcow2.l2-cache-size'/> + <flag name='drive.qcow2.refcount-cache-size'/> + <flag name='drive.qcow2.cache-clean-interval'/> <version>2009000</version> <kvmVersion>0</kvmVersion> <package> (v2.9.0)</package> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-qcow2-cache.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-qcow2-cache.args new file mode 100644 index 0000000..d13be92 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-qcow2-cache.args @@ -0,0 +1,28 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/home/test \ +USER=test \ +LOGNAME=test \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-i686 \ +-name QEMUGuest1 \ +-S \ +-M pc \ +-m 214 \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-nographic \ +-nodefaults \ +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,\ +server,nowait \ +-mon chardev=charmonitor,id=monitor,mode=readline \ +-no-acpi \ +-boot c \ +-usb \ +-drive file=/dev/HostVG/QEMUGuest1,format=qcow2,l2-cache-size=2097152,\ +refcount-cache-size=524288,cache-clean-interval=900,if=none,id=drive-ide0-0-0,\ +cache=none \ +-device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \ +-drive file=/dev/HostVG/QEMUGuest2,format=raw,if=none,media=cdrom,\ +id=drive-ide0-1-0,readonly=on \ +-device ide-drive,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0 diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index d6ada22..5baad68 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -910,6 +910,10 @@ mymain(void) QEMU_CAPS_DRIVE_CACHE_UNSAFE); DO_TEST("disk-drive-copy-on-read", QEMU_CAPS_DRIVE_COPY_ON_READ); + DO_TEST("disk-drive-qcow2-cache", + QEMU_CAPS_DRIVE_QCOW2_L2_CACHE_SIZE, + QEMU_CAPS_DRIVE_QCOW2_REFCOUNT_CACHE_SIZE, + QEMU_CAPS_DRIVE_QCOW2_CACHE_CLEAN_INTERVAL); DO_TEST("disk-drive-network-nbd", NONE); DO_TEST("disk-drive-network-nbd-export", NONE); DO_TEST("disk-drive-network-nbd-ipv6", NONE);
participants (2)
-
John Ferlan
-
Liu Qing