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(a)redhat.com>
---
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 :|