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

Eric Farman farman at linux.vnet.ibm.com
Wed Oct 26 21:42:42 UTC 2016


Signed-off-by: Eric Farman <farman at linux.vnet.ibm.com>
---
 docs/schemas/domaincommon.rng | 23 ++++++++++++
 src/conf/domain_audit.c       |  7 ++++
 src/conf/domain_conf.c        | 81 +++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 109 insertions(+), 2 deletions(-)

diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index dba9187..ad5d55d 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -3963,6 +3963,7 @@
       <ref name="hostdevsubsyspci"/>
       <ref name="hostdevsubsysusb"/>
       <ref name="hostdevsubsysscsi"/>
+      <ref name="hostdevsubsyshost"/>
     </choice>
   </define>
 
@@ -4091,6 +4092,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..844b3cd 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;
+    virDomainHostdevSubsysHostPtr hostsrc = &hostdev->source.subsys.u.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_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 08c4f8b..79cf32e 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -2318,6 +2318,9 @@ void virDomainHostdevDefClear(virDomainHostdevDefPtr def)
             } else {
                 VIR_FREE(scsisrc->u.host.adapter);
             }
+        } else if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_HOST) {
+            virDomainHostdevSubsysHostPtr hostsrc = &def->source.subsys.u.host;
+            VIR_FREE(hostsrc->wwpn);
         }
         break;
     }
@@ -6087,6 +6090,55 @@ virDomainHostdevSubsysSCSIDefParseXML(xmlNodePtr sourcenode,
     return ret;
 }
 
+static int
+virDomainHostdevSubsysHostDefParseXML(xmlNodePtr sourcenode,
+                                      virDomainHostdevDefPtr def)
+{
+    char *protocol = NULL;
+    virDomainHostdevSubsysHostPtr hostsrc = &def->source.subsys.u.host;
+
+    if ((protocol = virXMLPropString(sourcenode, "protocol"))) {
+        hostsrc->protocol =
+            virDomainHostdevSubsysHostProtocolTypeFromString(protocol);
+        if (hostsrc->protocol <= 0) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                           _("Unknown scsi_host subsystem protocol '%s'"),
+                           protocol);
+            goto cleanup;
+        }
+    }
+
+    switch ((virDomainHostdevSubsysHostProtocolType) hostsrc->protocol) {
+    case VIR_DOMAIN_HOSTDEV_SUBSYS_HOST_PROTOCOL_TYPE_VHOST:
+        if (!(hostsrc->wwpn = virXMLPropString(sourcenode, "wwpn"))) {
+            virReportError(VIR_ERR_XML_ERROR, "%s",
+                           _("missing vhost-scsi hostdev source path name"));
+            goto cleanup;
+        }
+
+        if (!STRPREFIX(hostsrc->wwpn, "naa.") ||
+            strlen(hostsrc->wwpn) != strlen("naa.") + 16) {
+            virReportError(VIR_ERR_XML_ERROR, "%s", _("malformed 'wwpn' value"));
+            goto cleanup;
+        }
+        break;
+    case VIR_DOMAIN_HOSTDEV_SUBSYS_HOST_PROTOCOL_TYPE_NONE:
+    case VIR_DOMAIN_HOSTDEV_SUBSYS_HOST_PROTOCOL_TYPE_LAST:
+        virReportError(VIR_ERR_XML_ERROR,
+                       _("Invalid hostdev protocol '%s'"),
+                       virDomainHostdevSubsysHostProtocolTypeToString(def->source.subsys.type));
+        goto cleanup;
+        break;
+    }
+
+    return 0;
+
+ cleanup:
+    VIR_FREE(hostsrc->wwpn);
+    VIR_FREE(protocol);
+    return -1;
+}
+
 
 static int
 virDomainHostdevDefParseXMLSubsys(xmlNodePtr node,
@@ -6211,6 +6263,11 @@ virDomainHostdevDefParseXMLSubsys(xmlNodePtr node,
             goto error;
         break;
 
+    case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_HOST:
+        if (virDomainHostdevSubsysHostDefParseXML(sourcenode, def) < 0)
+            goto error;
+        break;
+
     default:
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                        _("address type='%s' not supported in hostdev interfaces"),
@@ -13889,7 +13946,13 @@ virDomainHostdevMatchSubsys(virDomainHostdevDefPtr a,
         else
             return virDomainHostdevMatchSubsysSCSIHost(a, b);
     case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_HOST:
-        /* Fall through for now */
+        if (a->source.subsys.u.host.protocol !=
+            b->source.subsys.u.host.protocol)
+            return 0;
+        if (STREQ(a->source.subsys.u.host.wwpn, b->source.subsys.u.host.wwpn))
+            return 1;
+        else
+            return 0;
     case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
         return 0;
     }
@@ -20784,9 +20847,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;
+    virDomainHostdevSubsysHostPtr hostsrc = &def->source.subsys.u.host;
     virDomainHostdevSubsysSCSIHostPtr scsihostsrc = &scsisrc->u.host;
     virDomainHostdevSubsysSCSIiSCSIPtr iscsisrc = &scsisrc->u.iscsi;
 
@@ -20827,6 +20892,15 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf,
                           protocol, iscsisrc->path);
     }
 
+    if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_HOST) {
+        const char *protocol =
+            virDomainHostdevSubsysHostProtocolTypeToString(hostsrc->protocol);
+        closedSource = true;
+
+        virBufferAsprintf(buf, " protocol='%s' wwpn='%s'/",
+                          protocol, hostsrc->wwpn);
+    }
+
     virBufferAddLit(buf, ">\n");
 
     virBufferAdjustIndent(buf, 2);
@@ -20880,6 +20954,8 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf,
                               scsihostsrc->unit);
         }
         break;
+    case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_HOST:
+        break;
     default:
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("unexpected hostdev type %d"),
@@ -20895,7 +20971,8 @@ virDomainHostdevDefFormatSubsys(virBufferPtr buf,
     }
 
     virBufferAdjustIndent(buf, -2);
-    virBufferAddLit(buf, "</source>\n");
+    if (!closedSource)
+        virBufferAddLit(buf, "</source>\n");
 
     return 0;
 }
-- 
1.9.1




More information about the libvir-list mailing list