On Thu, Dec 24, 2020 at 08:14:29AM -0600, Jonathon Jongsma wrote: > This adds some internal API to query for persistent mediated devices > that are defined by mdevctl. Following commits will make use of this > information. This just provides the infrastructure and tests for this > feature. One test verifies that we are executing mdevctl with the proper > arguments, and the other test verifies that we can parse the returned > JSON and convert it to our own internal node device representations. > > Signed-off-by: Jonathon Jongsma <jjongsma@xxxxxxxxxx> > --- > src/node_device/node_device_driver.c | 150 ++++++++++++++++++ > src/node_device/node_device_driver.h | 7 + > .../mdevctl-list-defined.argv | 1 + > .../mdevctl-list-multiple.json | 59 +++++++ > .../mdevctl-list-multiple.out.xml | 39 +++++ > tests/nodedevmdevctltest.c | 95 ++++++++++- > 6 files changed, 349 insertions(+), 2 deletions(-) > create mode 100644 tests/nodedevmdevctldata/mdevctl-list-defined.argv > create mode 100644 tests/nodedevmdevctldata/mdevctl-list-multiple.json > create mode 100644 tests/nodedevmdevctldata/mdevctl-list-multiple.out.xml > > diff --git a/src/node_device/node_device_driver.c b/src/node_device/node_device_driver.c > index 6143459618..bbd373e32e 100644 > --- a/src/node_device/node_device_driver.c > +++ b/src/node_device/node_device_driver.c > @@ -853,6 +853,156 @@ virMdevctlStop(virNodeDeviceDefPtr def) > } > +int > +nodeDeviceParseMdevctlJSON(const char *jsonstring, > + virNodeDeviceDefPtr **devs) > +{ > + int n; > + g_autoptr(virJSONValue) json_devicelist = NULL; > + virNodeDeviceDefPtr *outdevs = NULL; > + size_t noutdevs = 0; > + size_t i, j; > + > + json_devicelist = virJSONValueFromString(jsonstring); > + > + if (!json_devicelist) > + goto parsefailure; > + > + if (!virJSONValueIsArray(json_devicelist)) > + goto parsefailure; > + > + n = virJSONValueArraySize(json_devicelist); > + > + for (i = 0; i < n; i++) { > + virJSONValuePtr obj = virJSONValueArrayGet(json_devicelist, i); > + const char *parent; > + virJSONValuePtr child_array; > + int nchildren; > + > + if (!virJSONValueIsObject(obj)) > + goto parsefailure; > + > + /* 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) > + goto parsefailure; > + > + parent = virJSONValueObjectGetKey(obj, 0); > + child_array = virJSONValueObjectGetValue(obj, 0); > + > + if (!virJSONValueIsArray(child_array)) > + goto parsefailure; > + > + nchildren = virJSONValueArraySize(child_array); > + > + for (j = 0; j < nchildren; j++) { > + g_autoptr(virNodeDeviceDef) child = NULL; > + virJSONValuePtr child_obj = virJSONValueArrayGet(child_array, j); > + > + if (!(child = nodeDeviceParseMdevctlChildDevice(parent, child_obj))) > + goto parsefailure; > + > + if (VIR_APPEND_ELEMENT(outdevs, noutdevs, child) < 0) > + goto parsefailure; > + } > + } > + > + *devs = outdevs; > + return noutdevs; > + > + parsefailure: > + for (i = 0; i < noutdevs; i++) > + virNodeDeviceDefFree(outdevs[i]); > + VIR_FREE(outdevs); > + > + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", > + _("unable to parse JSON response")); This error message is horrible for debugging as it tells us nothing about what part of parsing failed. Please report error messages at the original site of the error > + return -1; > +} Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|