Skip to content

Commit

Permalink
conf: Add support of zero-detection for disks
Browse files Browse the repository at this point in the history
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@redhat.com>
  • Loading branch information
nertpinx committed Jun 14, 2016
1 parent 7163143 commit d3c7849
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 1 deletion.
12 changes: 12 additions & 0 deletions docs/formatdomain.html.in
Original file line number Diff line number Diff line change
Expand Up @@ -2564,6 +2564,18 @@
(ignore the discard request).
<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
Expand Down
12 changes: 12 additions & 0 deletions docs/schemas/domaincommon.rng
Original file line number Diff line number Diff line change
Expand Up @@ -1618,6 +1618,9 @@
<optional>
<ref name="driverIOThread"/>
</optional>
<optional>
<ref name="detect_zeroes"/>
</optional>
<empty/>
</element>
</define>
Expand Down Expand Up @@ -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>
Expand Down
19 changes: 18 additions & 1 deletion src/conf/domain_conf.c
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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)
Expand All @@ -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");
}

Expand Down
11 changes: 11 additions & 0 deletions src/conf/domain_conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 */
};

Expand Down Expand Up @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions src/libvirt_private.syms
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,8 @@ virDomainDiskDefForeachPath;
virDomainDiskDefFree;
virDomainDiskDefNew;
virDomainDiskDefSourceParse;
virDomainDiskDetectZeroesTypeFromString;
virDomainDiskDetectZeroesTypeToString;
virDomainDiskDeviceTypeToString;
virDomainDiskDiscardTypeToString;
virDomainDiskErrorPolicyTypeFromString;
Expand Down
45 changes: 45 additions & 0 deletions tests/qemuxml2argvdata/qemuxml2argv-disk-drive-detect-zeroes.xml
Original file line number Diff line number Diff line change
@@ -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>
1 change: 1 addition & 0 deletions tests/qemuxml2xmltest.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down

0 comments on commit d3c7849

Please sign in to comment.