[libvirt] [PATCH] qemu: add support for detect-zeroes feature

Maros Zatko mzatko at redhat.com
Fri Apr 24 12:38:49 UTC 2015


---
 docs/schemas/domaincommon.rng | 12 ++++++++++++
 src/conf/domain_conf.c        | 19 +++++++++++++++++++
 src/conf/domain_conf.h        | 10 ++++++++++
 src/libvirt_private.syms      |  1 +
 src/qemu/qemu_capabilities.c  |  6 +++++-
 src/qemu/qemu_capabilities.h  |  1 +
 src/qemu/qemu_command.c       | 11 +++++++++++
 7 files changed, 59 insertions(+), 1 deletion(-)

diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 03fd541..5a330d1 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -1683,6 +1683,9 @@
       <optional>
         <ref name="driverIOThread"/>
       </optional>
+      <optional>
+        <ref name="detect_zeroes"/>
+      </optional>
       <empty/>
     </element>
   </define>
@@ -1761,6 +1764,15 @@
       </choice>
     </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="driverIOThread">
     <attribute name='iothread'>
       <ref name="unsignedInt"/>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 4d7e3c9..e8f45ce 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -761,6 +761,11 @@ VIR_ENUM_IMPL(virDomainTPMModel, VIR_DOMAIN_TPM_MODEL_LAST,
 VIR_ENUM_IMPL(virDomainTPMBackend, VIR_DOMAIN_TPM_TYPE_LAST,
               "passthrough")
 
+VIR_ENUM_IMPL(virDomainDiskDetectZeroes, VIR_DOMAIN_DISK_DETECT_ZEROES_LAST,
+              "off",
+              "on",
+              "unmap")
+
 VIR_ENUM_IMPL(virDomainDiskDiscard, VIR_DOMAIN_DISK_DISCARD_LAST,
               "default",
               "unmap",
@@ -6079,6 +6084,7 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
     char *mirrorFormat = NULL;
     char *mirrorType = NULL;
     char *domain_name = NULL;
+    char *detect_zeroes = NULL;
     int expected_secret_usage = -1;
     int auth_secret_usage = -1;
     int ret = 0;
@@ -6215,6 +6221,7 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
                 event_idx = virXMLPropString(cur, "event_idx");
                 copy_on_read = virXMLPropString(cur, "copy_on_read");
                 discard = virXMLPropString(cur, "discard");
+                detect_zeroes = virXMLPropString(cur, "detect_zeroes");
                 driverIOThread = virXMLPropString(cur, "iothread");
             } else if (!def->mirror &&
                        xmlStrEqual(cur->name, BAD_CAST "mirror") &&
@@ -6802,6 +6809,14 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
         def->copy_on_read = cor;
     }
 
+    if (detect_zeroes) {
+        if ((def->detect_zeroes = virDomainDiskDetectZeroesTypeFromString(detect_zeroes)) <= 0) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                           _("unknown disk detect-zeroes mode '%s'"), detect_zeroes);
+            goto error;
+        }
+    }
+
     if (discard) {
         if ((def->discard = virDomainDiskDiscardTypeFromString(discard)) <= 0) {
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
@@ -6936,6 +6951,7 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
     VIR_FREE(mirrorType);
     VIR_FREE(mirrorFormat);
     VIR_FREE(domain_name);
+    VIR_FREE(detect_zeroes);
 
     ctxt->node = save_ctxt;
     return def;
@@ -17865,6 +17881,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,
@@ -17942,6 +17959,8 @@ virDomainDiskDefFormat(virBufferPtr buf,
             virBufferAsprintf(buf, " copy_on_read='%s'", copy_on_read);
         if (def->discard)
             virBufferAsprintf(buf, " discard='%s'", discard);
+        if (def->detect_zeroes)
+            virBufferAsprintf(buf, " detect-zeroes='%s'", detect_zeroes);
         if (def->iothread)
             virBufferAsprintf(buf, " iothread='%u'", def->iothread);
         virBufferAddLit(buf, "/>\n");
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index e6fa3c9..24a00eb 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -638,6 +638,14 @@ typedef enum {
     VIR_DOMAIN_DISK_DISCARD_LAST
 } virDomainDiskDiscard;
 
+typedef enum {
+    VIR_DOMAIN_DISK_DETECT_ZEROES_DEFAULT = 0,
+    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;
@@ -725,6 +733,7 @@ struct _virDomainDiskDef {
     int discard; /* enum virDomainDiskDiscard */
     unsigned int iothread; /* unused = 0, > 0 specific thread # */
     char *domain_name; /* backend domain name */
+    int detect_zeroes; /* enum virDomainDiskDetectZeroes */
 };
 
 
@@ -2906,6 +2915,7 @@ VIR_ENUM_DECL(virDomainDiskErrorPolicy)
 VIR_ENUM_DECL(virDomainDiskIo)
 VIR_ENUM_DECL(virDomainDeviceSGIO)
 VIR_ENUM_DECL(virDomainDiskTray)
+VIR_ENUM_DECL(virDomainDiskDetectZeroes)
 VIR_ENUM_DECL(virDomainDiskDiscard)
 VIR_ENUM_DECL(virDomainDiskMirrorState)
 VIR_ENUM_DECL(virDomainController)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 7166283..bfed1e3 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -246,6 +246,7 @@ virDomainDiskDefForeachPath;
 virDomainDiskDefFree;
 virDomainDiskDefNew;
 virDomainDiskDefSourceParse;
+virDomainDiskDetectZeroesTypeToString;
 virDomainDiskDeviceTypeToString;
 virDomainDiskDiscardTypeToString;
 virDomainDiskErrorPolicyTypeFromString;
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 3b49271..71cce9b 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -279,6 +279,8 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST,
               "qxl.vgamem_mb",
               "qxl-vga.vgamem_mb",
               "pc-dimm",
+
+              "detect_zeroes", /* 185 */
     );
 
 
@@ -1041,7 +1043,6 @@ virQEMUCapsComputeCmdFlags(const char *help,
 {
     const char *p;
     const char *fsdev, *netdev;
-
     if (strstr(help, "-no-kqemu"))
         virQEMUCapsSet(qemuCaps, QEMU_CAPS_KQEMU);
     if (strstr(help, "-enable-kqemu"))
@@ -1085,6 +1086,8 @@ virQEMUCapsComputeCmdFlags(const char *help,
             virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_COPY_ON_READ);
         if (strstr(help, "bps="))
             virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_IOTUNE);
+        if (strstr(help, "detect-zeroes="))
+            virQEMUCapsSet(qemuCaps, QEMU_CAPS_DRIVE_DETECT_ZEROES);
     }
     if ((p = strstr(help, "-vga")) && !strstr(help, "-std-vga")) {
         const char *nl = strstr(p, "\n");
@@ -2509,6 +2512,7 @@ struct virQEMUCapsCommandLineProps {
 static struct virQEMUCapsCommandLineProps virQEMUCapsCommandLine[] = {
     { "machine", "mem-merge", QEMU_CAPS_MEM_MERGE },
     { "drive", "discard", QEMU_CAPS_DRIVE_DISCARD },
+    { "drive", "detect-zeroes", QEMU_CAPS_DRIVE_DETECT_ZEROES },
     { "realtime", "mlock", QEMU_CAPS_MLOCK },
     { "boot-opts", "strict", QEMU_CAPS_BOOT_STRICT },
     { "boot-opts", "reboot-timeout", QEMU_CAPS_REBOOT_TIMEOUT },
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index c7b1ac7..7f41a20 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -224,6 +224,7 @@ typedef enum {
     QEMU_CAPS_QXL_VGAMEM         = 182, /* -device qxl.vgamem_mb */
     QEMU_CAPS_QXL_VGA_VGAMEM     = 183, /* -device qxl-vga.vgamem_mb */
     QEMU_CAPS_DEVICE_PC_DIMM     = 184, /* pc-dimm device */
+    QEMU_CAPS_DRIVE_DETECT_ZEROES = 185, /* -drive detect-zeroes */
 
     QEMU_CAPS_LAST,                   /* this must always be the last item */
 } virQEMUCapsFlags;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index e7e0937..3cef993 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -3801,6 +3801,17 @@ qemuBuildDriveStr(virConnectPtr conn,
         }
     }
 
+    if (disk->detect_zeroes) {
+        if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_DETECT_ZEROES)) {
+            virBufferAsprintf(&opt, ",detect-zeroes=%s",
+                              virDomainDiskDetectZeroesTypeToString(disk->detect_zeroes));
+        } else {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                           _("detect-zeroes is not supported by this QEMU binary"));
+            goto error;
+        }
+    }
+
     if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MONITOR_JSON)) {
         const char *wpolicy = NULL, *rpolicy = NULL;
 
-- 
1.9.3




More information about the libvir-list mailing list