mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-25 07:05:28 +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__
|
||||
|
||||
int
|
||||
|
@ -403,4 +403,9 @@ virNodeDeviceGetPCIDynamicCaps(const char *sysfsPath,
|
||||
|
||||
int
|
||||
virNodeDeviceUpdateCaps(virNodeDeviceDefPtr def);
|
||||
|
||||
int
|
||||
virNodeDeviceCapsListExport(virNodeDeviceDefPtr def,
|
||||
virNodeDevCapType **list);
|
||||
|
||||
#endif /* __VIR_NODE_DEVICE_CONF_H__ */
|
||||
|
@ -699,6 +699,7 @@ virNodeDevCapMdevTypeFree;
|
||||
virNodeDevCapsDefFree;
|
||||
virNodeDevCapTypeFromString;
|
||||
virNodeDevCapTypeToString;
|
||||
virNodeDeviceCapsListExport;
|
||||
virNodeDeviceCreateVport;
|
||||
virNodeDeviceDefFormat;
|
||||
virNodeDeviceDefFree;
|
||||
|
@ -306,8 +306,6 @@ nodeDeviceNumOfCaps(virNodeDevicePtr device)
|
||||
{
|
||||
virNodeDeviceObjPtr obj;
|
||||
virNodeDeviceDefPtr def;
|
||||
virNodeDevCapsDefPtr caps;
|
||||
int ncaps = 0;
|
||||
int ret = -1;
|
||||
|
||||
if (!(obj = nodeDeviceObjFindByName(device->name)))
|
||||
@ -317,27 +315,7 @@ nodeDeviceNumOfCaps(virNodeDevicePtr device)
|
||||
if (virNodeDeviceNumOfCapsEnsureACL(device->conn, def) < 0)
|
||||
goto cleanup;
|
||||
|
||||
for (caps = def->caps; caps; caps = caps->next) {
|
||||
++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;
|
||||
ret = virNodeDeviceCapsListExport(def, NULL);
|
||||
|
||||
cleanup:
|
||||
virNodeDeviceObjEndAPI(&obj);
|
||||
@ -353,9 +331,10 @@ nodeDeviceListCaps(virNodeDevicePtr device,
|
||||
{
|
||||
virNodeDeviceObjPtr obj;
|
||||
virNodeDeviceDefPtr def;
|
||||
virNodeDevCapsDefPtr caps;
|
||||
virNodeDevCapType *list = NULL;
|
||||
int ncaps = 0;
|
||||
int ret = -1;
|
||||
size_t i = 0;
|
||||
|
||||
if (!(obj = nodeDeviceObjFindByName(device->name)))
|
||||
return -1;
|
||||
@ -364,46 +343,28 @@ nodeDeviceListCaps(virNodeDevicePtr device,
|
||||
if (virNodeDeviceListCapsEnsureACL(device->conn, def) < 0)
|
||||
goto cleanup;
|
||||
|
||||
for (caps = def->caps; caps && ncaps < maxnames; caps = caps->next) {
|
||||
if (VIR_STRDUP(names[ncaps++], virNodeDevCapTypeToString(caps->data.type)) < 0)
|
||||
if ((ncaps = virNodeDeviceCapsListExport(def, &list)) < 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;
|
||||
|
||||
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;
|
||||
|
||||
cleanup:
|
||||
virNodeDeviceObjEndAPI(&obj);
|
||||
if (ret == -1) {
|
||||
--ncaps;
|
||||
while (--ncaps >= 0)
|
||||
VIR_FREE(names[ncaps]);
|
||||
if (ret < 0) {
|
||||
size_t j;
|
||||
for (j = 0; j < i; j++)
|
||||
VIR_FREE(names[j]);
|
||||
}
|
||||
|
||||
VIR_FREE(list);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user