From: John Ferlan Date: Wed, 16 Nov 2016 22:50:09 +0000 (-0500) Subject: nodedev: Add ability to find a vport capable vHBA X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=8b629a3c01b8c5e148f8bbe3776f19150784cf80;p=libvirt.git nodedev: Add ability to find a vport capable vHBA If a 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 --- diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c index 25e1f4b53c..b13cb6b989 100644 --- a/src/conf/node_device_conf.c +++ b/src/conf/node_device_conf.c @@ -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; diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h index 9f00500024..2b2aed758d 100644 --- a/src/conf/node_device_conf.h +++ b/src/conf/node_device_conf.h @@ -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); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 01118730bc..a928e9055d 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -700,6 +700,7 @@ virNodeDeviceDefParseNode; virNodeDeviceDefParseString; virNodeDeviceFindByName; virNodeDeviceFindBySysfsPath; +virNodeDeviceFindVportParentHost; virNodeDeviceGetParentHost; virNodeDeviceGetWWNs; virNodeDeviceHasCap; diff --git a/src/node_device/node_device_driver.c b/src/node_device/node_device_driver.c index 91bb142b24..474b71365f 100644 --- a/src/node_device/node_device_driver.c +++ b/src/node_device/node_device_driver.c @@ -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,