Commit e9b534905f4 introduced an error when parsing an empty list
returned from mdevctl.
This occurs e.g. if nodedev-undefine is used to undefine the last
defined mdev which cuases the following error messages
libvirtd[33143]: internal error: Unexpected format for mdevctl
response libvirtd[33143]: internal error: failed to query mdevs from
mdevctl: libvirtd[33143]: mdevctl failed to updated mediated devices
Signed-off-by: Boris Fiuczynski <fiuczy@xxxxxxxxxxxxx>
---
src/node_device/node_device_driver.c | 68
++++++++++--------- .../mdevctl-list-empty.json |
1 + .../mdevctl-list-empty.out.xml | 0
tests/nodedevmdevctltest.c | 1 +
4 files changed, 37 insertions(+), 33 deletions(-)
create mode 100644 tests/nodedevmdevctldata/mdevctl-list-empty.json
create mode 100644
tests/nodedevmdevctldata/mdevctl-list-empty.out.xml
diff --git a/src/node_device/node_device_driver.c
b/src/node_device/node_device_driver.c index b4dd57e5f4..31525f2312
100644 --- a/src/node_device/node_device_driver.c
+++ b/src/node_device/node_device_driver.c
@@ -1123,51 +1123,53 @@ nodeDeviceParseMdevctlJSON(const char
*jsonstring, /* 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++) {
- const char *parent;
- virJSONValue *child_array;
- int nchildren;
+ if (virJSONValueArraySize(json_devicelist) > 0) {
+ if (virJSONValueArraySize(json_devicelist) != 1) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Unexpected format for mdevctl
response"));
+ goto error;
+ }
- /* 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);
+ obj = virJSONValueArrayGet(json_devicelist, 0);
- if (!virJSONValueIsArray(child_array)) {
+ if (!virJSONValueIsObject(obj)) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("Parent device's JSON object data is
not an array"));
+ _("device list is not an object"));
goto error;
}
- nchildren = virJSONValueArraySize(child_array);
+ n = virJSONValueObjectKeysNumber(obj);
+ for (i = 0; i < n; i++) {
+ const char *parent;
+ virJSONValue *child_array;
+ int nchildren;
- for (j = 0; j < nchildren; j++) {
- g_autoptr(virNodeDeviceDef) child = NULL;
- virJSONValue *child_obj =
virJSONValueArrayGet(child_array, j);
+ /* 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 (!(child = nodeDeviceParseMdevctlChildDevice(parent,
child_obj))) {
+ if (!virJSONValueIsArray(child_array)) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("Unable to parse child device"));
+ _("Parent device's JSON object data
is not an array")); goto error;
}
- if (VIR_APPEND_ELEMENT(outdevs, noutdevs, child) < 0)
- goto error;
+ nchildren = virJSONValueArraySize(child_array);
+
+ for (j = 0; j < nchildren; j++) {
+ g_autoptr(virNodeDeviceDef) child = NULL;
+ virJSONValue *child_obj =
virJSONValueArrayGet(child_array, j); +
+ if (!(child =
nodeDeviceParseMdevctlChildDevice(parent, child_obj))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Unable to parse child
device"));
+ goto error;
+ }
+
+ if (VIR_APPEND_ELEMENT(outdevs, noutdevs, child) < 0)
+ goto error;
+ }
}
}
diff --git a/tests/nodedevmdevctldata/mdevctl-list-empty.json
b/tests/nodedevmdevctldata/mdevctl-list-empty.json new file mode
100644 index 0000000000..fe51488c70
--- /dev/null
+++ b/tests/nodedevmdevctldata/mdevctl-list-empty.json
@@ -0,0 +1 @@
+[]
diff --git a/tests/nodedevmdevctldata/mdevctl-list-empty.out.xml
b/tests/nodedevmdevctldata/mdevctl-list-empty.out.xml new file mode
100644 index 0000000000..e69de29bb2
diff --git a/tests/nodedevmdevctltest.c b/tests/nodedevmdevctltest.c
index 8ba1d2da70..e246de4d87 100644
--- a/tests/nodedevmdevctltest.c
+++ b/tests/nodedevmdevctltest.c
@@ -360,6 +360,7 @@ mymain(void)
DO_TEST_LIST_DEFINED();
+ DO_TEST_PARSE_JSON("mdevctl-list-empty");
DO_TEST_PARSE_JSON("mdevctl-list-multiple");
DO_TEST_DEFINE("mdev_d069d019_36ea_4111_8f0a_8c9a70e21366");