[libvirt PATCH] nodedev: handle mdevs from multiple parents
Jonathon Jongsma
jjongsma at redhat.com
Tue Jun 22 15:08:36 UTC 2021
ping
On Thu, Jun 10, 2021 at 1:18 PM Jonathon Jongsma <jjongsma at redhat.com> wrote:
>
> Due to a rather unfortunate misunderstanding, we were parsing the list
> of defined devices from mdevctl incorrectly. Since my primary
> development machine only has a single device capable of mdevs, I
> apparently neglected to test multiple parent devices and made some
> assumptions based on reading the mdevctl code. These assumptions turned
> out to be incorrect, so the parsing failed when devices from more than
> one parent device were returned.
>
> The details: mdevctl returns an array of objects representing the
> defined devices. But instead of an array of multiple objects (with each
> object representing a parent device), the array always contains only a
> single object. That object has a separate property for each parent
> device.
>
> Signed-off-by: Jonathon Jongsma <jjongsma at redhat.com>
> ---
> src/node_device/node_device_driver.c | 41 ++++++++++---------
> .../mdevctl-list-multiple.json | 4 +-
> 2 files changed, 23 insertions(+), 22 deletions(-)
>
> diff --git a/src/node_device/node_device_driver.c b/src/node_device/node_device_driver.c
> index 8a0a2c3847..cb2c3ceaa4 100644
> --- a/src/node_device/node_device_driver.c
> +++ b/src/node_device/node_device_driver.c
> @@ -1056,6 +1056,7 @@ nodeDeviceParseMdevctlJSON(const char *jsonstring,
> size_t noutdevs = 0;
> size_t i;
> size_t j;
> + virJSONValue *obj;
>
> json_devicelist = virJSONValueFromString(jsonstring);
>
> @@ -1065,31 +1066,33 @@ nodeDeviceParseMdevctlJSON(const char *jsonstring,
> goto error;
> }
>
> - n = virJSONValueArraySize(json_devicelist);
> + /* mdevctl list --dumpjson produces an output that is an array that
> + * contains only a single object which contains a property for each parent
> + * device */
> + if (virJSONValueArraySize(json_devicelist) != 1) {
> + virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> + _("Unexpected format for mdevctl response"));
> + goto error;
> + }
> +
> + obj = virJSONValueArrayGet(json_devicelist, 0);
> +
> + if (!virJSONValueIsObject(obj)) {
> + virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> + _("device list is not an object"));
> + goto error;
> + }
>
> + n = virJSONValueObjectKeysNumber(obj);
> for (i = 0; i < n; i++) {
> - virJSONValue *obj = virJSONValueArrayGet(json_devicelist, i);
> const char *parent;
> virJSONValue *child_array;
> int nchildren;
>
> - if (!virJSONValueIsObject(obj)) {
> - virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> - _("Parent device is not an object"));
> - goto error;
> - }
> -
> - /* mdevctl returns an array of objects. Each object is a parent device
> - * object containing a single key-value pair which maps from the name
> - * of the parent device to an array of child devices */
> - if (virJSONValueObjectKeysNumber(obj) != 1) {
> - virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> - _("Unexpected format for parent device object"));
> - goto error;
> - }
> -
> - parent = virJSONValueObjectGetKey(obj, 0);
> - child_array = virJSONValueObjectGetValue(obj, 0);
> + /* The key of each object property is the name of a parent device
> + * which maps to an array of child devices */
> + parent = virJSONValueObjectGetKey(obj, i);
> + child_array = virJSONValueObjectGetValue(obj, i);
>
> if (!virJSONValueIsArray(child_array)) {
> virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> diff --git a/tests/nodedevmdevctldata/mdevctl-list-multiple.json b/tests/nodedevmdevctldata/mdevctl-list-multiple.json
> index eefcd90c62..ca1918d00a 100644
> --- a/tests/nodedevmdevctldata/mdevctl-list-multiple.json
> +++ b/tests/nodedevmdevctldata/mdevctl-list-multiple.json
> @@ -24,9 +24,7 @@
> ]
> }
> }
> - ]
> - },
> - {
> + ],
> "matrix": [
> { "783e6dbb-ea0e-411f-94e2-717eaad438bf": {
> "mdev_type": "vfio_ap-passthrough",
> --
> 2.31.1
>
More information about the libvir-list
mailing list