]> xenbits.xensource.com Git - libvirt.git/commitdiff
conf: Add support of zero-detection for disks
authorMartin Kletzander <mkletzan@redhat.com>
Thu, 14 Apr 2016 20:32:54 +0000 (22:32 +0200)
committerMartin Kletzander <mkletzan@redhat.com>
Tue, 14 Jun 2016 06:25:25 +0000 (08:25 +0200)
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>
docs/formatdomain.html.in
docs/schemas/domaincommon.rng
src/conf/domain_conf.c
src/conf/domain_conf.h
src/libvirt_private.syms
tests/qemuxml2argvdata/qemuxml2argv-disk-drive-detect-zeroes.xml [new file with mode: 0644]
tests/qemuxml2xmloutdata/qemuxml2xmlout-disk-drive-detect-zeroes.xml [new symlink]
tests/qemuxml2xmltest.c

index fb3ec5ee3e29eeb6a14f545058a9742016c50164..0ad2bbcc90a2119bfbbbb082638c3b47a0d3ce9b 100644 (file)
             (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
index 02078d73460a9b9fea29209dd75117418020ce86..2e07505b1a80f52b6b5ffb8c9b4bbcd10cc14fb7 100644 (file)
       <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>
index 10e61daf6dd41164639c3ebad74bb52b2b91c1a4..9504e5f63f4faf22bd2a24d87b63a6bdf4b4affe 100644 (file)
@@ -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");
     }
 
index 3792562f09831a2a0ffa406686bb71342e9d5a9a..15f9c80d019a87ccc4f78776052383d51f309040 100644 (file)
@@ -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)
index ec197a1df5d014a1a488a11997cd2c2bc8aa5bcf..e939de3b287d7ff5f01df72c7ec49432882fbd98 100644 (file)
@@ -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 (file)
index 0000000..8953f50
--- /dev/null
@@ -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 (symlink)
index 0000000..afa3199
--- /dev/null
@@ -0,0 +1 @@
+../qemuxml2argvdata/qemuxml2argv-disk-drive-detect-zeroes.xml
\ No newline at end of file
index ba559193478e42b7609a78ac70e8f297ce606a1c..7db9cb793147427d6980642246fe0155dae88989 100644 (file)
@@ -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");