mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-28 11:31:16 +00:00
nodedev: Introduce virNodeDeviceCapsListExport
Whether asking for a number of capabilities supported by a device or listing them, it's handled essentially by a copy-paste code, so extract the common stuff into this new helper which also updates all capabilities just before touching them. Signed-off-by: Erik Skultety <eskultet@redhat.com>
This commit is contained in:
parent
349dda1fc8
commit
36546e3cdb
@ -2487,6 +2487,79 @@ virNodeDeviceUpdateCaps(virNodeDeviceDefPtr def)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virNodeDeviceCapsListExport:
|
||||||
|
* @def: node device definition
|
||||||
|
* @list: pointer to an array to store all supported capabilities by a device
|
||||||
|
*
|
||||||
|
* Takes the definition, scans through all the capabilities that the device
|
||||||
|
* supports (including the nested caps) and populates a newly allocated list
|
||||||
|
* with them. Caller is responsible for freeing the list.
|
||||||
|
* If NULL is passed to @list, only the number of caps will be returned.
|
||||||
|
*
|
||||||
|
* Returns the number of capabilities the device supports, -1 on error.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
virNodeDeviceCapsListExport(virNodeDeviceDefPtr def,
|
||||||
|
virNodeDevCapType **list)
|
||||||
|
{
|
||||||
|
virNodeDevCapsDefPtr caps = NULL;
|
||||||
|
virNodeDevCapType *tmp = NULL;
|
||||||
|
bool want_list = !!list;
|
||||||
|
int ncaps = 0;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
#define MAYBE_ADD_CAP(cap) \
|
||||||
|
do { \
|
||||||
|
if (want_list) \
|
||||||
|
tmp[ncaps] = cap; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
if (want_list && VIR_ALLOC_N(tmp, VIR_NODE_DEV_CAP_LAST - 1) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
for (caps = def->caps; caps; caps = caps->next) {
|
||||||
|
unsigned int flags;
|
||||||
|
|
||||||
|
MAYBE_ADD_CAP(caps->data.type);
|
||||||
|
ncaps++;
|
||||||
|
|
||||||
|
/* check nested caps for a given type as well */
|
||||||
|
if (caps->data.type == VIR_NODE_DEV_CAP_SCSI_HOST) {
|
||||||
|
flags = caps->data.scsi_host.flags;
|
||||||
|
|
||||||
|
if (flags & VIR_NODE_DEV_CAP_FLAG_HBA_FC_HOST) {
|
||||||
|
MAYBE_ADD_CAP(VIR_NODE_DEV_CAP_FC_HOST);
|
||||||
|
ncaps++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & VIR_NODE_DEV_CAP_FLAG_HBA_VPORT_OPS) {
|
||||||
|
MAYBE_ADD_CAP(VIR_NODE_DEV_CAP_VPORTS);
|
||||||
|
ncaps++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (caps->data.type == VIR_NODE_DEV_CAP_PCI_DEV) {
|
||||||
|
flags = caps->data.pci_dev.flags;
|
||||||
|
|
||||||
|
if (flags & VIR_NODE_DEV_CAP_FLAG_PCI_MDEV) {
|
||||||
|
MAYBE_ADD_CAP(VIR_NODE_DEV_CAP_MDEV_TYPES);
|
||||||
|
ncaps++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef MAYBE_ADD_CAP
|
||||||
|
|
||||||
|
if (want_list)
|
||||||
|
VIR_STEAL_PTR(*list, tmp);
|
||||||
|
ret = ncaps;
|
||||||
|
cleanup:
|
||||||
|
VIR_FREE(tmp);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -403,4 +403,9 @@ virNodeDeviceGetPCIDynamicCaps(const char *sysfsPath,
|
|||||||
|
|
||||||
int
|
int
|
||||||
virNodeDeviceUpdateCaps(virNodeDeviceDefPtr def);
|
virNodeDeviceUpdateCaps(virNodeDeviceDefPtr def);
|
||||||
|
|
||||||
|
int
|
||||||
|
virNodeDeviceCapsListExport(virNodeDeviceDefPtr def,
|
||||||
|
virNodeDevCapType **list);
|
||||||
|
|
||||||
#endif /* __VIR_NODE_DEVICE_CONF_H__ */
|
#endif /* __VIR_NODE_DEVICE_CONF_H__ */
|
||||||
|
@ -699,6 +699,7 @@ virNodeDevCapMdevTypeFree;
|
|||||||
virNodeDevCapsDefFree;
|
virNodeDevCapsDefFree;
|
||||||
virNodeDevCapTypeFromString;
|
virNodeDevCapTypeFromString;
|
||||||
virNodeDevCapTypeToString;
|
virNodeDevCapTypeToString;
|
||||||
|
virNodeDeviceCapsListExport;
|
||||||
virNodeDeviceCreateVport;
|
virNodeDeviceCreateVport;
|
||||||
virNodeDeviceDefFormat;
|
virNodeDeviceDefFormat;
|
||||||
virNodeDeviceDefFree;
|
virNodeDeviceDefFree;
|
||||||
|
@ -306,8 +306,6 @@ nodeDeviceNumOfCaps(virNodeDevicePtr device)
|
|||||||
{
|
{
|
||||||
virNodeDeviceObjPtr obj;
|
virNodeDeviceObjPtr obj;
|
||||||
virNodeDeviceDefPtr def;
|
virNodeDeviceDefPtr def;
|
||||||
virNodeDevCapsDefPtr caps;
|
|
||||||
int ncaps = 0;
|
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
if (!(obj = nodeDeviceObjFindByName(device->name)))
|
if (!(obj = nodeDeviceObjFindByName(device->name)))
|
||||||
@ -317,27 +315,7 @@ nodeDeviceNumOfCaps(virNodeDevicePtr device)
|
|||||||
if (virNodeDeviceNumOfCapsEnsureACL(device->conn, def) < 0)
|
if (virNodeDeviceNumOfCapsEnsureACL(device->conn, def) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
for (caps = def->caps; caps; caps = caps->next) {
|
ret = virNodeDeviceCapsListExport(def, NULL);
|
||||||
++ncaps;
|
|
||||||
|
|
||||||
if (caps->data.type == VIR_NODE_DEV_CAP_SCSI_HOST) {
|
|
||||||
if (caps->data.scsi_host.flags &
|
|
||||||
VIR_NODE_DEV_CAP_FLAG_HBA_FC_HOST)
|
|
||||||
ncaps++;
|
|
||||||
|
|
||||||
if (caps->data.scsi_host.flags &
|
|
||||||
VIR_NODE_DEV_CAP_FLAG_HBA_VPORT_OPS)
|
|
||||||
ncaps++;
|
|
||||||
}
|
|
||||||
if (caps->data.type == VIR_NODE_DEV_CAP_PCI_DEV) {
|
|
||||||
if (caps->data.pci_dev.flags &
|
|
||||||
VIR_NODE_DEV_CAP_FLAG_PCI_MDEV)
|
|
||||||
ncaps++;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = ncaps;
|
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
virNodeDeviceObjEndAPI(&obj);
|
virNodeDeviceObjEndAPI(&obj);
|
||||||
@ -353,9 +331,10 @@ nodeDeviceListCaps(virNodeDevicePtr device,
|
|||||||
{
|
{
|
||||||
virNodeDeviceObjPtr obj;
|
virNodeDeviceObjPtr obj;
|
||||||
virNodeDeviceDefPtr def;
|
virNodeDeviceDefPtr def;
|
||||||
virNodeDevCapsDefPtr caps;
|
virNodeDevCapType *list = NULL;
|
||||||
int ncaps = 0;
|
int ncaps = 0;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
if (!(obj = nodeDeviceObjFindByName(device->name)))
|
if (!(obj = nodeDeviceObjFindByName(device->name)))
|
||||||
return -1;
|
return -1;
|
||||||
@ -364,46 +343,28 @@ nodeDeviceListCaps(virNodeDevicePtr device,
|
|||||||
if (virNodeDeviceListCapsEnsureACL(device->conn, def) < 0)
|
if (virNodeDeviceListCapsEnsureACL(device->conn, def) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
for (caps = def->caps; caps && ncaps < maxnames; caps = caps->next) {
|
if ((ncaps = virNodeDeviceCapsListExport(def, &list)) < 0)
|
||||||
if (VIR_STRDUP(names[ncaps++], virNodeDevCapTypeToString(caps->data.type)) < 0)
|
goto cleanup;
|
||||||
|
|
||||||
|
if (ncaps > maxnames)
|
||||||
|
ncaps = maxnames;
|
||||||
|
|
||||||
|
for (i = 0; i < ncaps; i++) {
|
||||||
|
if (VIR_STRDUP(names[i], virNodeDevCapTypeToString(list[i])) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (caps->data.type == VIR_NODE_DEV_CAP_SCSI_HOST) {
|
|
||||||
if (ncaps < maxnames &&
|
|
||||||
caps->data.scsi_host.flags &
|
|
||||||
VIR_NODE_DEV_CAP_FLAG_HBA_FC_HOST) {
|
|
||||||
if (VIR_STRDUP(names[ncaps++],
|
|
||||||
virNodeDevCapTypeToString(VIR_NODE_DEV_CAP_FC_HOST)) < 0)
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ncaps < maxnames &&
|
|
||||||
caps->data.scsi_host.flags &
|
|
||||||
VIR_NODE_DEV_CAP_FLAG_HBA_VPORT_OPS) {
|
|
||||||
if (VIR_STRDUP(names[ncaps++],
|
|
||||||
virNodeDevCapTypeToString(VIR_NODE_DEV_CAP_VPORTS)) < 0)
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (caps->data.type == VIR_NODE_DEV_CAP_PCI_DEV) {
|
|
||||||
if (ncaps < maxnames &&
|
|
||||||
caps->data.pci_dev.flags &
|
|
||||||
VIR_NODE_DEV_CAP_FLAG_PCI_MDEV) {
|
|
||||||
if (VIR_STRDUP(names[ncaps++],
|
|
||||||
virNodeDevCapTypeToString(VIR_NODE_DEV_CAP_MDEV_TYPES)) < 0)
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = ncaps;
|
ret = ncaps;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
virNodeDeviceObjEndAPI(&obj);
|
virNodeDeviceObjEndAPI(&obj);
|
||||||
if (ret == -1) {
|
if (ret < 0) {
|
||||||
--ncaps;
|
size_t j;
|
||||||
while (--ncaps >= 0)
|
for (j = 0; j < i; j++)
|
||||||
VIR_FREE(names[ncaps]);
|
VIR_FREE(names[j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VIR_FREE(list);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user