[libvirt] [PATCH v4 2/3] hostdev: Add iSCSI hostdev XML

John Ferlan jferlan at redhat.com
Tue Aug 5 23:24:36 UTC 2014


Introduce a new structure to handle an iSCSI host device based on the
existing virDomainHostdevSubsysSCSI by adding a "protocol='iscsi'" to
the <source/> element.  The hostdev structure mimics the existing
<disk/> element for an iSCSI device (network) device. New XML is:

  <hostdev mode='subsystem' type='scsi' managed='yes'>
    <source protocol='iscsi' name='iqn.1992-01.com.example'>
      <host name='example.org' port='3260'/>
      <auth username='myname'>
        <secret type='iscsi' usage='mycluster_myname'/>
      </auth>
    </source>
    <address type='drive' controller='0' bus='0' target='2' unit='5'/>
  </hostdev>

The controller element will mimic the existing scsi_host code insomuch
as when 'lsi' and 'virtio-scsi' are used.

Signed-off-by: John Ferlan <jferlan at redhat.com>
---
Changes since v3:
  * Rework RNG to match comments from review 8/8
  * Move the <auth> inside the <source>
  * Modify the tests and html doc to match where the <auth> is found

 docs/formatdomain.html.in                          | 144 +++++++++++++-------
 docs/schemas/domaincommon.rng                      |  51 ++++++-
 src/conf/domain_conf.c                             | 150 ++++++++++++++++++---
 .../qemuxml2argv-hostdev-scsi-lsi-iscsi-auth.args  |  14 ++
 .../qemuxml2argv-hostdev-scsi-lsi-iscsi-auth.xml   |  46 +++++++
 .../qemuxml2argv-hostdev-scsi-lsi-iscsi.args       |  14 ++
 .../qemuxml2argv-hostdev-scsi-lsi-iscsi.xml        |  40 ++++++
 ...emuxml2argv-hostdev-scsi-virtio-iscsi-auth.args |  16 +++
 ...qemuxml2argv-hostdev-scsi-virtio-iscsi-auth.xml |  46 +++++++
 .../qemuxml2argv-hostdev-scsi-virtio-iscsi.args    |  16 +++
 .../qemuxml2argv-hostdev-scsi-virtio-iscsi.xml     |  40 ++++++
 tests/qemuxml2argvtest.c                           |  16 +++
 tests/qemuxml2xmltest.c                            |   5 +
 13 files changed, 529 insertions(+), 69 deletions(-)
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-lsi-iscsi-auth.args
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-lsi-iscsi-auth.xml
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-lsi-iscsi.args
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-lsi-iscsi.xml
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-virtio-iscsi-auth.args
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-virtio-iscsi-auth.xml
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-virtio-iscsi.args
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-virtio-iscsi.xml

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index e5b1adb..8b294bd 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -2824,57 +2824,107 @@
   </devices>
   ...</pre>
 
+
+    <p>or:</p>
+
+<pre>
+  ...
+  <devices>
+    <hostdev mode='subsystem' type='scsi'>
+      <source protocol='iscsi' name='iqn.2014-08.com.example:iscsi-nopool/1'>
+        <host name='example.com' port='3260'/>
+        <auth username='myuser'>
+          <secret type='iscsi' usage='libvirtiscsi'/>
+        </auth>
+      </source>
+      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+    </hostdev>
+  </devices>
+  ...</pre>
+
     <dl>
       <dt><code>hostdev</code></dt>
       <dd>The <code>hostdev</code> element is the main container for describing
-        host devices. For usb device passthrough <code>mode</code> is always
-        "subsystem" and <code>type</code> is "usb" for a USB device, "pci"
-        for a PCI device and "scsi" for a SCSI device. When
-        <code>managed</code> is "yes" for a PCI
-        device, it is detached from the host before being passed on to
-        the guest, and reattached to the host after the guest exits.
-        If <code>managed</code> is omitted or "no", and for USB
-        devices, the user is responsible to
-        call <code>virNodeDeviceDettach</code> (or <code>virsh
-        nodedev-dettach</code>) before starting the guest or
-        hot-plugging the device,
-        and <code>virNodeDeviceReAttach</code> (or <code>virsh
-        nodedev-reattach</code>) after hot-unplug or stopping the
-        guest. For SCSI device, user is responsible to make sure the device
-        is not used by host.
-        The optional <code>sgio</code> (<span class="since">since 1.0.6</span>)
-        attribute indicates whether the kernel will filter unprivileged
-        SG_IO commands for the disk, valid settings are "filtered" or
-        "unfiltered". Defaults to "filtered".
+        host devices. For each device, the <code>mode</code> is always
+        "subsystem" and the <code>type</code> is one of the following values
+        with additional attributes noted.
+        <dl>
+          <dt>usb</dt>
+          <dd>For USB devices, the user is responsible to call
+            <code>virNodeDeviceDettach</code> (or
+            <code>virsh nodedev-detach</code>) before starting the guest
+            or hot-plugging the device and <code>virNodeDeviceReAttach</code>
+            (or <code>virsh nodedev-reattach</code>) after hot-unplug or
+            stopping the guest.
+          </dd>
+          <dt>pci</dt>
+          <dd>For PCI devices, when <code>managed</code> is "yes" it is
+            detached from the host before being passed on to the guest
+            and reattached to the host after the guest exits. If
+            <code>managed</code> is omitted or "no", follow the steps
+            described for a USB device to detach before starting the
+            guest or hot-plugging and reattach after stopping the guest
+            or hot-unplug.
+          </dd>
+          <dt>scsi</dt>
+          <dd>For SCSI devices, user is responsible to make sure the device
+            is not used by host. The optional <code>sgio</code>
+            (<span class="since">since 1.0.6</span>) attribute indicates
+            whether the kernel will filter unprivileged SG_IO commands for
+            the disk, valid settings are "filtered" or "unfiltered".
+            The default is "filtered".
+          </dd>
+        </dl>
       </dd>
       <dt><code>source</code></dt>
-      <dd>The source element describes the device as seen from the host.
-      The USB device can either be addressed by vendor / product id using the
-      <code>vendor</code> and <code>product</code> elements or by the device's
-      address on the hosts using the <code>address</code> element. PCI devices
-      on the other hand can only be described by their <code>address</code>.
-      SCSI devices are described by both the <code>adapter</code> and
-      <code>address</code> elements.
-
-      <span class="since">Since 1.0.0</span>, the <code>source</code> element
-      of USB devices may contain <code>startupPolicy</code> attribute which can
-      be used to define policy what to do if the specified host USB device is
-      not found. The attribute accepts the following values:
-        <table class="top_table">
-          <tr>
-            <td> mandatory </td>
-            <td> fail if missing for any reason (the default) </td>
-          </tr>
-          <tr>
-            <td> requisite </td>
-            <td> fail if missing on boot up,
-                 drop if missing on migrate/restore/revert </td>
-          </tr>
-          <tr>
-            <td> optional </td>
-            <td> drop if missing at any start attempt </td>
-          </tr>
-        </table>
+      <dd>The source element describes the device as seen from the host using
+        the following mechanism to describe:
+        <dl>
+          <dt>usb</dt>
+          <dd>The USB device can either be addressed by vendor / product id
+            using the <code>vendor</code> and <code>product</code> elements
+            or by the device's address on the host using the
+            <code>address</code> element.
+            <p>
+            <span class="since">Since 1.0.0</span>, the <code>source</code>
+            element of USB devices may contain <code>startupPolicy</code>
+            attribute which can be used to define policy what to do if the
+            specified host USB device is not found. The attribute accepts
+            the following values:
+            </p>
+            <table class="top_table">
+              <tr>
+                <td> mandatory </td>
+                <td> fail if missing for any reason (the default) </td>
+              </tr>
+              <tr>
+                <td> requisite </td>
+                <td> fail if missing on boot up,
+                     drop if missing on migrate/restore/revert </td>
+              </tr>
+              <tr>
+                <td> optional </td>
+                <td> drop if missing at any start attempt </td>
+              </tr>
+            </table>
+          </dd>
+          <dt>pci</dt>
+          <dd>PCI devices can only be described by their <code>address</code>.
+          </dd>
+          <dt>scsi</dt>
+          <dd>SCSI devices are described by both the <code>adapter</code>
+            and <code>address</code> elements.
+            <p>
+            <span class="since">Since 1.2.8</span>, the <code>source</code>
+            element of a SCSI device may contain the <code>protocol</code>
+            attribute. When the attribute is set to "iscsi", the host
+            device XML follows the network <a href="#elementsDisks">disk</a>
+            device using the same <code>name</code> attribute and optionally
+            using the <code>auth</code> element to provide the authentication
+            credentials to the iSCSI server.
+            </p>
+          </dd>
+        </dl>
       </dd>
       <dt><code>vendor</code>, <code>product</code></dt>
       <dd>The <code>vendor</code> and <code>product</code> elements each have an
@@ -3589,7 +3639,7 @@
       before being passed on to the guest, and reattached to the host
       after the guest exits. If <code>managed</code> is omitted or "no",
       the user is responsible to call <code>virNodeDeviceDettach</code>
-      (or <code>virsh nodedev-dettach</code>) before starting the guest
+      (or <code>virsh nodedev-detach</code>) before starting the guest
       or hot-plugging the device, and <code>virNodeDeviceReAttach</code>
       (or <code>virsh nodedev-reattach</code>) after hot-unplug or
       stopping the guest.
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 11f0fd0..b7a1b6f 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -3589,12 +3589,51 @@
       </attribute>
     </optional>
     <element name="source">
-      <interleave>
-        <ref name="sourceinfoadapter"/>
-        <element name="address">
-          <ref name="scsiaddress"/>
-        </element>
-      </interleave>
+      <choice>
+        <group>  <!-- scsi_host adapter -->
+          <optional>
+            <attribute name="protocol">
+              <choice>
+                <value>adapter</value>   <!-- scsi_host, default, optional -->
+              </choice>
+            </attribute>
+          </optional>
+          <interleave>
+            <ref name="sourceinfoadapter"/>
+            <element name="address">
+              <ref name="scsiaddress"/>
+            </element>
+          </interleave>
+        </group>
+        <group>  <!-- iscsi adapter -->
+          <attribute name="protocol">
+            <choice>
+              <value>iscsi</value>     <!-- iscsi, required -->
+            </choice>
+          </attribute>
+          <attribute name="name">
+            <text/>
+          </attribute>
+          <interleave>
+            <oneOrMore>
+              <element name='host'>
+                <attribute name='name'>
+                  <text/>
+                </attribute>
+                <optional>
+                  <attribute name='port'>
+                    <ref name="PortNumber"/>
+                  </attribute>
+                </optional>
+                <empty/>
+              </element>
+            </oneOrMore>
+            <optional>
+              <ref name='diskAuth'/>
+            </optional>
+          </interleave>
+        </group>
+      </choice>
     </element>
   </define>
 
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 358afae..d87ca24 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -597,6 +597,11 @@ VIR_ENUM_IMPL(virDomainHostdevSubsysPCIBackend,
               "vfio",
               "xen")
 
+VIR_ENUM_IMPL(virDomainHostdevSubsysSCSIProtocol,
+              VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_LAST,
+              "adapter",
+              "iscsi")
+
 VIR_ENUM_IMPL(virDomainHostdevCaps, VIR_DOMAIN_HOSTDEV_CAPS_TYPE_LAST,
               "storage",
               "misc",
@@ -4213,10 +4218,96 @@ virDomainHostdevSubsysSCSIHostDefParseXML(xmlNodePtr sourcenode,
 }
 
 static int
+virDomainHostdevSubsysSCSIiSCSIDefParseXML(xmlNodePtr sourcenode,
+                                           virDomainHostdevSubsysSCSIPtr def)
+{
+    int ret = -1;
+    int auth_secret_usage = -1;
+    xmlNodePtr cur;
+    virStorageAuthDefPtr authdef = NULL;
+    virDomainHostdevSubsysSCSIiSCSIPtr iscsisrc = &def->u.iscsi;
+
+    /* Similar to virDomainDiskSourceParse for a VIR_STORAGE_TYPE_NETWORK */
+
+    if (!(iscsisrc->path = virXMLPropString(sourcenode, "name"))) {
+        virReportError(VIR_ERR_XML_ERROR, "%s",
+                       _("missing iSCSI hostdev source path name"));
+        goto cleanup;
+    }
+
+    if (virDomainStorageHostParse(sourcenode, &iscsisrc->hosts,
+                                  &iscsisrc->nhosts) < 0)
+        goto cleanup;
+
+    if (iscsisrc->nhosts < 1) {
+        virReportError(VIR_ERR_XML_ERROR, "%s",
+                       _("missing the host address for the iSCSI hostdev"));
+        goto cleanup;
+    }
+    if (iscsisrc->nhosts > 1) {
+        virReportError(VIR_ERR_XML_ERROR, "%s",
+                       _("only one source host address may be specified "
+                         "for the iSCSI hostdev"));
+        goto cleanup;
+    }
+
+    cur = sourcenode->children;
+    while (cur != NULL) {
+        if (cur->type == XML_ELEMENT_NODE &&
+            xmlStrEqual(cur->name, BAD_CAST "auth")) {
+            if (!(authdef = virStorageAuthDefParse(sourcenode->doc, cur)))
+                goto cleanup;
+            if ((auth_secret_usage =
+                 virSecretUsageTypeFromString(authdef->secrettype)) < 0) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                               _("invalid secret type %s"),
+                               authdef->secrettype);
+                goto cleanup;
+            }
+            if (auth_secret_usage != VIR_SECRET_USAGE_TYPE_ISCSI) {
+                virReportError(VIR_ERR_INTERNAL_ERROR,
+                               _("hostdev invalid secret type '%s'"),
+                               authdef->secrettype);
+                goto cleanup;
+            }
+            iscsisrc->auth = authdef;
+            authdef = NULL;
+        }
+        cur = cur->next;
+    }
+    ret = 0;
+
+ cleanup:
+    virStorageAuthDefFree(authdef);
+    return ret;
+}
+
+static int
 virDomainHostdevSubsysSCSIDefParseXML(xmlNodePtr sourcenode,
                                       virDomainHostdevSubsysSCSIPtr scsisrc)
 {
-    return virDomainHostdevSubsysSCSIHostDefParseXML(sourcenode, scsisrc);
+    char *protocol = NULL;
+    int ret = -1;
+
+    if ((protocol = virXMLPropString(sourcenode, "protocol"))) {
+        scsisrc->protocol =
+            virDomainHostdevSubsysSCSIProtocolTypeFromString(protocol);
+        if (scsisrc->protocol < 0) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                           _("Unknown SCSI subsystem protocol '%s'"),
+                           protocol);
+            goto cleanup;
+        }
+    }
+
+    if (scsisrc->protocol == VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI)
+        ret = virDomainHostdevSubsysSCSIiSCSIDefParseXML(sourcenode, scsisrc);
+    else
+        ret = virDomainHostdevSubsysSCSIHostDefParseXML(sourcenode, scsisrc);
+
+ cleanup:
+    VIR_FREE(protocol);
+    return ret;
 }
 
 /* Check if a drive type address $controller:0:0:$unit is already
@@ -15761,6 +15852,7 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf,
     virDomainHostdevSubsysPCIPtr pcisrc = &def->source.subsys.u.pci;
     virDomainHostdevSubsysSCSIPtr scsisrc = &def->source.subsys.u.scsi;
     virDomainHostdevSubsysSCSIHostPtr scsihostsrc = &scsisrc->u.host;
+    virDomainHostdevSubsysSCSIiSCSIPtr iscsisrc = &scsisrc->u.iscsi;
 
     if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI &&
         pcisrc->backend != VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT) {
@@ -15777,17 +15869,27 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf,
     }
 
     virBufferAddLit(buf, "<source");
-    if (def->startupPolicy) {
-        const char *policy;
-        policy = virDomainStartupPolicyTypeToString(def->startupPolicy);
-        virBufferAsprintf(buf, " startupPolicy='%s'", policy);
+    if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) {
+        if (def->startupPolicy) {
+            const char *policy;
+            policy = virDomainStartupPolicyTypeToString(def->startupPolicy);
+            virBufferAsprintf(buf, " startupPolicy='%s'", policy);
+        }
+        if (usbsrc->autoAddress && (flags & VIR_DOMAIN_XML_MIGRATABLE))
+            virBufferAddLit(buf, " autoAddress='yes'");
+
+        if (def->missing && !(flags & VIR_DOMAIN_XML_INACTIVE))
+            virBufferAddLit(buf, " missing='yes'");
     }
-    if (usbsrc->autoAddress && (flags & VIR_DOMAIN_XML_MIGRATABLE))
-        virBufferAddLit(buf, " autoAddress='yes'");
 
-    if (def->missing &&
-        !(flags & VIR_DOMAIN_XML_INACTIVE))
-        virBufferAddLit(buf, " missing='yes'");
+    if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI &&
+        scsisrc->protocol == VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI) {
+        const char *protocol =
+            virDomainHostdevSubsysSCSIProtocolTypeToString(scsisrc->protocol);
+
+        virBufferAsprintf(buf, " protocol='%s' name='%s'",
+                          protocol, iscsisrc->path);
+    }
 
     virBufferAddLit(buf, ">\n");
 
@@ -15828,12 +15930,20 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf,
         }
         break;
     case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI:
-        virBufferAsprintf(buf, "<adapter name='%s'/>\n",
-                          scsihostsrc->adapter);
-        virBufferAsprintf(buf, "<address %sbus='%d' target='%d' unit='%d'/>\n",
-                          includeTypeInAddr ? "type='scsi' " : "",
-                          scsihostsrc->bus, scsihostsrc->target,
-                          scsihostsrc->unit);
+        if (scsisrc->protocol == VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI) {
+            virBufferAddLit(buf, "<host");
+            virBufferEscapeString(buf, " name='%s'", iscsisrc->hosts[0].name);
+            virBufferEscapeString(buf, " port='%s'", iscsisrc->hosts[0].port);
+            virBufferAddLit(buf, "/>\n");
+        } else {
+            virBufferAsprintf(buf, "<adapter name='%s'/>\n",
+                              scsihostsrc->adapter);
+            virBufferAsprintf(buf,
+                              "<address %sbus='%d' target='%d' unit='%d'/>\n",
+                              includeTypeInAddr ? "type='scsi' " : "",
+                              scsihostsrc->bus, scsihostsrc->target,
+                              scsihostsrc->unit);
+        }
         break;
     default:
         virReportError(VIR_ERR_INTERNAL_ERROR,
@@ -15842,8 +15952,16 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf,
         return -1;
     }
 
+    if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI &&
+        scsisrc->protocol == VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI &&
+        iscsisrc->auth) {
+        if (virStorageAuthDefFormat(buf, iscsisrc->auth) < 0)
+            return -1;
+    }
+
     virBufferAdjustIndent(buf, -2);
     virBufferAddLit(buf, "</source>\n");
+
     return 0;
 }
 
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-lsi-iscsi-auth.args b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-lsi-iscsi-auth.args
new file mode 100644
index 0000000..6638dce
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-lsi-iscsi-auth.args
@@ -0,0 +1,14 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \
+/usr/bin/qemu -S -M \
+pc -m 214 -smp 1 -nographic -nodefaults -monitor \
+unix:/tmp/test-monitor,server,nowait -no-acpi -boot c \
+-device lsi,id=scsi0,bus=pci.0,addr=0x3 -usb \
+-drive file=/dev/HostVG/QEMUGuest2,if=none,id=drive-ide0-0-0 \
+-device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \
+-drive file=iscsi://myname:AQCVn5hO6HzFAhAAq0NCv8jtJcIcE+HOBlMQ1A@example.org\
+:3260/iqn.1992-01.com.example,if=none,format=raw,id=drive-hostdev0 \
+-device scsi-generic,bus=scsi0.0,scsi-id=4,drive=drive-hostdev0,id=hostdev0 \
+-drive file=iscsi://myname:AQCVn5hO6HzFAhAAq0NCv8jtJcIcE+HOBlMQ1A@example.org\
+:3260/iqn.1992-01.com.example/1,if=none,format=raw,id=drive-hostdev1 \
+-device scsi-generic,bus=scsi0.0,scsi-id=5,drive=drive-hostdev1,id=hostdev1 \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x4
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-lsi-iscsi-auth.xml b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-lsi-iscsi-auth.xml
new file mode 100644
index 0000000..3bfded4
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-lsi-iscsi-auth.xml
@@ -0,0 +1,46 @@
+<domain type='qemu'>
+  <name>QEMUGuest2</name>
+  <uuid>c7a5fdbd-edaf-9466-926a-d65c16db1809</uuid>
+  <memory unit='KiB'>219100</memory>
+  <currentMemory unit='KiB'>219100</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os>
+    <type arch='i686' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu</emulator>
+    <disk type='block' device='disk'>
+      <source dev='/dev/HostVG/QEMUGuest2'/>
+      <target dev='hda' bus='ide'/>
+      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+    </disk>
+    <controller type='scsi' index='0'/>
+    <controller type='usb' index='0'/>
+    <controller type='ide' index='0'/>
+    <controller type='pci' index='0' model='pci-root'/>
+    <hostdev mode='subsystem' type='scsi' managed='yes'>
+      <source protocol='iscsi' name='iqn.1992-01.com.example'>
+        <host name='example.org' port='3260'/>
+        <auth username='myname'>
+          <secret type='iscsi' usage='mycluster_myname'/>
+        </auth>
+      </source>
+      <address type='drive' controller='0' bus='0' target='0' unit='4'/>
+    </hostdev>
+    <hostdev mode='subsystem' type='scsi' managed='yes'>
+      <source protocol='iscsi' name='iqn.1992-01.com.example/1'>
+        <host name='example.org' port='3260'/>
+        <auth username='myname'>
+          <secret type='iscsi' usage='mycluster_myname'/>
+        </auth>
+      </source>
+      <address type='drive' controller='0' bus='0' target='0' unit='5'/>
+    </hostdev>
+    <memballoon model='virtio'/>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-lsi-iscsi.args b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-lsi-iscsi.args
new file mode 100644
index 0000000..2aebe9c
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-lsi-iscsi.args
@@ -0,0 +1,14 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \
+/usr/bin/qemu -S -M \
+pc -m 214 -smp 1 -nographic -nodefaults -monitor \
+unix:/tmp/test-monitor,server,nowait -no-acpi -boot c \
+-device lsi,id=scsi0,bus=pci.0,addr=0x3 -usb \
+-drive file=/dev/HostVG/QEMUGuest2,if=none,id=drive-ide0-0-0 \
+-device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \
+-drive file=iscsi://example.org:3260/iqn.1992-01.com.example,if=none,\
+format=raw,id=drive-hostdev0 \
+-device scsi-generic,bus=scsi0.0,scsi-id=4,drive=drive-hostdev0,id=hostdev0 \
+-drive file=iscsi://example.org:3260/iqn.1992-01.com.example/1,if=none,\
+format=raw,id=drive-hostdev1 \
+-device scsi-generic,bus=scsi0.0,scsi-id=5,drive=drive-hostdev1,id=hostdev1 \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x4
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-lsi-iscsi.xml b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-lsi-iscsi.xml
new file mode 100644
index 0000000..8a05099
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-lsi-iscsi.xml
@@ -0,0 +1,40 @@
+<domain type='qemu'>
+  <name>QEMUGuest2</name>
+  <uuid>c7a5fdbd-edaf-9466-926a-d65c16db1809</uuid>
+  <memory unit='KiB'>219100</memory>
+  <currentMemory unit='KiB'>219100</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os>
+    <type arch='i686' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu</emulator>
+    <disk type='block' device='disk'>
+      <source dev='/dev/HostVG/QEMUGuest2'/>
+      <target dev='hda' bus='ide'/>
+      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+    </disk>
+    <controller type='scsi' index='0'/>
+    <controller type='usb' index='0'/>
+    <controller type='ide' index='0'/>
+    <controller type='pci' index='0' model='pci-root'/>
+    <hostdev mode='subsystem' type='scsi' managed='yes'>
+      <source protocol='iscsi' name='iqn.1992-01.com.example'>
+        <host name='example.org' port='3260'/>
+      </source>
+      <address type='drive' controller='0' bus='0' target='0' unit='4'/>
+    </hostdev>
+    <hostdev mode='subsystem' type='scsi' managed='yes'>
+      <source protocol='iscsi' name='iqn.1992-01.com.example/1'>
+        <host name='example.org' port='3260'/>
+      </source>
+      <address type='drive' controller='0' bus='0' target='0' unit='5'/>
+    </hostdev>
+    <memballoon model='virtio'/>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-virtio-iscsi-auth.args b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-virtio-iscsi-auth.args
new file mode 100644
index 0000000..7fd3a00
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-virtio-iscsi-auth.args
@@ -0,0 +1,16 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \
+/usr/bin/qemu -S -M \
+pc -m 214 -smp 1 -nographic -nodefaults -monitor \
+unix:/tmp/test-monitor,server,nowait -no-acpi -boot c \
+-device virtio-scsi-pci,id=scsi0,bus=pci.0,addr=0x3 -usb \
+-drive file=/dev/HostVG/QEMUGuest2,if=none,id=drive-ide0-0-0 \
+-device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \
+-drive file=iscsi://myname:AQCVn5hO6HzFAhAAq0NCv8jtJcIcE+HOBlMQ1A@example.org\
+:3260/iqn.1992-01.com.example,if=none,format=raw,id=drive-hostdev0 \
+-device scsi-generic,bus=scsi0.0,channel=0,scsi-id=2,lun=4,\
+drive=drive-hostdev0,id=hostdev0 \
+-drive file=iscsi://myname:AQCVn5hO6HzFAhAAq0NCv8jtJcIcE+HOBlMQ1A@example.org\
+:3260/iqn.1992-01.com.example/1,if=none,format=raw,id=drive-hostdev1 \
+-device scsi-generic,bus=scsi0.0,channel=0,scsi-id=2,lun=5,\
+drive=drive-hostdev1,id=hostdev1 \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x4
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-virtio-iscsi-auth.xml b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-virtio-iscsi-auth.xml
new file mode 100644
index 0000000..d4dba4a
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-virtio-iscsi-auth.xml
@@ -0,0 +1,46 @@
+<domain type='qemu'>
+  <name>QEMUGuest2</name>
+  <uuid>c7a5fdbd-edaf-9466-926a-d65c16db1809</uuid>
+  <memory unit='KiB'>219100</memory>
+  <currentMemory unit='KiB'>219100</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os>
+    <type arch='i686' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu</emulator>
+    <disk type='block' device='disk'>
+      <source dev='/dev/HostVG/QEMUGuest2'/>
+      <target dev='hda' bus='ide'/>
+      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+    </disk>
+    <controller type='scsi' index='0' model='virtio-scsi'/>
+    <controller type='usb' index='0'/>
+    <controller type='ide' index='0'/>
+    <controller type='pci' index='0' model='pci-root'/>
+    <hostdev mode='subsystem' type='scsi' managed='yes'>
+      <source protocol='iscsi' name='iqn.1992-01.com.example'>
+        <host name='example.org' port='3260'/>
+        <auth username='myname'>
+          <secret type='iscsi' usage='mycluster_myname'/>
+        </auth>
+      </source>
+      <address type='drive' controller='0' bus='0' target='2' unit='4'/>
+    </hostdev>
+    <hostdev mode='subsystem' type='scsi' managed='yes'>
+      <source protocol='iscsi' name='iqn.1992-01.com.example/1'>
+        <host name='example.org' port='3260'/>
+        <auth username='myname'>
+          <secret type='iscsi' usage='mycluster_myname'/>
+        </auth>
+      </source>
+      <address type='drive' controller='0' bus='0' target='2' unit='5'/>
+    </hostdev>
+    <memballoon model='virtio'/>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-virtio-iscsi.args b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-virtio-iscsi.args
new file mode 100644
index 0000000..e4b6e97
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-virtio-iscsi.args
@@ -0,0 +1,16 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \
+/usr/bin/qemu -S -M \
+pc -m 214 -smp 1 -nographic -nodefaults -monitor \
+unix:/tmp/test-monitor,server,nowait -no-acpi -boot c \
+-device virtio-scsi-pci,id=scsi0,bus=pci.0,addr=0x3 -usb \
+-drive file=/dev/HostVG/QEMUGuest2,if=none,id=drive-ide0-0-0 \
+-device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \
+-drive file=iscsi://example.org:3260/iqn.1992-01.com.example,if=none,\
+format=raw,id=drive-hostdev0 \
+-device scsi-generic,bus=scsi0.0,channel=0,scsi-id=2,lun=4,\
+drive=drive-hostdev0,id=hostdev0 \
+-drive file=iscsi://example.org:3260/iqn.1992-01.com.example/1,if=none,\
+format=raw,id=drive-hostdev1 \
+-device scsi-generic,bus=scsi0.0,channel=0,scsi-id=2,lun=5,\
+drive=drive-hostdev1,id=hostdev1 \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x4
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-virtio-iscsi.xml b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-virtio-iscsi.xml
new file mode 100644
index 0000000..13c0930
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-scsi-virtio-iscsi.xml
@@ -0,0 +1,40 @@
+<domain type='qemu'>
+  <name>QEMUGuest2</name>
+  <uuid>c7a5fdbd-edaf-9466-926a-d65c16db1809</uuid>
+  <memory unit='KiB'>219100</memory>
+  <currentMemory unit='KiB'>219100</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os>
+    <type arch='i686' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu</emulator>
+    <disk type='block' device='disk'>
+      <source dev='/dev/HostVG/QEMUGuest2'/>
+      <target dev='hda' bus='ide'/>
+      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+    </disk>
+    <controller type='scsi' index='0' model='virtio-scsi'/>
+    <controller type='usb' index='0'/>
+    <controller type='ide' index='0'/>
+    <controller type='pci' index='0' model='pci-root'/>
+    <hostdev mode='subsystem' type='scsi' managed='yes'>
+      <source protocol='iscsi' name='iqn.1992-01.com.example'>
+        <host name='example.org' port='3260'/>
+      </source>
+      <address type='drive' controller='0' bus='0' target='2' unit='4'/>
+    </hostdev>
+    <hostdev mode='subsystem' type='scsi' managed='yes'>
+      <source protocol='iscsi' name='iqn.1992-01.com.example/1'>
+        <host name='example.org' port='3260'/>
+      </source>
+      <address type='drive' controller='0' bus='0' target='2' unit='5'/>
+    </hostdev>
+    <memballoon model='virtio'/>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 12ecabc..609c1bc 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -1353,6 +1353,22 @@ mymain(void)
             QEMU_CAPS_VIRTIO_SCSI, QEMU_CAPS_VIRTIO_SCSI,
             QEMU_CAPS_DEVICE_SCSI_GENERIC,
             QEMU_CAPS_DEVICE_SCSI_GENERIC_BOOTINDEX);
+    DO_TEST("hostdev-scsi-lsi-iscsi", QEMU_CAPS_DRIVE,
+            QEMU_CAPS_DEVICE, QEMU_CAPS_DRIVE,
+            QEMU_CAPS_VIRTIO_SCSI, QEMU_CAPS_SCSI_LSI,
+            QEMU_CAPS_DEVICE_SCSI_GENERIC);
+    DO_TEST("hostdev-scsi-lsi-iscsi-auth", QEMU_CAPS_DRIVE,
+            QEMU_CAPS_DEVICE, QEMU_CAPS_DRIVE,
+            QEMU_CAPS_VIRTIO_SCSI, QEMU_CAPS_SCSI_LSI,
+            QEMU_CAPS_DEVICE_SCSI_GENERIC);
+    DO_TEST("hostdev-scsi-virtio-iscsi", QEMU_CAPS_DRIVE,
+            QEMU_CAPS_DEVICE, QEMU_CAPS_DRIVE,
+            QEMU_CAPS_VIRTIO_SCSI, QEMU_CAPS_VIRTIO_SCSI,
+            QEMU_CAPS_DEVICE_SCSI_GENERIC);
+    DO_TEST("hostdev-scsi-virtio-iscsi-auth", QEMU_CAPS_DRIVE,
+            QEMU_CAPS_DEVICE, QEMU_CAPS_DRIVE,
+            QEMU_CAPS_VIRTIO_SCSI, QEMU_CAPS_VIRTIO_SCSI,
+            QEMU_CAPS_DEVICE_SCSI_GENERIC);
 
     DO_TEST("mlock-on", QEMU_CAPS_MLOCK);
     DO_TEST_FAILURE("mlock-on", NONE);
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index 451dedc..7d416d0 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -361,6 +361,11 @@ mymain(void)
 
     DO_TEST_DIFFERENT("hostdev-scsi-autogen-address");
 
+    DO_TEST("hostdev-scsi-lsi-iscsi");
+    DO_TEST("hostdev-scsi-lsi-iscsi-auth");
+    DO_TEST("hostdev-scsi-virtio-iscsi");
+    DO_TEST("hostdev-scsi-virtio-iscsi-auth");
+
     DO_TEST_DIFFERENT("s390-defaultconsole");
 
     DO_TEST("pcihole64");
-- 
1.9.3




More information about the libvir-list mailing list