(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
<optional>
<ref name="driverIOThread"/>
</optional>
+ <optional>
+ <ref name="detect_zeroes"/>
+ </optional>
<empty/>
</element>
</define>
<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>
"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",
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:
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,
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)
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");
}
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;
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 */
};
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)
virDomainDiskDefFree;
virDomainDiskDefNew;
virDomainDiskDefSourceParse;
+virDomainDiskDetectZeroesTypeFromString;
+virDomainDiskDetectZeroesTypeToString;
virDomainDiskDeviceTypeToString;
virDomainDiskDiscardTypeToString;
virDomainDiskErrorPolicyTypeFromString;
--- /dev/null
+<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>
--- /dev/null
+../qemuxml2argvdata/qemuxml2argv-disk-drive-detect-zeroes.xml
\ No newline at end of file
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");