[libvirt] [PATCH v3 0/3] Add iSCSI hostdev pass-through device

Patches 1 & 2 are related to: Update to http://www.redhat.com/archives/libvir-list/2014-July/msg01098.html Patch 1/3 is already ACK'd, but felt it was easier to push together. Patch 2/3 change since last: - Fix typos as called in review of 8/8 - Adjust the rng file to - Change the order of things to be <source>, then <auth> to follow how <disk> (and storage pools) do things. That resulted in code motion in domain_conf.c and adjustment to the *-iscsi-auth.xml files Patch 3 is related to http://www.redhat.com/archives/libvir-list/2014-July/msg01268.html John Ferlan (3): domain_conf: Common routine to handle network storage host xml def hostdev: Add iSCSI hostdev XML qemu: Remove extraneous space in function prototypes docs/formatdomain.html.in | 144 ++++++---- docs/schemas/domaincommon.rng | 48 +++- src/conf/domain_conf.c | 289 +++++++++++++++------ src/qemu/qemu_capabilities.h | 2 +- src/qemu/qemu_command.h | 136 +++++----- src/qemu/qemu_conf.h | 2 +- .../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 + 16 files changed, 672 insertions(+), 202 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 -- 1.9.3

In preparation for hostdev support for iSCSI and a virStorageNetHostDefPtr, split out the network disk storage parsing of the 'host' element into a separate routine. Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/domain_conf.c | 137 +++++++++++++++++++++++++++---------------------- 1 file changed, 76 insertions(+), 61 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index c25c74b..358afae 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -4051,6 +4051,79 @@ virDomainHostdevSubsysPCIDefParseXML(xmlNodePtr node, } static int +virDomainStorageHostParse(xmlNodePtr node, + virStorageNetHostDefPtr *hosts, + size_t *nhosts) +{ + int ret = -1; + xmlNodePtr child; + char *transport = NULL; + virStorageNetHostDef host; + + memset(&host, 0, sizeof(host)); + + child = node->children; + while (child != NULL) { + if (child->type == XML_ELEMENT_NODE && + xmlStrEqual(child->name, BAD_CAST "host")) { + + host.transport = VIR_STORAGE_NET_HOST_TRANS_TCP; + + /* transport can be tcp (default), unix or rdma. */ + if ((transport = virXMLPropString(child, "transport"))) { + host.transport = virStorageNetHostTransportTypeFromString(transport); + if (host.transport < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown protocol transport type '%s'"), + transport); + goto cleanup; + } + } + + host.socket = virXMLPropString(child, "socket"); + + if (host.transport == VIR_STORAGE_NET_HOST_TRANS_UNIX && + host.socket == NULL) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("missing socket for unix transport")); + goto cleanup; + } + + if (host.transport != VIR_STORAGE_NET_HOST_TRANS_UNIX && + host.socket != NULL) { + virReportError(VIR_ERR_XML_ERROR, + _("transport '%s' does not support " + "socket attribute"), + transport); + goto cleanup; + } + + VIR_FREE(transport); + + if (host.transport != VIR_STORAGE_NET_HOST_TRANS_UNIX) { + if (!(host.name = virXMLPropString(child, "name"))) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("missing name for host")); + goto cleanup; + } + + host.port = virXMLPropString(child, "port"); + } + + if (VIR_APPEND_ELEMENT(*hosts, *nhosts, host) < 0) + goto cleanup; + } + child = child->next; + } + ret = 0; + + cleanup: + virStorageNetHostDefClear(&host); + VIR_FREE(transport); + return ret; +} + +static int virDomainHostdevSubsysSCSIHostDefParseXML(xmlNodePtr sourcenode, virDomainHostdevSubsysSCSIPtr scsisrc) { @@ -5046,13 +5119,8 @@ int virDomainDiskSourceParse(xmlNodePtr node, virStorageSourcePtr src) { - char *protocol = NULL; - char *transport = NULL; - virStorageNetHostDef host; - xmlNodePtr child; int ret = -1; - - memset(&host, 0, sizeof(host)); + char *protocol = NULL; switch ((virStorageType)src->type) { case VIR_STORAGE_TYPE_FILE: @@ -5105,59 +5173,8 @@ virDomainDiskSourceParse(xmlNodePtr node, tmp[0] = '\0'; } - child = node->children; - while (child != NULL) { - if (child->type == XML_ELEMENT_NODE && - xmlStrEqual(child->name, BAD_CAST "host")) { - - host.transport = VIR_STORAGE_NET_HOST_TRANS_TCP; - - /* transport can be tcp (default), unix or rdma. */ - if ((transport = virXMLPropString(child, "transport"))) { - host.transport = virStorageNetHostTransportTypeFromString(transport); - if (host.transport < 0) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("unknown protocol transport type '%s'"), - transport); - goto cleanup; - } - } - - host.socket = virXMLPropString(child, "socket"); - - if (host.transport == VIR_STORAGE_NET_HOST_TRANS_UNIX && - host.socket == NULL) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("missing socket for unix transport")); - goto cleanup; - } - - if (host.transport != VIR_STORAGE_NET_HOST_TRANS_UNIX && - host.socket != NULL) { - virReportError(VIR_ERR_XML_ERROR, - _("transport '%s' does not support " - "socket attribute"), - transport); - goto cleanup; - } - - VIR_FREE(transport); - - if (host.transport != VIR_STORAGE_NET_HOST_TRANS_UNIX) { - if (!(host.name = virXMLPropString(child, "name"))) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("missing name for host")); - goto cleanup; - } - - host.port = virXMLPropString(child, "port"); - } - - if (VIR_APPEND_ELEMENT(src->hosts, src->nhosts, host) < 0) - goto cleanup; - } - child = child->next; - } + if (virDomainStorageHostParse(node, &src->hosts, &src->nhosts) < 0) + goto cleanup; break; case VIR_STORAGE_TYPE_VOLUME: if (virDomainDiskSourcePoolDefParse(node, &src->srcpool) < 0) @@ -5180,9 +5197,7 @@ virDomainDiskSourceParse(xmlNodePtr node, ret = 0; cleanup: - virStorageNetHostDefClear(&host); VIR_FREE(protocol); - VIR_FREE(transport); return ret; } -- 1.9.3

On 08/05/2014 02:09 PM, John Ferlan wrote:
In preparation for hostdev support for iSCSI and a virStorageNetHostDefPtr, split out the network disk storage parsing of the 'host' element into a separate routine.
Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/domain_conf.c | 137 +++++++++++++++++++++++++++---------------------- 1 file changed, 76 insertions(+), 61 deletions(-)
ACK -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

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'> <auth username='myname'> <secret type='iscsi' usage='mycluster_myname'/> </auth> <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='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@redhat.com> --- docs/formatdomain.html.in | 144 ++++++++++++------- docs/schemas/domaincommon.rng | 48 ++++++- src/conf/domain_conf.c | 152 ++++++++++++++++++--- .../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, 526 insertions(+), 71 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..0489a55 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'/> + </source> + <auth username='myuser'> + <secret type='iscsi' usage='libvirtiscsi'/> + </auth> + <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..a73989b 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -3588,14 +3588,48 @@ </choice> </attribute> </optional> - <element name="source"> - <interleave> - <ref name="sourceinfoadapter"/> - <element name="address"> - <ref name="scsiaddress"/> + <choice> + <group> <!-- scsi_host adapter --> + <element name="source"> + <interleave> + <ref name="sourceinfoadapter"/> + <element name="address"> + <ref name="scsiaddress"/> + </element> + </interleave> </element> - </interleave> - </element> + </group> + <group> <!-- iscsi adapter --> + <element name="source"> + <attribute name="protocol"> + <choice> + <value>iscsi</value> + </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> + </interleave> + </element> + <optional> + <ref name='diskAuth'/> + </optional> + </group> + </choice> </define> <define name="hostdevcapsstorage"> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 358afae..b7834eb 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, + "default", + "iscsi") + VIR_ENUM_IMPL(virDomainHostdevCaps, VIR_DOMAIN_HOSTDEV_CAPS_TYPE_LAST, "storage", "misc", @@ -4213,10 +4218,93 @@ virDomainHostdevSubsysSCSIHostDefParseXML(xmlNodePtr sourcenode, } static int +virDomainHostdevSubsysSCSIiSCSIDefParseXML(xmlNodePtr sourcenode, + xmlNodePtr authnode, + virDomainHostdevSubsysSCSIPtr def) +{ + int ret = -1; + int auth_secret_usage = -1; + 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; + } + + if (authnode) { + if (!(authdef = virStorageAuthDefParse(sourcenode->doc, authnode))) + 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; + } + ret = 0; + + cleanup: + virStorageAuthDefFree(authdef); + return ret; +} + +static int virDomainHostdevSubsysSCSIDefParseXML(xmlNodePtr sourcenode, + xmlNodePtr authnode, 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, authnode, + scsisrc); + else + ret = virDomainHostdevSubsysSCSIHostDefParseXML(sourcenode, scsisrc); + + cleanup: + VIR_FREE(protocol); + return ret; } /* Check if a drive type address $controller:0:0:$unit is already @@ -4361,6 +4449,7 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node, virDomainHostdevDefPtr def, unsigned int flags) { + xmlNodePtr authnode; xmlNodePtr sourcenode; char *managed = NULL; char *sgio = NULL; @@ -4456,7 +4545,9 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node, break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: - if (virDomainHostdevSubsysSCSIDefParseXML(sourcenode, scsisrc) < 0) + authnode = virXPathNode("./auth", ctxt); + if (virDomainHostdevSubsysSCSIDefParseXML(sourcenode, authnode, + scsisrc) < 0) goto error; break; @@ -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, @@ -15844,6 +15954,14 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf, virBufferAdjustIndent(buf, -2); virBufferAddLit(buf, "</source>\n"); + + 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; + } + 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..a4c637b --- /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'/> + </source> + <auth username='myname'> + <secret type='iscsi' usage='mycluster_myname'/> + </auth> + <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> + <auth username='myname'> + <secret type='iscsi' usage='mycluster_myname'/> + </auth> + <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..8d2e88e --- /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'/> + </source> + <auth username='myname'> + <secret type='iscsi' usage='mycluster_myname'/> + </auth> + <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> + <auth username='myname'> + <secret type='iscsi' usage='mycluster_myname'/> + </auth> + <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

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@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

On 08/05/2014 05:24 PM, John Ferlan wrote:
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.
Might be worth mentioning that protocol='adapter' was added as an optional marker of the existing use.
Signed-off-by: John Ferlan <jferlan@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
+++ 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")
So 0 == adapter...
+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);
so whether the user omitted protocol or specified it as adapter, they get the old style parse...
- 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);
...but here, you don't output the protocol. I can live with that (the alternative would be to always output the protocol, whether or not it was provided on input, and then touch up existing tests to reflect the new output; but the end result is the same). ACK -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

During review of the iSCSI hostdev series, eblake noted that the prototypes shouldn't have the extranenous space between the "*" and the function name: http://www.redhat.com/archives/libvir-list/2014-July/msg01227.html Since it was more invasive than 1 or 2 lines - I said I'd send a patch covering this once committed. Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/qemu/qemu_capabilities.h | 2 +- src/qemu/qemu_command.h | 136 +++++++++++++++++++++---------------------- src/qemu/qemu_conf.h | 2 +- 3 files changed, 70 insertions(+), 70 deletions(-) diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index e80a377..1db84ab 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -311,7 +311,7 @@ bool virQEMUCapsSupportsChardev(virDomainDefPtr def, bool virQEMUCapsIsMachineSupported(virQEMUCapsPtr qemuCaps, const char *canonical_machine); -const char * virQEMUCapsGetDefaultMachine(virQEMUCapsPtr qemuCaps); +const char *virQEMUCapsGetDefaultMachine(virQEMUCapsPtr qemuCaps); int virQEMUCapsInitGuestFromBinary(virCapsPtr caps, const char *binary, diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h index b71e964..95f3fc9 100644 --- a/src/qemu/qemu_command.h +++ b/src/qemu/qemu_command.h @@ -58,11 +58,11 @@ typedef struct _qemuBuildCommandLineCallbacks qemuBuildCommandLineCallbacks; typedef qemuBuildCommandLineCallbacks *qemuBuildCommandLineCallbacksPtr; struct _qemuBuildCommandLineCallbacks { - char * (*qemuGetSCSIDeviceSgName) (const char *sysfs_prefix, - const char *adapter, - unsigned int bus, - unsigned int target, - unsigned int unit); + char *(*qemuGetSCSIDeviceSgName) (const char *sysfs_prefix, + const char *adapter, + unsigned int bus, + unsigned int target, + unsigned int unit); }; extern qemuBuildCommandLineCallbacks buildCommandLineCallbacks; @@ -89,27 +89,27 @@ qemuBuildChrDeviceStr(char **deviceStr, virQEMUCapsPtr qemuCaps); /* With vlan == -1, use netdev syntax, else old hostnet */ -char * qemuBuildHostNetStr(virDomainNetDefPtr net, - virQEMUDriverPtr driver, - char type_sep, - int vlan, - char **tapfd, - int tapfdSize, - char **vhostfd, - int vhostfdSize); +char *qemuBuildHostNetStr(virDomainNetDefPtr net, + virQEMUDriverPtr driver, + char type_sep, + int vlan, + char **tapfd, + int tapfdSize, + char **vhostfd, + int vhostfdSize); /* Legacy, pre device support */ -char * qemuBuildNicStr(virDomainNetDefPtr net, - const char *prefix, - int vlan); +char *qemuBuildNicStr(virDomainNetDefPtr net, + const char *prefix, + int vlan); /* Current, best practice */ -char * qemuBuildNicDevStr(virDomainDefPtr def, - virDomainNetDefPtr net, - int vlan, - int bootindex, - int vhostfdSize, - virQEMUCapsPtr qemuCaps); +char *qemuBuildNicDevStr(virDomainDefPtr def, + virDomainNetDefPtr net, + int vlan, + int bootindex, + int vhostfdSize, + virQEMUCapsPtr qemuCaps); char *qemuDeviceDriveHostAlias(virDomainDiskDefPtr disk, virQEMUCapsPtr qemuCaps); @@ -123,68 +123,68 @@ char *qemuBuildFSStr(virDomainFSDefPtr fs, virQEMUCapsPtr qemuCaps); /* Current, best practice */ -char * qemuBuildDriveDevStr(virDomainDefPtr def, - virDomainDiskDefPtr disk, - int bootindex, - virQEMUCapsPtr qemuCaps); -char * qemuBuildFSDevStr(virDomainDefPtr domainDef, - virDomainFSDefPtr fs, - virQEMUCapsPtr qemuCaps); +char *qemuBuildDriveDevStr(virDomainDefPtr def, + virDomainDiskDefPtr disk, + int bootindex, + virQEMUCapsPtr qemuCaps); +char *qemuBuildFSDevStr(virDomainDefPtr domainDef, + virDomainFSDefPtr fs, + virQEMUCapsPtr qemuCaps); /* Current, best practice */ -char * qemuBuildControllerDevStr(virDomainDefPtr domainDef, - virDomainControllerDefPtr def, - virQEMUCapsPtr qemuCaps, - int *nusbcontroller); +char *qemuBuildControllerDevStr(virDomainDefPtr domainDef, + virDomainControllerDefPtr def, + virQEMUCapsPtr qemuCaps, + int *nusbcontroller); -char * qemuBuildWatchdogDevStr(virDomainDefPtr domainDef, - virDomainWatchdogDefPtr dev, - virQEMUCapsPtr qemuCaps); +char *qemuBuildWatchdogDevStr(virDomainDefPtr domainDef, + virDomainWatchdogDefPtr dev, + virQEMUCapsPtr qemuCaps); -char * qemuBuildMemballoonDevStr(virDomainDefPtr domainDef, - virDomainMemballoonDefPtr dev, - virQEMUCapsPtr qemuCaps); +char *qemuBuildMemballoonDevStr(virDomainDefPtr domainDef, + virDomainMemballoonDefPtr dev, + virQEMUCapsPtr qemuCaps); -char * qemuBuildUSBInputDevStr(virDomainDefPtr domainDef, - virDomainInputDefPtr dev, - virQEMUCapsPtr qemuCaps); +char *qemuBuildUSBInputDevStr(virDomainDefPtr domainDef, + virDomainInputDefPtr dev, + virQEMUCapsPtr qemuCaps); -char * qemuBuildSoundDevStr(virDomainDefPtr domainDef, - virDomainSoundDefPtr sound, - virQEMUCapsPtr qemuCaps); +char *qemuBuildSoundDevStr(virDomainDefPtr domainDef, + virDomainSoundDefPtr sound, + virQEMUCapsPtr qemuCaps); /* Legacy, pre device support */ -char * qemuBuildPCIHostdevPCIDevStr(virDomainHostdevDefPtr dev, - virQEMUCapsPtr qemuCaps); +char *qemuBuildPCIHostdevPCIDevStr(virDomainHostdevDefPtr dev, + virQEMUCapsPtr qemuCaps); /* Current, best practice */ -char * qemuBuildPCIHostdevDevStr(virDomainDefPtr def, - virDomainHostdevDefPtr dev, - const char *configfd, - virQEMUCapsPtr qemuCaps); +char *qemuBuildPCIHostdevDevStr(virDomainDefPtr def, + virDomainHostdevDefPtr dev, + const char *configfd, + virQEMUCapsPtr qemuCaps); int qemuOpenPCIConfig(virDomainHostdevDefPtr dev); /* Legacy, pre device support */ -char * qemuBuildUSBHostdevUSBDevStr(virDomainHostdevDefPtr dev); +char *qemuBuildUSBHostdevUSBDevStr(virDomainHostdevDefPtr dev); /* Current, best practice */ -char * qemuBuildUSBHostdevDevStr(virDomainDefPtr def, +char *qemuBuildUSBHostdevDevStr(virDomainDefPtr def, + virDomainHostdevDefPtr dev, + virQEMUCapsPtr qemuCaps); + +char *qemuBuildSCSIHostdevDrvStr(virConnectPtr conn, + virDomainHostdevDefPtr dev, + virQEMUCapsPtr qemuCaps, + qemuBuildCommandLineCallbacksPtr callbacks) + ATTRIBUTE_NONNULL(4); +char *qemuBuildSCSIHostdevDevStr(virDomainDefPtr def, virDomainHostdevDefPtr dev, virQEMUCapsPtr qemuCaps); -char * qemuBuildSCSIHostdevDrvStr(virConnectPtr conn, - virDomainHostdevDefPtr dev, - virQEMUCapsPtr qemuCaps, - qemuBuildCommandLineCallbacksPtr callbacks) - ATTRIBUTE_NONNULL(4); -char * qemuBuildSCSIHostdevDevStr(virDomainDefPtr def, - virDomainHostdevDefPtr dev, - virQEMUCapsPtr qemuCaps); - -char * qemuBuildHubDevStr(virDomainDefPtr def, - virDomainHubDefPtr dev, - virQEMUCapsPtr qemuCaps); -char * qemuBuildRedirdevDevStr(virDomainDefPtr def, - virDomainRedirdevDefPtr dev, - virQEMUCapsPtr qemuCaps); +char *qemuBuildHubDevStr(virDomainDefPtr def, + virDomainHubDefPtr dev, + virQEMUCapsPtr qemuCaps); +char *qemuBuildRedirdevDevStr(virDomainDefPtr def, + virDomainRedirdevDefPtr dev, + virQEMUCapsPtr qemuCaps); int qemuNetworkIfaceConnect(virDomainDefPtr def, virConnectPtr conn, virQEMUDriverPtr driver, diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index c3c9d6c..90aebef 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -286,7 +286,7 @@ bool qemuSharedDeviceEntryDomainExists(qemuSharedDeviceEntryPtr entry, int *index) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); -char * qemuGetSharedDeviceKey(const char *disk_path) +char *qemuGetSharedDeviceKey(const char *disk_path) ATTRIBUTE_NONNULL(1); void qemuSharedDeviceEntryFree(void *payload, const void *name) -- 1.9.3

On 08/05/2014 02:09 PM, John Ferlan wrote:
During review of the iSCSI hostdev series, eblake noted that the prototypes shouldn't have the extranenous space between the "*" and the function name:
http://www.redhat.com/archives/libvir-list/2014-July/msg01227.html
Since it was more invasive than 1 or 2 lines - I said I'd send a patch covering this once committed.
Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/qemu/qemu_capabilities.h | 2 +- src/qemu/qemu_command.h | 136 +++++++++++++++++++++---------------------- src/qemu/qemu_conf.h | 2 +- 3 files changed, 70 insertions(+), 70 deletions(-)
ACK. Mechanical, and nice to do it as a separate patch. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On 08/05/2014 04:09 PM, John Ferlan wrote:
Patches 1 & 2 are related to:
Update to http://www.redhat.com/archives/libvir-list/2014-July/msg01098.html
Patch 1/3 is already ACK'd, but felt it was easier to push together.
Patch 2/3 change since last: - Fix typos as called in review of 8/8 - Adjust the rng file to - Change the order of things to be <source>, then <auth> to follow how <disk> (and storage pools) do things. That resulted in code motion in domain_conf.c and adjustment to the *-iscsi-auth.xml files
Patch 3 is related to http://www.redhat.com/archives/libvir-list/2014-July/msg01268.html
John Ferlan (3): domain_conf: Common routine to handle network storage host xml def hostdev: Add iSCSI hostdev XML qemu: Remove extraneous space in function prototypes
docs/formatdomain.html.in | 144 ++++++---- docs/schemas/domaincommon.rng | 48 +++- src/conf/domain_conf.c | 289 +++++++++++++++------ src/qemu/qemu_capabilities.h | 2 +- src/qemu/qemu_command.h | 136 +++++----- src/qemu/qemu_conf.h | 2 +- .../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 + 16 files changed, 672 insertions(+), 202 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
Thanks for the review - these are now pushed with the adjustment to the the 2/3 commit message to indicate that protocol='adapter' is possible on read, but just not written out or documented. Tks, John
participants (2)
-
Eric Blake
-
John Ferlan