[libvirt] [PATCH 07/15] nodedev: Introduce virNodeDeviceCapsListExport
Wuzongyong (Euler Dept)
cordius.wu at huawei.com
Fri Jan 26 09:00:32 UTC 2018
> -----Original Message-----
> From: libvir-list-bounces at redhat.com [mailto:libvir-list-
> bounces at redhat.com] On Behalf Of Erik Skultety
> Sent: Thursday, January 25, 2018 5:24 PM
> To: libvir-list at redhat.com
> Cc: Erik Skultety <eskultet at redhat.com>
> Subject: [libvirt] [PATCH 07/15] 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 at redhat.com>
> ---
> src/conf/node_device_conf.c | 73
> +++++++++++++++++++++++++++++++++++
> src/conf/node_device_conf.h | 5 +++
> src/libvirt_private.syms | 1 +
> src/node_device/node_device_driver.c | 75 +++++++++----------------------
> -----
> 4 files changed, 97 insertions(+), 57 deletions(-)
>
> diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c
> index 217673a56..9467bb415 100644
> --- a/src/conf/node_device_conf.c
> +++ b/src/conf/node_device_conf.c
> @@ -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
> diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h
> index 7e32f5c05..53cdfdb01 100644
> --- a/src/conf/node_device_conf.h
> +++ b/src/conf/node_device_conf.h
> @@ -403,4 +403,9 @@ virNodeDeviceGetPCIDynamicCaps(const char *sysfsPath,
>
> int
> virNodeDeviceUpdateCaps(virNodeDeviceDefPtr def);
> +
> +int
> +virNodeDeviceCapsListExport(virNodeDeviceDefPtr def,
> + virNodeDevCapType **list);
> +
> #endif /* __VIR_NODE_DEVICE_CONF_H__ */ diff --git
> a/src/libvirt_private.syms b/src/libvirt_private.syms index
> 6098cf121..1698e6227 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -699,6 +699,7 @@ virNodeDevCapMdevTypeFree; virNodeDevCapsDefFree;
> virNodeDevCapTypeFromString; virNodeDevCapTypeToString;
> +virNodeDeviceCapsListExport;
> virNodeDeviceCreateVport;
> virNodeDeviceDefFormat;
> virNodeDeviceDefFree;
> diff --git a/src/node_device/node_device_driver.c
> b/src/node_device/node_device_driver.c
> index 48f45474c..8fb08742b 100644
> --- a/src/node_device/node_device_driver.c
> +++ b/src/node_device/node_device_driver.c
> @@ -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;
variable i should be initialized. Or the act is uncertain when cleanup.
Except this, this series of patches work well for me.
>
> 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;
> }
>
> --
> 2.13.6
>
> --
> libvir-list mailing list
> libvir-list at redhat.com
> https://www.redhat.com/mailman/listinfo/libvir-list
More information about the libvir-list
mailing list