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:
parent
8f3054a0f8
commit
8b629a3c01
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -700,6 +700,7 @@ virNodeDeviceDefParseNode;
|
|||||||
virNodeDeviceDefParseString;
|
virNodeDeviceDefParseString;
|
||||||
virNodeDeviceFindByName;
|
virNodeDeviceFindByName;
|
||||||
virNodeDeviceFindBySysfsPath;
|
virNodeDeviceFindBySysfsPath;
|
||||||
|
virNodeDeviceFindVportParentHost;
|
||||||
virNodeDeviceGetParentHost;
|
virNodeDeviceGetParentHost;
|
||||||
virNodeDeviceGetWWNs;
|
virNodeDeviceGetWWNs;
|
||||||
virNodeDeviceHasCap;
|
virNodeDeviceHasCap;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user