From d3c784999d39e20224801188464b048836159565 Mon Sep 17 00:00:00 2001 From: Martin Kletzander Date: Thu, 14 Apr 2016 22:32:54 +0200 Subject: [PATCH] conf: Add support of zero-detection for disks 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 --- 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 +++++++++++++++++++ ...emuxml2xmlout-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 fb3ec5ee3e..0ad2bbcc90 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -2564,6 +2564,18 @@ (ignore the discard request). Since 1.0.6 (QEMU and KVM only) +
  • + The optional detect_zeroes 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 discard above (it will act as "on" + if discard is set to "ignore"). NB enabling the + detection is a compute intensive operation, but can save file + space and/or time on slow media. + Since 1.3.6 +
  • The optional iothread attribute assigns the disk to an IOThread as defined by the range for the domain diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 02078d7346..2e07505b1a 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -1618,6 +1618,9 @@ + + + @@ -1702,6 +1705,15 @@ + + + + off + on + unmap + + + diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 10e61daf6d..9504e5f63f 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, "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 3792562f09..15f9c80d01 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 ec197a1df5..e939de3b28 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 0000000000..8953f50f3f --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-drive-detect-zeroes.xml @@ -0,0 +1,45 @@ + + test + 92d7a226-cfae-425b-a6d3-00bbf9ec5c9e + 1048576 + 1048576 + 1 + + hvm + + + + + + destroy + restart + restart + + /usr/bin/qemu + + + + +
    + + + + + + +
    + + +
    + + +
    + + + + + +
    + + + 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 0000000000..afa3199d4a --- /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 ba55919347..7db9cb7931 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"); -- GitLab