Create a hash table of device property names which also stores the corresponding JSON object so that the detection code can look at the recently added 'default-value' field and possibly others. Signed-off-by: Peter Krempa <pkrempa@xxxxxxxxxx> --- src/qemu/qemu_capabilities.c | 18 ++++++++------ src/qemu/qemu_monitor.c | 11 ++++----- src/qemu/qemu_monitor.h | 5 ++-- src/qemu/qemu_monitor_json.c | 46 +++++++++++++++++++++++++++++------- src/qemu/qemu_monitor_json.h | 7 +++--- 5 files changed, 58 insertions(+), 29 deletions(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 42425fabbd..ae1f0853f1 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -2580,20 +2580,24 @@ virQEMUCapsProbeQMPDeviceProperties(virQEMUCapsPtr qemuCaps, for (i = 0; i < G_N_ELEMENTS(virQEMUCapsDeviceProps); i++) { virQEMUCapsObjectTypeProps *device = virQEMUCapsDeviceProps + i; - VIR_AUTOSTRINGLIST values = NULL; - int nvalues; + g_autoptr(virHashTable) qemuprops = NULL; + size_t j; if (device->capsCondition >= 0 && !virQEMUCapsGet(qemuCaps, device->capsCondition)) continue; - if ((nvalues = qemuMonitorGetDeviceProps(mon, device->type, &values)) < 0) + if (!(qemuprops = qemuMonitorGetDeviceProps(mon, device->type))) return -1; - virQEMUCapsProcessStringFlags(qemuCaps, - device->nprops, - device->props, - nvalues, values); + for (j = 0; j < device->nprops; j++) { + virJSONValuePtr entry = virHashLookup(qemuprops, device->props[j].value); + + if (!entry) + continue; + + virQEMUCapsSet(qemuCaps, device->props[j].flag); + } } return 0; diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 339facfad3..9c853ccb93 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -3764,16 +3764,15 @@ qemuMonitorGetObjectTypes(qemuMonitorPtr mon, } -int +virHashTablePtr qemuMonitorGetDeviceProps(qemuMonitorPtr mon, - const char *device, - char ***props) + const char *device) { - VIR_DEBUG("device=%s props=%p", device, props); + VIR_DEBUG("device=%s", device); - QEMU_CHECK_MONITOR(mon); + QEMU_CHECK_MONITOR_NULL(mon); - return qemuMonitorJSONGetDeviceProps(mon, device, props); + return qemuMonitorJSONGetDeviceProps(mon, device); } diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 68e21dcaee..2e35d94bda 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -1203,9 +1203,8 @@ int qemuMonitorGetKVMState(qemuMonitorPtr mon, int qemuMonitorGetObjectTypes(qemuMonitorPtr mon, char ***types); -int qemuMonitorGetDeviceProps(qemuMonitorPtr mon, - const char *device, - char ***props); +virHashTablePtr qemuMonitorGetDeviceProps(qemuMonitorPtr mon, + const char *device); int qemuMonitorGetObjectProps(qemuMonitorPtr mon, const char *object, char ***props); diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 9d1db07ccd..505b31a78a 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -6745,28 +6745,56 @@ qemuMonitorJSONParsePropsList(virJSONValuePtr cmd, } -int +static int +qemuMonitorJSONGetDevicePropsWorker(size_t pos G_GNUC_UNUSED, + virJSONValuePtr item, + void *opaque) +{ + const char *name = virJSONValueObjectGetString(item, "name"); + virHashTablePtr devices = opaque; + + if (!name) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("reply data was missing 'name'")); + return -1; + } + + if (virHashAddEntry(devices, name, item) < 0) + return -1; + + return 0; +} + + +virHashTablePtr qemuMonitorJSONGetDeviceProps(qemuMonitorPtr mon, - const char *device, - char ***props) + const char *device) { + g_autoptr(virHashTable) props = virHashNew(virJSONValueHashFree); g_autoptr(virJSONValue) cmd = NULL; g_autoptr(virJSONValue) reply = NULL; - *props = NULL; - if (!(cmd = qemuMonitorJSONMakeCommand("device-list-properties", "s:typename", device, NULL))) - return -1; + return NULL; if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0) - return -1; + return NULL; + /* return empty hash */ if (qemuMonitorJSONHasError(reply, "DeviceNotFound")) - return 0; + return g_steal_pointer(&props); + + if (qemuMonitorJSONCheckReply(cmd, reply, VIR_JSON_TYPE_ARRAY) < 0) + return NULL; + + if (virJSONValueArrayForeachSteal(virJSONValueObjectGetArray(reply, "return"), + qemuMonitorJSONGetDevicePropsWorker, + props) < 0) + return NULL; - return qemuMonitorJSONParsePropsList(cmd, reply, NULL, props); + return g_steal_pointer(&props); } diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index 05a46b4fe2..d3d46ec2f7 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -487,10 +487,9 @@ int qemuMonitorJSONSetObjectProperty(qemuMonitorPtr mon, qemuMonitorJSONObjectPropertyPtr prop) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4); -int qemuMonitorJSONGetDeviceProps(qemuMonitorPtr mon, - const char *device, - char ***props) - ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); +virHashTablePtr qemuMonitorJSONGetDeviceProps(qemuMonitorPtr mon, + const char *device) + ATTRIBUTE_NONNULL(2); int qemuMonitorJSONGetObjectProps(qemuMonitorPtr mon, const char *object, char ***props) -- 2.26.2