commit 91ef4e05eac546f8ffdb18979cd21e4aee3dcbfd
Author: Matthias Dahl <mdvirt@designassembly.de>
Date:   Wed Apr 21 16:28:21 2010 +0200

    qemu aio: add XML parsing
    
    Allows io={threads|native} as an optional attribute to <driver>.
    
    Signed-off-by: Eric Blake <eblake@redhat.com>

Index: libvirt-0.7.6/AUTHORS
===================================================================
--- libvirt-0.7.6.orig/AUTHORS
+++ libvirt-0.7.6/AUTHORS
@@ -89,6 +89,7 @@ Patches have also been contributed by:
   Steve Yarmie         <steve.yarmie@gmail.com>
   Dan Kenigsberg       <danken@redhat.com>
   Yuji NISHIDA         <nishidy@nict.go.jp>
+  Matthias Dahl        <mdvirt@designassembly.de>
 
   [....send patches to get your name here....]
 
Index: libvirt-0.7.6/docs/formatdomain.html.in
===================================================================
--- libvirt-0.7.6.orig/docs/formatdomain.html.in
+++ libvirt-0.7.6/docs/formatdomain.html.in
@@ -525,12 +525,38 @@
         <span class="since">Since 0.0.3; <code>bus</code> attribute since 0.4.3;
         "usb" attribute value since after 0.4.4</span></dd>
       <dt><code>driver</code></dt>
-      <dd>If the hypervisor supports multiple backend drivers, then the optional
-        <code>driver</code> element allows them to be selected. The <code>name</code>
-        attribute is the primary backend driver name, while the optional <code>type</code>
-        attribute provides the sub-type. The optional <code>cache</code> attribute
-        controls the cache mechanism, possible values are "default", "none",
-        "writethrough" and "writeback". <span class="since">Since 0.1.8</span>
+      <dd>
+        The optional driver element allows specifying further details
+        related to the hypervisor driver used to provide the disk.
+        <span class="since">Since 0.1.8; <code>io</code> attribute
+        since 0.8.8</span>
+        <ul>
+          <li>
+            If the hypervisor supports multiple backend drivers, then
+            the <code>name</code> attribute selects the primary
+            backend driver name, while the optional <code>type</code>
+            attribute provides the sub-type.  For example, xen
+            supports a name of "tap", "tap2", "phy", or "file", with a
+            type of "aio", while qemu only supports a name of "qemu",
+            but multiple types including "raw", "bochs", "qcow2", and
+            "qed".
+          </li>
+          <li>
+            The optional <code>cache</code> attribute controls the
+            cache mechanism, possible values are "default", "none",
+            "writethrough" and "writeback".
+          </li>
+          <li>
+            The optional <code>error_policy</code> attribute controls
+            how the hypervisor will behave on an error, possible
+            values are "stop", "ignore", and "enospace".
+          </li>
+          <li>
+            The optional <code>io</code> attribute controls specific
+            policies on I/O; qemu guests support "threads" and
+            "native".
+          </li>
+        </ul>
       </dd>
       <dt><code>encryption</code></dt>
       <dd>If present, specifies how the volume is encrypted.  See
Index: libvirt-0.7.6/docs/schemas/domain.rng
===================================================================
--- libvirt-0.7.6.orig/docs/schemas/domain.rng
+++ libvirt-0.7.6/docs/schemas/domain.rng
@@ -599,6 +599,9 @@
           <ref name="driverCache"/>
         </group>
       </choice>
+      <optional>
+        <ref name="driverIO"/>
+      </optional>
       <empty/>
     </element>
   </define>
@@ -621,6 +624,14 @@
       </choice>
     </attribute>
   </define>
+  <define name="driverIO">
+    <attribute name="io">
+      <choice>
+        <value>threads</value>
+        <value>native</value>
+      </choice>
+    </attribute>
+  </define>
   <define name="controller">
     <element name="controller">
       <optional>
Index: libvirt-0.7.6/src/conf/domain_conf.c
===================================================================
--- libvirt-0.7.6.orig/src/conf/domain_conf.c
+++ libvirt-0.7.6/src/conf/domain_conf.c
@@ -130,6 +130,11 @@ VIR_ENUM_IMPL(virDomainDiskCache, VIR_DO
               "writethrough",
               "writeback")
 
+VIR_ENUM_IMPL(virDomainDiskIo, VIR_DOMAIN_DISK_IO_LAST,
+              "default",
+              "native",
+              "threads")
+
 VIR_ENUM_IMPL(virDomainController, VIR_DOMAIN_CONTROLLER_TYPE_LAST,
               "ide",
               "fdc",
@@ -1284,6 +1289,7 @@ virDomainDiskDefParseXML(virConnectPtr c
     char *target = NULL;
     char *bus = NULL;
     char *cachetag = NULL;
+    char *iotag = NULL;
     char *devaddr = NULL;
     virStorageEncryptionPtr encryption = NULL;
     char *serial = NULL;
@@ -1349,6 +1355,7 @@ virDomainDiskDefParseXML(virConnectPtr c
                 driverName = virXMLPropString(cur, "name");
                 driverType = virXMLPropString(cur, "type");
                 cachetag = virXMLPropString(cur, "cache");
+                iotag = virXMLPropString(cur, "io");
             } else if (xmlStrEqual(cur->name, BAD_CAST "readonly")) {
                 def->readonly = 1;
             } else if (xmlStrEqual(cur->name, BAD_CAST "shareable")) {
@@ -1465,6 +1472,15 @@ virDomainDiskDefParseXML(virConnectPtr c
         goto error;
     }
 
+    if (iotag) {
+        if ((def->iomode = virDomainDiskIoTypeFromString(iotag)) < 0 ||
+            def->iomode == VIR_DOMAIN_DISK_IO_DEFAULT) {
+            virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
+                                 _("unknown disk io mode '%s'"), iotag);
+            goto error;
+        }
+    }
+
     if (devaddr) {
         if (sscanf(devaddr, "%x:%x:%x",
                    &def->info.addr.pci.domain,
@@ -1516,6 +1532,7 @@ cleanup:
     VIR_FREE(driverType);
     VIR_FREE(driverName);
     VIR_FREE(cachetag);
+    VIR_FREE(iotag);
     VIR_FREE(devaddr);
     VIR_FREE(serial);
     virStorageEncryptionFree(encryption);
@@ -4915,6 +4932,7 @@ virDomainDiskDefFormat(virConnectPtr con
     const char *device = virDomainDiskDeviceTypeToString(def->device);
     const char *bus = virDomainDiskBusTypeToString(def->bus);
     const char *cachemode = virDomainDiskCacheTypeToString(def->cachemode);
+    const char *iomode = virDomainDiskIoTypeToString(def->iomode);
 
     if (!type) {
         virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
@@ -4936,6 +4954,11 @@ virDomainDiskDefFormat(virConnectPtr con
                              _("unexpected disk cache mode %d"), def->cachemode);
         return -1;
     }
+    if (!iomode) {
+        virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
+                             _("unexpected disk io mode %d"), def->iomode);
+        return -1;
+    }
 
     virBufferVSprintf(buf,
                       "    <disk type='%s' device='%s'>\n",
@@ -4947,6 +4970,8 @@ virDomainDiskDefFormat(virConnectPtr con
             virBufferVSprintf(buf, " type='%s'", def->driverType);
         if (def->cachemode)
             virBufferVSprintf(buf, " cache='%s'", cachemode);
+        if (def->iomode)
+            virBufferVSprintf(buf, " io='%s'", iomode);
         virBufferVSprintf(buf, "/>\n");
     }
 
Index: libvirt-0.7.6/src/conf/domain_conf.h
===================================================================
--- libvirt-0.7.6.orig/src/conf/domain_conf.h
+++ libvirt-0.7.6/src/conf/domain_conf.h
@@ -141,6 +141,14 @@ enum  virDomainDiskCache {
     VIR_DOMAIN_DISK_CACHE_LAST
 };
 
+enum  virDomainDiskIo {
+    VIR_DOMAIN_DISK_IO_DEFAULT,
+    VIR_DOMAIN_DISK_IO_NATIVE,
+    VIR_DOMAIN_DISK_IO_THREADS,
+
+    VIR_DOMAIN_DISK_IO_LAST
+};
+
 /* Stores the virtual disk configuration */
 typedef struct _virDomainDiskDef virDomainDiskDef;
 typedef virDomainDiskDef *virDomainDiskDefPtr;
@@ -154,6 +162,7 @@ struct _virDomainDiskDef {
     char *driverType;
     char *serial;
     int cachemode;
+    int iomode;
     unsigned int readonly : 1;
     unsigned int shared : 1;
     virDomainDeviceInfo info;
@@ -1015,6 +1024,7 @@ VIR_ENUM_DECL(virDomainDisk)
 VIR_ENUM_DECL(virDomainDiskDevice)
 VIR_ENUM_DECL(virDomainDiskBus)
 VIR_ENUM_DECL(virDomainDiskCache)
+VIR_ENUM_DECL(virDomainDiskIo)
 VIR_ENUM_DECL(virDomainController)
 VIR_ENUM_DECL(virDomainFS)
 VIR_ENUM_DECL(virDomainNet)
Index: libvirt-0.7.6/src/libvirt_private.syms
===================================================================
--- libvirt-0.7.6.orig/src/libvirt_private.syms
+++ libvirt-0.7.6/src/libvirt_private.syms
@@ -197,6 +197,8 @@ virDomainDefClearPCIAddresses;
 virDomainDefClearDeviceAliases;
 virDomainDeviceInfoIterate;
 virDomainDiskDefForeachPath;
+virDomainDiskIoTypeFromString;
+virDomainDiskIoTypeToString;
 virDomainClockOffsetTypeToString;
 virDomainClockOffsetTypeFromString;
 virDomainTimerNameTypeToString;
