This option allows or disallows detection of zero-writes if it is set to
"on" or "off", respectively. It can be also set to "unmap"
in which
case it will try discarding that part of image based on the value of the
"discard" option.
Signed-off-by: Martin Kletzander <mkletzan(a)redhat.com>
---
docs/formatdomain.html.in | 12 ++++++
docs/schemas/domaincommon.rng | 12 ++++++
src/conf/domain_conf.c | 19 ++++++++-
src/conf/domain_conf.h | 11 ++++++
src/libvirt_private.syms | 2 +
.../qemuxml2argv-disk-drive-detect-zeroes.xml | 45 ++++++++++++++++++++++
.../qemuxml2xmlout-disk-drive-detect-zeroes.xml | 1 +
tests/qemuxml2xmltest.c | 1 +
8 files changed, 102 insertions(+), 1 deletion(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-detect-zeroes.xml
create mode 120000 tests/qemuxml2xmloutdata/qemuxml2xmlout-disk-drive-detect-zeroes.xml
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index fb3ec5ee3e29..0ad2bbcc90a2 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -2565,6 +2565,18 @@
<span class='since'>Since 1.0.6 (QEMU and KVM
only)</span>
</li>
<li>
+ The optional <code>detect_zeroes</code> attribute controls
whether
+ to detect zero write requests. The value can be "off",
"on" or
+ "unmap". First two values turn the detection off and on,
+ respectively. The third value ("unmap") turns the detection on
+ and additionally tries to discard such areas from the image based
+ on the value of <code>discard</code> above (it will act as
"on"
+ if <code>discard</code> is set to "ignore"). NB
enabling the
+ detection is a compute intensive operation, but can save file
+ space and/or time on slow media.
+ <span class='since'>Since 1.3.6</span>
+ </li>
+ <li>
The optional <code>iothread</code> attribute assigns the
disk to an IOThread as defined by the range for the domain
<a
href="#elementsIOThreadsAllocation"><code>iothreads</code></a>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 02078d73460a..2e07505b1a80 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -1618,6 +1618,9 @@
<optional>
<ref name="driverIOThread"/>
</optional>
+ <optional>
+ <ref name="detect_zeroes"/>
+ </optional>
<empty/>
</element>
</define>
@@ -1702,6 +1705,15 @@
<ref name="unsignedInt"/>
</attribute>
</define>
+ <define name="detect_zeroes">
+ <attribute name='detect_zeroes'>
+ <choice>
+ <value>off</value>
+ <value>on</value>
+ <value>unmap</value>
+ </choice>
+ </attribute>
+ </define>
<define name="controller">
<element name="controller">
<optional>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 10e61daf6dd4..9504e5f63f4f 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -807,6 +807,12 @@ VIR_ENUM_IMPL(virDomainDiskDiscard, VIR_DOMAIN_DISK_DISCARD_LAST,
"unmap",
"ignore")
+VIR_ENUM_IMPL(virDomainDiskDetectZeroes, VIR_DOMAIN_DISK_DETECT_ZEROES_LAST,
+ "default",
+ "off",
+ "on",
+ "unmap")
+
VIR_ENUM_IMPL(virDomainDiskMirrorState, VIR_DOMAIN_DISK_MIRROR_STATE_LAST,
"none",
"yes",
@@ -7378,6 +7384,14 @@ virDomainDiskDefDriverParseXML(virDomainDiskDefPtr def,
VIR_FREE(tmp);
}
+ if ((tmp = virXMLPropString(cur, "detect_zeroes")) &&
+ (def->detect_zeroes = virDomainDiskDetectZeroesTypeFromString(tmp)) <= 0)
{
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("unknown driver detect_zeroes value '%s'"),
tmp);
+ goto cleanup;
+ }
+ VIR_FREE(tmp);
+
ret = 0;
cleanup:
@@ -19631,6 +19645,7 @@ virDomainDiskDefFormat(virBufferPtr buf,
const char *copy_on_read = virTristateSwitchTypeToString(def->copy_on_read);
const char *sgio = virDomainDeviceSGIOTypeToString(def->sgio);
const char *discard = virDomainDiskDiscardTypeToString(def->discard);
+ const char *detect_zeroes =
virDomainDiskDetectZeroesTypeToString(def->detect_zeroes);
if (!type || !def->src->type) {
virReportError(VIR_ERR_INTERNAL_ERROR,
@@ -19685,7 +19700,7 @@ virDomainDiskDefFormat(virBufferPtr buf,
if (def->src->driverName || def->src->format > 0 || def->cachemode
||
def->error_policy || def->rerror_policy || def->iomode ||
def->ioeventfd || def->event_idx || def->copy_on_read ||
- def->discard || def->iothread) {
+ def->discard || def->iothread || def->detect_zeroes) {
virBufferAddLit(buf, "<driver");
virBufferEscapeString(buf, " name='%s'",
def->src->driverName);
if (def->src->format > 0)
@@ -19709,6 +19724,8 @@ virDomainDiskDefFormat(virBufferPtr buf,
virBufferAsprintf(buf, " discard='%s'", discard);
if (def->iothread)
virBufferAsprintf(buf, " iothread='%u'",
def->iothread);
+ if (def->detect_zeroes)
+ virBufferAsprintf(buf, " detect_zeroes='%s'",
detect_zeroes);
virBufferAddLit(buf, "/>\n");
}
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 3792562f0983..15f9c80d019a 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -528,6 +528,15 @@ typedef enum {
VIR_DOMAIN_DISK_DISCARD_LAST
} virDomainDiskDiscard;
+typedef enum {
+ VIR_DOMAIN_DISK_DETECT_ZEROES_DEFAULT = 0,
+ VIR_DOMAIN_DISK_DETECT_ZEROES_OFF,
+ VIR_DOMAIN_DISK_DETECT_ZEROES_ON,
+ VIR_DOMAIN_DISK_DETECT_ZEROES_UNMAP,
+
+ VIR_DOMAIN_DISK_DETECT_ZEROES_LAST
+} virDomainDiskDetectZeroes;
+
typedef struct _virDomainBlockIoTuneInfo virDomainBlockIoTuneInfo;
struct _virDomainBlockIoTuneInfo {
unsigned long long total_bytes_sec;
@@ -606,6 +615,7 @@ struct _virDomainDiskDef {
int sgio; /* enum virDomainDeviceSGIO */
int discard; /* enum virDomainDiskDiscard */
unsigned int iothread; /* unused = 0, > 0 specific thread # */
+ int detect_zeroes; /* enum virDomainDiskDetectZeroes */
char *domain_name; /* backend domain name */
};
@@ -2937,6 +2947,7 @@ VIR_ENUM_DECL(virDomainDiskIo)
VIR_ENUM_DECL(virDomainDeviceSGIO)
VIR_ENUM_DECL(virDomainDiskTray)
VIR_ENUM_DECL(virDomainDiskDiscard)
+VIR_ENUM_DECL(virDomainDiskDetectZeroes)
VIR_ENUM_DECL(virDomainDiskMirrorState)
VIR_ENUM_DECL(virDomainController)
VIR_ENUM_DECL(virDomainControllerModelPCI)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 85b9cd14ae7c..a1273bf09f05 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -267,6 +267,8 @@ virDomainDiskDefForeachPath;
virDomainDiskDefFree;
virDomainDiskDefNew;
virDomainDiskDefSourceParse;
+virDomainDiskDetectZeroesTypeFromString;
+virDomainDiskDetectZeroesTypeToString;
virDomainDiskDeviceTypeToString;
virDomainDiskDiscardTypeToString;
virDomainDiskErrorPolicyTypeFromString;
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-detect-zeroes.xml
b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-detect-zeroes.xml
new file mode 100644
index 000000000000..8953f50f3f92
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-detect-zeroes.xml
@@ -0,0 +1,45 @@
+<domain type='qemu'>
+ <name>test</name>
+ <uuid>92d7a226-cfae-425b-a6d3-00bbf9ec5c9e</uuid>
+ <memory unit='KiB'>1048576</memory>
+ <currentMemory unit='KiB'>1048576</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc-0.13'>hvm</type>
+ <boot dev='cdrom'/>
+ <boot dev='hd'/>
+ <bootmenu enable='yes'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>restart</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <disk type='file' device='disk'>
+ <driver name='qemu' type='qcow2' discard='unmap'
detect_zeroes='unmap'/>
+ <source file='/var/lib/libvirt/images/f14.img'/>
+ <target dev='vda' bus='virtio'/>
+ <address type='pci' domain='0x0000' bus='0x00'
slot='0x04' function='0x0'/>
+ </disk>
+ <disk type='file' device='cdrom'>
+ <driver discard='ignore' detect_zeroes='off'/>
+ <source file='/var/lib/libvirt/Fedora-14-x86_64-Live-KDE.iso'/>
+ <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='virtio'>
+ <address type='pci' domain='0x0000' bus='0x00'
slot='0x03' function='0x0'/>
+ </memballoon>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-disk-drive-detect-zeroes.xml
b/tests/qemuxml2xmloutdata/qemuxml2xmlout-disk-drive-detect-zeroes.xml
new file mode 120000
index 000000000000..afa3199d4a7e
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-disk-drive-detect-zeroes.xml
@@ -0,0 +1 @@
+../qemuxml2argvdata/qemuxml2argv-disk-drive-detect-zeroes.xml
\ No newline at end of file
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index ba559193478e..7db9cb793147 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -566,6 +566,7 @@ mymain(void)
DO_TEST("disk-source-pool-mode");
DO_TEST("disk-drive-discard");
+ DO_TEST("disk-drive-detect-zeroes");
DO_TEST("virtio-rng-random");
DO_TEST("virtio-rng-egd");
--
2.8.3