1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2025-03-07 17:28:15 +00:00

nodedev: Add ability to find a vport capable vHBA

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>
This commit is contained in:
John Ferlan 2016-11-16 17:50:09 -05:00
parent 8f3054a0f8
commit 8b629a3c01
4 changed files with 61 additions and 7 deletions

View File

@ -75,14 +75,19 @@ virNodeDevCapsDefParseString(const char *xpath,
int virNodeDeviceHasCap(const virNodeDeviceObj *dev, const char *cap) int virNodeDeviceHasCap(const virNodeDeviceObj *dev, const char *cap)
{ {
virNodeDevCapsDefPtr caps = dev->def->caps; 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) { while (caps) {
if (STREQ(cap, virNodeDevCapTypeToString(caps->data.type))) if (STREQ(cap, virNodeDevCapTypeToString(caps->data.type)))
return 1; return 1;
else if (caps->data.type == VIR_NODE_DEV_CAP_SCSI_HOST) 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 & (caps->data.scsi_host.flags &
VIR_NODE_DEV_CAP_FLAG_HBA_FC_HOST)) || VIR_NODE_DEV_CAP_FLAG_HBA_FC_HOST)) ||
(STREQ(cap, "vports") && (STREQ(cap, vports_cap) &&
(caps->data.scsi_host.flags & (caps->data.scsi_host.flags &
VIR_NODE_DEV_CAP_FLAG_HBA_VPORT_OPS))) VIR_NODE_DEV_CAP_FLAG_HBA_VPORT_OPS)))
return 1; 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) void virNodeDeviceDefFree(virNodeDeviceDefPtr def)
{ {
virNodeDevCapsDefPtr caps; virNodeDevCapsDefPtr caps;
@ -1828,6 +1850,29 @@ virNodeDeviceGetParentHost(virNodeDeviceObjListPtr devs,
return ret; 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) void virNodeDevCapsDefFree(virNodeDevCapsDefPtr caps)
{ {
size_t i = 0; size_t i = 0;

View File

@ -273,6 +273,9 @@ int virNodeDeviceGetParentHost(virNodeDeviceObjListPtr devs,
const char *parent_name, const char *parent_name,
int *parent_host); int *parent_host);
int virNodeDeviceFindVportParentHost(virNodeDeviceObjListPtr devs,
int *parent_host);
void virNodeDeviceDefFree(virNodeDeviceDefPtr def); void virNodeDeviceDefFree(virNodeDeviceDefPtr def);
void virNodeDeviceObjFree(virNodeDeviceObjPtr dev); void virNodeDeviceObjFree(virNodeDeviceObjPtr dev);

View File

@ -700,6 +700,7 @@ virNodeDeviceDefParseNode;
virNodeDeviceDefParseString; virNodeDeviceDefParseString;
virNodeDeviceFindByName; virNodeDeviceFindByName;
virNodeDeviceFindBySysfsPath; virNodeDeviceFindBySysfsPath;
virNodeDeviceFindVportParentHost;
virNodeDeviceGetParentHost; virNodeDeviceGetParentHost;
virNodeDeviceGetWWNs; virNodeDeviceGetWWNs;
virNodeDeviceHasCap; virNodeDeviceHasCap;

View File

@ -584,10 +584,15 @@ nodeDeviceCreateXML(virConnectPtr conn,
if (virNodeDeviceGetWWNs(def, &wwnn, &wwpn) == -1) if (virNodeDeviceGetWWNs(def, &wwnn, &wwpn) == -1)
goto cleanup; goto cleanup;
if (def->parent) {
if (virNodeDeviceGetParentHost(&driver->devs, if (virNodeDeviceGetParentHost(&driver->devs,
def->name, def->name,
def->parent, def->parent,
&parent_host) == -1) { &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; goto cleanup;
} }