[libvirt] [PATCH v4 6/9] conf: Wire up the vhost-scsi connection from/to XML

Eric Farman posted 9 patches 9 years, 2 months ago
[libvirt] [PATCH v4 6/9] conf: Wire up the vhost-scsi connection from/to XML
Posted by Eric Farman 9 years, 2 months ago
With the QEMU components in place, provide the XML parsing to
invoke that code when given the following XML snippet:

    <hostdev mode='subsystem' type='scsi_host'>
      <source protocol='vhost' wwpn='naa.501234567890abcd'/>
    </hostdev>

An optional address element can be specified within the hostdev
(pick CCW or PCI as necessary):

      <address type='ccw' cssid='0xfe' ssid='0x0' devno='0x0625'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>

Signed-off-by: Eric Farman <farman@linux.vnet.ibm.com>
---
 docs/schemas/domaincommon.rng | 23 +++++++++++
 src/conf/domain_audit.c       |  7 ++++
 src/conf/domain_conf.c        | 92 ++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 121 insertions(+), 1 deletion(-)

diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 19d45fd..bb903ef 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -3974,6 +3974,7 @@
       <ref name="hostdevsubsyspci"/>
       <ref name="hostdevsubsysusb"/>
       <ref name="hostdevsubsysscsi"/>
+      <ref name="hostdevsubsyshost"/>
     </choice>
   </define>
 
@@ -4102,6 +4103,28 @@
     </element>
   </define>
 
+  <define name="hostdevsubsyshost">
+    <attribute name="type">
+      <value>scsi_host</value>
+    </attribute>
+    <element name="source">
+      <choice>
+        <group>
+          <attribute name="protocol">
+            <choice>
+              <value>vhost</value>     <!-- vhost, required -->
+            </choice>
+          </attribute>
+          <attribute name="wwpn">
+            <data type="string">
+              <param name="pattern">(naa\.)[0-9a-fA-F]{16}</param>
+            </data>
+          </attribute>
+        </group>
+      </choice>
+    </element>
+  </define>
+
   <define name="hostdevcapsstorage">
     <attribute name="type">
       <value>storage</value>
diff --git a/src/conf/domain_audit.c b/src/conf/domain_audit.c
index 2decf02..2d9ff5e 100644
--- a/src/conf/domain_audit.c
+++ b/src/conf/domain_audit.c
@@ -392,6 +392,7 @@ virDomainAuditHostdev(virDomainObjPtr vm, virDomainHostdevDefPtr hostdev,
     virDomainHostdevSubsysUSBPtr usbsrc = &hostdev->source.subsys.u.usb;
     virDomainHostdevSubsysPCIPtr pcisrc = &hostdev->source.subsys.u.pci;
     virDomainHostdevSubsysSCSIPtr scsisrc = &hostdev->source.subsys.u.scsi;
+    virDomainHostdevSubsysSCSIVHostPtr hostsrc = &hostdev->source.subsys.u.scsi_host;
 
     virUUIDFormat(vm->def->uuid, uuidstr);
     if (!(vmname = virAuditEncode("vm", vm->def->name))) {
@@ -444,6 +445,12 @@ virDomainAuditHostdev(virDomainObjPtr vm, virDomainHostdevDefPtr hostdev,
             }
             break;
         }
+        case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
+            if (VIR_STRDUP_QUIET(address, hostsrc->wwpn) < 0) {
+                VIR_WARN("OOM while encoding audit message");
+                goto cleanup;
+            }
+            break;
         default:
             VIR_WARN("Unexpected hostdev type while encoding audit message: %d",
                      hostdev->source.subsys.type);
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 3a4123d..618a214 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -2323,6 +2323,9 @@ void virDomainHostdevDefClear(virDomainHostdevDefPtr def)
             } else {
                 VIR_FREE(scsisrc->u.host.adapter);
             }
+        } else if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST) {
+            virDomainHostdevSubsysSCSIVHostPtr hostsrc = &def->source.subsys.u.scsi_host;
+            VIR_FREE(hostsrc->wwpn);
         }
         break;
     }
@@ -6094,6 +6097,58 @@ virDomainHostdevSubsysSCSIDefParseXML(xmlNodePtr sourcenode,
     return ret;
 }
 
+static int
+virDomainHostdevSubsysSCSIVHostDefParseXML(xmlNodePtr sourcenode,
+                                           virDomainHostdevDefPtr def)
+{
+    char *protocol = NULL;
+    virDomainHostdevSubsysSCSIVHostPtr hostsrc = &def->source.subsys.u.scsi_host;
+
+    if (!(protocol = virXMLPropString(sourcenode, "protocol"))) {
+        virReportError(VIR_ERR_XML_ERROR, "%s",
+                       _("Missing scsi_host subsystem protocol"));
+        return -1;
+    }
+
+    if ((hostsrc->protocol =
+         virDomainHostdevSubsysSCSIHostProtocolTypeFromString(protocol)) <= 0) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                       _("Unknown scsi_host subsystem protocol '%s'"),
+                       protocol);
+        goto cleanup;
+    }
+
+    switch ((virDomainHostdevSubsysSCSIHostProtocolType) hostsrc->protocol) {
+    case VIR_DOMAIN_HOSTDEV_SUBSYS_SCSI_HOST_PROTOCOL_TYPE_VHOST:
+        if (!(hostsrc->wwpn = virXMLPropString(sourcenode, "wwpn"))) {
+            virReportError(VIR_ERR_XML_ERROR, "%s",
+                           _("missing vhost-scsi hostdev source wwpn"));
+            goto cleanup;
+        }
+
+        if (!STRPREFIX(hostsrc->wwpn, "naa.") ||
+            !virValidateWWN(hostsrc->wwpn + 4)) {
+            virReportError(VIR_ERR_XML_ERROR, "%s", _("malformed 'wwpn' value"));
+            goto cleanup;
+        }
+        break;
+    case VIR_DOMAIN_HOSTDEV_SUBSYS_SCSI_HOST_PROTOCOL_TYPE_NONE:
+    case VIR_DOMAIN_HOSTDEV_SUBSYS_SCSI_HOST_PROTOCOL_TYPE_LAST:
+        virReportError(VIR_ERR_XML_ERROR,
+                       _("Invalid hostdev protocol '%s'"),
+                       virDomainHostdevSubsysSCSIHostProtocolTypeToString(hostsrc->protocol));
+        goto cleanup;
+        break;
+    }
+
+    return 0;
+
+ cleanup:
+    VIR_FREE(hostsrc->wwpn);
+    VIR_FREE(protocol);
+    return -1;
+}
+
 
 static int
 virDomainHostdevDefParseXMLSubsys(xmlNodePtr node,
@@ -6218,6 +6273,11 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node,
             goto error;
         break;
 
+    case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
+        if (virDomainHostdevSubsysSCSIVHostDefParseXML(sourcenode, def) < 0)
+            goto error;
+        break;
+
     default:
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                        _("address type='%s' not supported in hostdev interfaces"),
@@ -13023,6 +13083,15 @@ virDomainHostdevDefParseXML(virDomainXMLOptionPtr xmlopt,
                 def->shareable = true;
             break;
         case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
+            if (def->info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE &&
+                def->info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI &&
+                def->info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) {
+                virReportError(VIR_ERR_XML_ERROR, "%s",
+                               _("SCSI_host host device must use 'pci' "
+                                 "or 'ccw' address type"));
+                goto error;
+            }
+            break;
         case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
         case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
             break;
@@ -13907,7 +13976,14 @@ virDomainHostdevMatchSubsys(virDomainHostdevDefPtr a,
         else
             return virDomainHostdevMatchSubsysSCSIHost(a, b);
     case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
-        /* Fall through for now */
+        if (a->source.subsys.u.scsi_host.protocol !=
+            b->source.subsys.u.scsi_host.protocol)
+            return 0;
+        if (STREQ(a->source.subsys.u.scsi_host.wwpn,
+                  b->source.subsys.u.scsi_host.wwpn))
+            return 1;
+        else
+            return 0;
     case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
         return 0;
     }
@@ -20814,9 +20890,11 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf,
                                 unsigned int flags,
                                 bool includeTypeInAddr)
 {
+    bool closedSource = false;
     virDomainHostdevSubsysUSBPtr usbsrc = &def->source.subsys.u.usb;
     virDomainHostdevSubsysPCIPtr pcisrc = &def->source.subsys.u.pci;
     virDomainHostdevSubsysSCSIPtr scsisrc = &def->source.subsys.u.scsi;
+    virDomainHostdevSubsysSCSIVHostPtr hostsrc = &def->source.subsys.u.scsi_host;
     virDomainHostdevSubsysSCSIHostPtr scsihostsrc = &scsisrc->u.host;
     virDomainHostdevSubsysSCSIiSCSIPtr iscsisrc = &scsisrc->u.iscsi;
 
@@ -20857,6 +20935,15 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf,
                           protocol, iscsisrc->path);
     }
 
+    if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST) {
+        const char *protocol =
+            virDomainHostdevSubsysSCSIHostProtocolTypeToString(hostsrc->protocol);
+        closedSource = true;
+
+        virBufferAsprintf(buf, " protocol='%s' wwpn='%s'/",
+                          protocol, hostsrc->wwpn);
+    }
+
     virBufferAddLit(buf, ">\n");
 
     virBufferAdjustIndent(buf, 2);
@@ -20910,6 +20997,8 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf,
                               scsihostsrc->unit);
         }
         break;
+    case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
+        break;
     default:
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("unexpected hostdev type %d"),
@@ -20925,6 +21014,7 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf,
     }
 
     virBufferAdjustIndent(buf, -2);
+    if (!closedSource)
     virBufferAddLit(buf, "</source>\n");
 
     return 0;
-- 
1.9.1

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v4 6/9] conf: Wire up the vhost-scsi connection from/to XML
Posted by John Ferlan 9 years, 2 months ago

On 11/21/2016 10:58 PM, Eric Farman wrote:
> With the QEMU components in place, provide the XML parsing to
> invoke that code when given the following XML snippet:
> 
>     <hostdev mode='subsystem' type='scsi_host'>
>       <source protocol='vhost' wwpn='naa.501234567890abcd'/>
>     </hostdev>
> 
> An optional address element can be specified within the hostdev
> (pick CCW or PCI as necessary):
> 
>       <address type='ccw' cssid='0xfe' ssid='0x0' devno='0x0625'/>
>       <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
> 
> Signed-off-by: Eric Farman <farman@linux.vnet.ibm.com>
> ---
>  docs/schemas/domaincommon.rng | 23 +++++++++++
>  src/conf/domain_audit.c       |  7 ++++
>  src/conf/domain_conf.c        | 92 ++++++++++++++++++++++++++++++++++++++++++-
>  3 files changed, 121 insertions(+), 1 deletion(-)
> 

Typically when we add rng we add the xml2xml in the same patch - I'll
merge patch 8 into here to keep things "normal" and "familiar".  Also
also merge patch 9 into here since that too would be needed...  Will
move patch 7 to just before here, so that the conf will be the last patch.

> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
> index 19d45fd..bb903ef 100644
> --- a/docs/schemas/domaincommon.rng
> +++ b/docs/schemas/domaincommon.rng
> @@ -3974,6 +3974,7 @@
>        <ref name="hostdevsubsyspci"/>
>        <ref name="hostdevsubsysusb"/>
>        <ref name="hostdevsubsysscsi"/>
> +      <ref name="hostdevsubsyshost"/>
>      </choice>
>    </define>
>  
> @@ -4102,6 +4103,28 @@
>      </element>
>    </define>
>  
> +  <define name="hostdevsubsyshost">
> +    <attribute name="type">
> +      <value>scsi_host</value>
> +    </attribute>
> +    <element name="source">
> +      <choice>
> +        <group>
> +          <attribute name="protocol">
> +            <choice>
> +              <value>vhost</value>     <!-- vhost, required -->
> +            </choice>
> +          </attribute>
> +          <attribute name="wwpn">
> +            <data type="string">
> +              <param name="pattern">(naa\.)[0-9a-fA-F]{16}</param>
> +            </data>
> +          </attribute>
> +        </group>
> +      </choice>
> +    </element>
> +  </define>
> +
>    <define name="hostdevcapsstorage">
>      <attribute name="type">
>        <value>storage</value>
> diff --git a/src/conf/domain_audit.c b/src/conf/domain_audit.c
> index 2decf02..2d9ff5e 100644
> --- a/src/conf/domain_audit.c
> +++ b/src/conf/domain_audit.c
> @@ -392,6 +392,7 @@ virDomainAuditHostdev(virDomainObjPtr vm, virDomainHostdevDefPtr hostdev,
>      virDomainHostdevSubsysUSBPtr usbsrc = &hostdev->source.subsys.u.usb;
>      virDomainHostdevSubsysPCIPtr pcisrc = &hostdev->source.subsys.u.pci;
>      virDomainHostdevSubsysSCSIPtr scsisrc = &hostdev->source.subsys.u.scsi;
> +    virDomainHostdevSubsysSCSIVHostPtr hostsrc = &hostdev->source.subsys.u.scsi_host;
>  
>      virUUIDFormat(vm->def->uuid, uuidstr);
>      if (!(vmname = virAuditEncode("vm", vm->def->name))) {
> @@ -444,6 +445,12 @@ virDomainAuditHostdev(virDomainObjPtr vm, virDomainHostdevDefPtr hostdev,
>              }
>              break;
>          }
> +        case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:

Looks like a missed spot from the already pushed patch (no big deal,
just making a mental note).  The default: exists so so I see why.

> +            if (VIR_STRDUP_QUIET(address, hostsrc->wwpn) < 0) {
> +                VIR_WARN("OOM while encoding audit message");
> +                goto cleanup;
> +            }
> +            break;
>          default:
>              VIR_WARN("Unexpected hostdev type while encoding audit message: %d",
>                       hostdev->source.subsys.type);
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index 3a4123d..618a214 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -2323,6 +2323,9 @@ void virDomainHostdevDefClear(virDomainHostdevDefPtr def)
>              } else {
>                  VIR_FREE(scsisrc->u.host.adapter);
>              }
> +        } else if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST) {
> +            virDomainHostdevSubsysSCSIVHostPtr hostsrc = &def->source.subsys.u.scsi_host;
> +            VIR_FREE(hostsrc->wwpn);
>          }
>          break;
>      }
> @@ -6094,6 +6097,58 @@ virDomainHostdevSubsysSCSIDefParseXML(xmlNodePtr sourcenode,
>      return ret;
>  }
>  
> +static int
> +virDomainHostdevSubsysSCSIVHostDefParseXML(xmlNodePtr sourcenode,
> +                                           virDomainHostdevDefPtr def)
> +{
> +    char *protocol = NULL;
> +    virDomainHostdevSubsysSCSIVHostPtr hostsrc = &def->source.subsys.u.scsi_host;
> +
> +    if (!(protocol = virXMLPropString(sourcenode, "protocol"))) {
> +        virReportError(VIR_ERR_XML_ERROR, "%s",
> +                       _("Missing scsi_host subsystem protocol"));
> +        return -1;
> +    }
> +
> +    if ((hostsrc->protocol =
> +         virDomainHostdevSubsysSCSIHostProtocolTypeFromString(protocol)) <= 0) {
> +        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> +                       _("Unknown scsi_host subsystem protocol '%s'"),
> +                       protocol);
> +        goto cleanup;
> +    }
> +
> +    switch ((virDomainHostdevSubsysSCSIHostProtocolType) hostsrc->protocol) {
> +    case VIR_DOMAIN_HOSTDEV_SUBSYS_SCSI_HOST_PROTOCOL_TYPE_VHOST:
> +        if (!(hostsrc->wwpn = virXMLPropString(sourcenode, "wwpn"))) {
> +            virReportError(VIR_ERR_XML_ERROR, "%s",
> +                           _("missing vhost-scsi hostdev source wwpn"));
> +            goto cleanup;
> +        }
> +
> +        if (!STRPREFIX(hostsrc->wwpn, "naa.") ||
> +            !virValidateWWN(hostsrc->wwpn + 4)) {
> +            virReportError(VIR_ERR_XML_ERROR, "%s", _("malformed 'wwpn' value"));
> +            goto cleanup;
> +        }
> +        break;
> +    case VIR_DOMAIN_HOSTDEV_SUBSYS_SCSI_HOST_PROTOCOL_TYPE_NONE:
> +    case VIR_DOMAIN_HOSTDEV_SUBSYS_SCSI_HOST_PROTOCOL_TYPE_LAST:
> +        virReportError(VIR_ERR_XML_ERROR,
> +                       _("Invalid hostdev protocol '%s'"),
> +                       virDomainHostdevSubsysSCSIHostProtocolTypeToString(hostsrc->protocol));
> +        goto cleanup;
> +        break;
> +    }
> +
> +    return 0;
> +
> + cleanup:
> +    VIR_FREE(hostsrc->wwpn);
> +    VIR_FREE(protocol);
> +    return -1;
> +}
> +
>  
>  static int
>  virDomainHostdevDefParseXMLSubsys(xmlNodePtr node,
> @@ -6218,6 +6273,11 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node,
>              goto error;
>          break;
>  
> +    case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:

Yet another spot were the default is used...

> +        if (virDomainHostdevSubsysSCSIVHostDefParseXML(sourcenode, def) < 0)
> +            goto error;
> +        break;
> +
>      default:
>          virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
>                         _("address type='%s' not supported in hostdev interfaces"),
> @@ -13023,6 +13083,15 @@ virDomainHostdevDefParseXML(virDomainXMLOptionPtr xmlopt,
>                  def->shareable = true;
>              break;
>          case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
> +            if (def->info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE &&
> +                def->info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI &&
> +                def->info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) {
> +                virReportError(VIR_ERR_XML_ERROR, "%s",
> +                               _("SCSI_host host device must use 'pci' "
> +                                 "or 'ccw' address type"));
> +                goto error;
> +            }
> +            break;
>          case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
>          case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
>              break;
> @@ -13907,7 +13976,14 @@ virDomainHostdevMatchSubsys(virDomainHostdevDefPtr a,
>          else
>              return virDomainHostdevMatchSubsysSCSIHost(a, b);
>      case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
> -        /* Fall through for now */
> +        if (a->source.subsys.u.scsi_host.protocol !=
> +            b->source.subsys.u.scsi_host.protocol)
> +            return 0;
> +        if (STREQ(a->source.subsys.u.scsi_host.wwpn,
> +                  b->source.subsys.u.scsi_host.wwpn))
> +            return 1;
> +        else
> +            return 0;
>      case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
>          return 0;
>      }
> @@ -20814,9 +20890,11 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf,
>                                  unsigned int flags,
>                                  bool includeTypeInAddr)
>  {
> +    bool closedSource = false;
>      virDomainHostdevSubsysUSBPtr usbsrc = &def->source.subsys.u.usb;
>      virDomainHostdevSubsysPCIPtr pcisrc = &def->source.subsys.u.pci;
>      virDomainHostdevSubsysSCSIPtr scsisrc = &def->source.subsys.u.scsi;
> +    virDomainHostdevSubsysSCSIVHostPtr hostsrc = &def->source.subsys.u.scsi_host;
>      virDomainHostdevSubsysSCSIHostPtr scsihostsrc = &scsisrc->u.host;
>      virDomainHostdevSubsysSCSIiSCSIPtr iscsisrc = &scsisrc->u.iscsi;
>  
> @@ -20857,6 +20935,15 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf,
>                            protocol, iscsisrc->path);
>      }
>  
> +    if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST) {
> +        const char *protocol =
> +            virDomainHostdevSubsysSCSIHostProtocolTypeToString(hostsrc->protocol);
> +        closedSource = true;
> +
> +        virBufferAsprintf(buf, " protocol='%s' wwpn='%s'/",
> +                          protocol, hostsrc->wwpn);
> +    }
> +
>      virBufferAddLit(buf, ">\n");
>  
>      virBufferAdjustIndent(buf, 2);
> @@ -20910,6 +20997,8 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf,
>                                scsihostsrc->unit);
>          }
>          break;
> +    case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
> +        break;
>      default:
>          virReportError(VIR_ERR_INTERNAL_ERROR,
>                         _("unexpected hostdev type %d"),
> @@ -20925,6 +21014,7 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf,
>      }
>  
>      virBufferAdjustIndent(buf, -2);
> +    if (!closedSource)
>      virBufferAddLit(buf, "</source>\n");

I'll reindent this...

ACK

John

>  
>      return 0;
> 

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH v4 6/9] conf: Wire up the vhost-scsi connection from/to XML
Posted by Eric Farman 9 years, 2 months ago

On 11/22/2016 04:12 PM, John Ferlan wrote:
>
> On 11/21/2016 10:58 PM, Eric Farman wrote:
>> With the QEMU components in place, provide the XML parsing to
>> invoke that code when given the following XML snippet:
>>
>>      <hostdev mode='subsystem' type='scsi_host'>
>>        <source protocol='vhost' wwpn='naa.501234567890abcd'/>
>>      </hostdev>
>>
>> An optional address element can be specified within the hostdev
>> (pick CCW or PCI as necessary):
>>
>>        <address type='ccw' cssid='0xfe' ssid='0x0' devno='0x0625'/>
>>        <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
>>
>> Signed-off-by: Eric Farman <farman@linux.vnet.ibm.com>
>> ---
>>   docs/schemas/domaincommon.rng | 23 +++++++++++
>>   src/conf/domain_audit.c       |  7 ++++
>>   src/conf/domain_conf.c        | 92 ++++++++++++++++++++++++++++++++++++++++++-
>>   3 files changed, 121 insertions(+), 1 deletion(-)
>>
> Typically when we add rng we add the xml2xml in the same patch - I'll
> merge patch 8 into here to keep things "normal" and "familiar".  Also
> also merge patch 9 into here since that too would be needed...  Will
> move patch 7 to just before here, so that the conf will be the last patch.

Much obliged.

>
>> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
>> index 19d45fd..bb903ef 100644
>> --- a/docs/schemas/domaincommon.rng
>> +++ b/docs/schemas/domaincommon.rng
>> @@ -3974,6 +3974,7 @@
>>         <ref name="hostdevsubsyspci"/>
>>         <ref name="hostdevsubsysusb"/>
>>         <ref name="hostdevsubsysscsi"/>
>> +      <ref name="hostdevsubsyshost"/>
>>       </choice>
>>     </define>
>>   
>> @@ -4102,6 +4103,28 @@
>>       </element>
>>     </define>
>>   
>> +  <define name="hostdevsubsyshost">
>> +    <attribute name="type">
>> +      <value>scsi_host</value>
>> +    </attribute>
>> +    <element name="source">
>> +      <choice>
>> +        <group>
>> +          <attribute name="protocol">
>> +            <choice>
>> +              <value>vhost</value>     <!-- vhost, required -->
>> +            </choice>
>> +          </attribute>
>> +          <attribute name="wwpn">
>> +            <data type="string">
>> +              <param name="pattern">(naa\.)[0-9a-fA-F]{16}</param>
>> +            </data>
>> +          </attribute>
>> +        </group>
>> +      </choice>
>> +    </element>
>> +  </define>
>> +
>>     <define name="hostdevcapsstorage">
>>       <attribute name="type">
>>         <value>storage</value>
>> diff --git a/src/conf/domain_audit.c b/src/conf/domain_audit.c
>> index 2decf02..2d9ff5e 100644
>> --- a/src/conf/domain_audit.c
>> +++ b/src/conf/domain_audit.c
>> @@ -392,6 +392,7 @@ virDomainAuditHostdev(virDomainObjPtr vm, virDomainHostdevDefPtr hostdev,
>>       virDomainHostdevSubsysUSBPtr usbsrc = &hostdev->source.subsys.u.usb;
>>       virDomainHostdevSubsysPCIPtr pcisrc = &hostdev->source.subsys.u.pci;
>>       virDomainHostdevSubsysSCSIPtr scsisrc = &hostdev->source.subsys.u.scsi;
>> +    virDomainHostdevSubsysSCSIVHostPtr hostsrc = &hostdev->source.subsys.u.scsi_host;
>>   
>>       virUUIDFormat(vm->def->uuid, uuidstr);
>>       if (!(vmname = virAuditEncode("vm", vm->def->name))) {
>> @@ -444,6 +445,12 @@ virDomainAuditHostdev(virDomainObjPtr vm, virDomainHostdevDefPtr hostdev,
>>               }
>>               break;
>>           }
>> +        case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
> Looks like a missed spot from the already pushed patch (no big deal,
> just making a mental note).  The default: exists so so I see why.

If memory serves me right, these cases are guarded by earlier code. But, 
in the interest of the "hey, look over here when adding a thing!" 
mentality, I will send a fixup for them.

Thanks,
  - Eric

>
>> +            if (VIR_STRDUP_QUIET(address, hostsrc->wwpn) < 0) {
>> +                VIR_WARN("OOM while encoding audit message");
>> +                goto cleanup;
>> +            }
>> +            break;
>>           default:
>>               VIR_WARN("Unexpected hostdev type while encoding audit message: %d",
>>                        hostdev->source.subsys.type);
>> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
>> index 3a4123d..618a214 100644
>> --- a/src/conf/domain_conf.c
>> +++ b/src/conf/domain_conf.c
>> @@ -2323,6 +2323,9 @@ void virDomainHostdevDefClear(virDomainHostdevDefPtr def)
>>               } else {
>>                   VIR_FREE(scsisrc->u.host.adapter);
>>               }
>> +        } else if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST) {
>> +            virDomainHostdevSubsysSCSIVHostPtr hostsrc = &def->source.subsys.u.scsi_host;
>> +            VIR_FREE(hostsrc->wwpn);
>>           }
>>           break;
>>       }
>> @@ -6094,6 +6097,58 @@ virDomainHostdevSubsysSCSIDefParseXML(xmlNodePtr sourcenode,
>>       return ret;
>>   }
>>   
>> +static int
>> +virDomainHostdevSubsysSCSIVHostDefParseXML(xmlNodePtr sourcenode,
>> +                                           virDomainHostdevDefPtr def)
>> +{
>> +    char *protocol = NULL;
>> +    virDomainHostdevSubsysSCSIVHostPtr hostsrc = &def->source.subsys.u.scsi_host;
>> +
>> +    if (!(protocol = virXMLPropString(sourcenode, "protocol"))) {
>> +        virReportError(VIR_ERR_XML_ERROR, "%s",
>> +                       _("Missing scsi_host subsystem protocol"));
>> +        return -1;
>> +    }
>> +
>> +    if ((hostsrc->protocol =
>> +         virDomainHostdevSubsysSCSIHostProtocolTypeFromString(protocol)) <= 0) {
>> +        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
>> +                       _("Unknown scsi_host subsystem protocol '%s'"),
>> +                       protocol);
>> +        goto cleanup;
>> +    }
>> +
>> +    switch ((virDomainHostdevSubsysSCSIHostProtocolType) hostsrc->protocol) {
>> +    case VIR_DOMAIN_HOSTDEV_SUBSYS_SCSI_HOST_PROTOCOL_TYPE_VHOST:
>> +        if (!(hostsrc->wwpn = virXMLPropString(sourcenode, "wwpn"))) {
>> +            virReportError(VIR_ERR_XML_ERROR, "%s",
>> +                           _("missing vhost-scsi hostdev source wwpn"));
>> +            goto cleanup;
>> +        }
>> +
>> +        if (!STRPREFIX(hostsrc->wwpn, "naa.") ||
>> +            !virValidateWWN(hostsrc->wwpn + 4)) {
>> +            virReportError(VIR_ERR_XML_ERROR, "%s", _("malformed 'wwpn' value"));
>> +            goto cleanup;
>> +        }
>> +        break;
>> +    case VIR_DOMAIN_HOSTDEV_SUBSYS_SCSI_HOST_PROTOCOL_TYPE_NONE:
>> +    case VIR_DOMAIN_HOSTDEV_SUBSYS_SCSI_HOST_PROTOCOL_TYPE_LAST:
>> +        virReportError(VIR_ERR_XML_ERROR,
>> +                       _("Invalid hostdev protocol '%s'"),
>> +                       virDomainHostdevSubsysSCSIHostProtocolTypeToString(hostsrc->protocol));
>> +        goto cleanup;
>> +        break;
>> +    }
>> +
>> +    return 0;
>> +
>> + cleanup:
>> +    VIR_FREE(hostsrc->wwpn);
>> +    VIR_FREE(protocol);
>> +    return -1;
>> +}
>> +
>>   
>>   static int
>>   virDomainHostdevDefParseXMLSubsys(xmlNodePtr node,
>> @@ -6218,6 +6273,11 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node,
>>               goto error;
>>           break;
>>   
>> +    case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
> Yet another spot were the default is used...
>
>> +        if (virDomainHostdevSubsysSCSIVHostDefParseXML(sourcenode, def) < 0)
>> +            goto error;
>> +        break;
>> +
>>       default:
>>           virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
>>                          _("address type='%s' not supported in hostdev interfaces"),
>> @@ -13023,6 +13083,15 @@ virDomainHostdevDefParseXML(virDomainXMLOptionPtr xmlopt,
>>                   def->shareable = true;
>>               break;
>>           case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
>> +            if (def->info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE &&
>> +                def->info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI &&
>> +                def->info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) {
>> +                virReportError(VIR_ERR_XML_ERROR, "%s",
>> +                               _("SCSI_host host device must use 'pci' "
>> +                                 "or 'ccw' address type"));
>> +                goto error;
>> +            }
>> +            break;
>>           case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB:
>>           case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
>>               break;
>> @@ -13907,7 +13976,14 @@ virDomainHostdevMatchSubsys(virDomainHostdevDefPtr a,
>>           else
>>               return virDomainHostdevMatchSubsysSCSIHost(a, b);
>>       case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
>> -        /* Fall through for now */
>> +        if (a->source.subsys.u.scsi_host.protocol !=
>> +            b->source.subsys.u.scsi_host.protocol)
>> +            return 0;
>> +        if (STREQ(a->source.subsys.u.scsi_host.wwpn,
>> +                  b->source.subsys.u.scsi_host.wwpn))
>> +            return 1;
>> +        else
>> +            return 0;
>>       case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
>>           return 0;
>>       }
>> @@ -20814,9 +20890,11 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf,
>>                                   unsigned int flags,
>>                                   bool includeTypeInAddr)
>>   {
>> +    bool closedSource = false;
>>       virDomainHostdevSubsysUSBPtr usbsrc = &def->source.subsys.u.usb;
>>       virDomainHostdevSubsysPCIPtr pcisrc = &def->source.subsys.u.pci;
>>       virDomainHostdevSubsysSCSIPtr scsisrc = &def->source.subsys.u.scsi;
>> +    virDomainHostdevSubsysSCSIVHostPtr hostsrc = &def->source.subsys.u.scsi_host;
>>       virDomainHostdevSubsysSCSIHostPtr scsihostsrc = &scsisrc->u.host;
>>       virDomainHostdevSubsysSCSIiSCSIPtr iscsisrc = &scsisrc->u.iscsi;
>>   
>> @@ -20857,6 +20935,15 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf,
>>                             protocol, iscsisrc->path);
>>       }
>>   
>> +    if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST) {
>> +        const char *protocol =
>> +            virDomainHostdevSubsysSCSIHostProtocolTypeToString(hostsrc->protocol);
>> +        closedSource = true;
>> +
>> +        virBufferAsprintf(buf, " protocol='%s' wwpn='%s'/",
>> +                          protocol, hostsrc->wwpn);
>> +    }
>> +
>>       virBufferAddLit(buf, ">\n");
>>   
>>       virBufferAdjustIndent(buf, 2);
>> @@ -20910,6 +20997,8 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf,
>>                                 scsihostsrc->unit);
>>           }
>>           break;
>> +    case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
>> +        break;
>>       default:
>>           virReportError(VIR_ERR_INTERNAL_ERROR,
>>                          _("unexpected hostdev type %d"),
>> @@ -20925,6 +21014,7 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf,
>>       }
>>   
>>       virBufferAdjustIndent(buf, -2);
>> +    if (!closedSource)
>>       virBufferAddLit(buf, "</source>\n");
> I'll reindent this...
>
> ACK
>
> John
>
>>   
>>       return 0;
>>

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list