]> xenbits.xensource.com Git - libvirt.git/commitdiff
nodedev: Add ability to find a vport capable vHBA
authorJohn Ferlan <jferlan@redhat.com>
Wed, 16 Nov 2016 22:50:09 +0000 (17:50 -0500)
committerJohn Ferlan <jferlan@redhat.com>
Wed, 4 Jan 2017 22:09:59 +0000 (17:09 -0500)
If a <parent> is not supplied in the XML used to create a non-persistent
vHBA, then instead of failing, let's try to find a "vports" capable node
device and use that.

Signed-off-by: John Ferlan <jferlan@redhat.com>
src/conf/node_device_conf.c
src/conf/node_device_conf.h
src/libvirt_private.syms
src/node_device/node_device_driver.c

index 25e1f4b53c1fb8dd3e02fdbc6720924898dd719a..b13cb6b9899aca129f6b842f35a4fc9f637f5ff6 100644 (file)
@@ -75,14 +75,19 @@ virNodeDevCapsDefParseString(const char *xpath,
 int virNodeDeviceHasCap(const virNodeDeviceObj *dev, const char *cap)
 {
     virNodeDevCapsDefPtr caps = dev->def->caps;
+    const char *fc_host_cap =
+        virNodeDevCapTypeToString(VIR_NODE_DEV_CAP_FC_HOST);
+    const char *vports_cap =
+        virNodeDevCapTypeToString(VIR_NODE_DEV_CAP_VPORTS);
+
     while (caps) {
         if (STREQ(cap, virNodeDevCapTypeToString(caps->data.type)))
             return 1;
         else if (caps->data.type == VIR_NODE_DEV_CAP_SCSI_HOST)
-            if ((STREQ(cap, "fc_host") &&
+            if ((STREQ(cap, fc_host_cap) &&
                 (caps->data.scsi_host.flags &
                  VIR_NODE_DEV_CAP_FLAG_HBA_FC_HOST)) ||
-                (STREQ(cap, "vports") &&
+                (STREQ(cap, vports_cap) &&
                 (caps->data.scsi_host.flags &
                  VIR_NODE_DEV_CAP_FLAG_HBA_VPORT_OPS)))
                 return 1;
@@ -151,6 +156,23 @@ virNodeDeviceObjPtr virNodeDeviceFindByName(virNodeDeviceObjListPtr devs,
 }
 
 
+static virNodeDeviceObjPtr
+virNodeDeviceFindByCap(virNodeDeviceObjListPtr devs,
+                       const char *cap)
+{
+    size_t i;
+
+    for (i = 0; i < devs->count; i++) {
+        virNodeDeviceObjLock(devs->objs[i]);
+        if (virNodeDeviceHasCap(devs->objs[i], cap))
+            return devs->objs[i];
+        virNodeDeviceObjUnlock(devs->objs[i]);
+    }
+
+    return NULL;
+}
+
+
 void virNodeDeviceDefFree(virNodeDeviceDefPtr def)
 {
     virNodeDevCapsDefPtr caps;
@@ -1828,6 +1850,29 @@ virNodeDeviceGetParentHost(virNodeDeviceObjListPtr devs,
     return ret;
 }
 
+
+int
+virNodeDeviceFindVportParentHost(virNodeDeviceObjListPtr devs,
+                                 int *parent_host)
+{
+    virNodeDeviceObjPtr parent = NULL;
+    const char *cap = virNodeDevCapTypeToString(VIR_NODE_DEV_CAP_VPORTS);
+    int ret;
+
+    if (!(parent = virNodeDeviceFindByCap(devs, cap))) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("Could not find any vport capable device"));
+        return -1;
+    }
+
+    ret = virNodeDeviceFindFCParentHost(parent, parent_host);
+
+    virNodeDeviceObjUnlock(parent);
+
+    return ret;
+}
+
+
 void virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps)
 {
     size_t i = 0;
index 9f005000242084bb14f7287b2d5b9323cb067a5a..2b2aed758d5fc667883d9105e8faa6137b7b5809 100644 (file)
@@ -273,6 +273,9 @@ int virNodeDeviceGetParentHost(virNodeDeviceObjListPtr devs,
                                const char *parent_name,
                                int *parent_host);
 
+int virNodeDeviceFindVportParentHost(virNodeDeviceObjListPtr devs,
+                                     int *parent_host);
+
 void virNodeDeviceDefFree(virNodeDeviceDefPtr def);
 
 void virNodeDeviceObjFree(virNodeDeviceObjPtr dev);
index 01118730bc5d3f3381ddef16f92f0c7fdb685f1b..a928e9055d40729ef716f5b0cdb7729f75ca4b67 100644 (file)
@@ -700,6 +700,7 @@ virNodeDeviceDefParseNode;
 virNodeDeviceDefParseString;
 virNodeDeviceFindByName;
 virNodeDeviceFindBySysfsPath;
+virNodeDeviceFindVportParentHost;
 virNodeDeviceGetParentHost;
 virNodeDeviceGetWWNs;
 virNodeDeviceHasCap;
index 91bb142b24c16b17a42c3f19eb719b9d188febe6..474b71365f7fc5f5c25a792f081146982b5e8b2d 100644 (file)
@@ -584,11 +584,16 @@ nodeDeviceCreateXML(virConnectPtr conn,
     if (virNodeDeviceGetWWNs(def, &wwnn, &wwpn) == -1)
         goto cleanup;
 
-    if (virNodeDeviceGetParentHost(&driver->devs,
-                                   def->name,
-                                   def->parent,
-                                   &parent_host) == -1) {
-        goto cleanup;
+    if (def->parent) {
+        if (virNodeDeviceGetParentHost(&driver->devs,
+                                       def->name,
+                                       def->parent,
+                                       &parent_host) < 0)
+            goto cleanup;
+    } else {
+        /* Try to find a vport capable scsi_host when no parent supplied */
+        if (virNodeDeviceFindVportParentHost(&driver->devs, &parent_host) < 0)
+            goto cleanup;
     }
 
     if (virManageVport(parent_host,