
On 02.07.2013 15:39, John Ferlan wrote:
Add a new qemuMonitorGetObjectProperty() method to support invocation of the 'qom-get' JSON monitor command with a provided path, property, and expected data type return. The qemuMonitorObjectProperty is similar to virTypedParameter; however, a future patch will extend it a bit to include a void pointer to balloon driver statistic data.
The provided test will execute a qom-get on "/machine/i440fx" which will return a property "realized". --- src/qemu/qemu_monitor.c | 23 ++++++++++++ src/qemu/qemu_monitor.h | 33 +++++++++++++++++ src/qemu/qemu_monitor_json.c | 86 ++++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_monitor_json.h | 6 ++++ tests/qemumonitorjsontest.c | 48 +++++++++++++++++++++++++ 5 files changed, 196 insertions(+)
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index f175250..6737a63 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -3468,6 +3468,29 @@ void qemuMonitorListPathFree(qemuMonitorListPathPtr paths) }
+int qemuMonitorGetObjectProperty(qemuMonitorPtr mon, + const char *path, + const char *property, + qemuMonitorObjectPropertyPtr prop) +{ + VIR_DEBUG("mon=%p path=%s property=%s prop=%p type=%d", + mon, path, property, prop, prop->type); + if (!mon) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("monitor must not be NULL")); + return -1; + } + + if (!mon->json) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("JSON monitor is required")); + return -1; + } + + return qemuMonitorJSONGetObjectProperty(mon, path, property, prop); +} + + int qemuMonitorGetObjectProps(qemuMonitorPtr mon, const char *type, char ***props) diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 2e92f8c..cc22123 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -694,6 +694,39 @@ int qemuMonitorGetObjectListPaths(qemuMonitorPtr mon,
void qemuMonitorListPathFree(qemuMonitorListPathPtr paths);
+/* Flags for the 'type' field in _qemuMonitorObjectProperty */ +typedef enum { + QEMU_MONITOR_OBJECT_PROPERTY_BOOLEAN=1, + QEMU_MONITOR_OBJECT_PROPERTY_INT, + QEMU_MONITOR_OBJECT_PROPERTY_LONG, + QEMU_MONITOR_OBJECT_PROPERTY_UINT, + QEMU_MONITOR_OBJECT_PROPERTY_ULONG, + QEMU_MONITOR_OBJECT_PROPERTY_DOUBLE, + QEMU_MONITOR_OBJECT_PROPERTY_STRING, + + QEMU_MONITOR_OBJECT_PROPERTY_LAST +} qemuMonitorObjectPropertyType; + +typedef struct _qemuMonitorObjectProperty qemuMonitorObjectProperty; +typedef qemuMonitorObjectProperty *qemuMonitorObjectPropertyPtr; +struct _qemuMonitorObjectProperty { + int type; /* qemuMonitorObjectPropertyType */ + union { + bool b; + int i; + long long l; + unsigned int ui; + unsigned long long ul; + double d; + char *str; + } val; +}; + +int qemuMonitorGetObjectProperty(qemuMonitorPtr mon, + const char *path, + const char *property, + qemuMonitorObjectPropertyPtr prop); + int qemuMonitorGetObjectProps(qemuMonitorPtr mon, const char *type, char ***props); diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 7d0cc85..a725903 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -4626,6 +4626,92 @@ cleanup: return ret; }
+ +int qemuMonitorJSONGetObjectProperty(qemuMonitorPtr mon, + const char *path, + const char *property, + qemuMonitorObjectPropertyPtr prop) +{ + int ret; + virJSONValuePtr cmd; + virJSONValuePtr reply = NULL; + virJSONValuePtr data; + const char *tmp; + + if (!(cmd = qemuMonitorJSONMakeCommand("qom-get", + "s:path", path, + "s:property", property, + NULL))) + return -1; + + ret = qemuMonitorJSONCommand(mon, cmd, &reply); + + if (ret == 0) + ret = qemuMonitorJSONCheckError(cmd, reply); + + if (ret < 0) + goto cleanup; + + ret = -1; + + if (!(data = virJSONValueObjectGet(reply, "return"))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("qom-get reply was missing return data")); + goto cleanup; + } + + switch (prop->type) { + /* Simple cases of boolean, int, long, uint, ulong, double, and string + * will receive return value as part of {"return": xxx} statement + */ + case QEMU_MONITOR_OBJECT_PROPERTY_BOOLEAN: + ret = virJSONValueGetBoolean(data, &prop->val.b); + break; + case QEMU_MONITOR_OBJECT_PROPERTY_INT: + ret = virJSONValueGetNumberInt(data, &prop->val.i); + break; + case QEMU_MONITOR_OBJECT_PROPERTY_LONG: + ret = virJSONValueGetNumberLong(data, &prop->val.l); + break; + case QEMU_MONITOR_OBJECT_PROPERTY_UINT: + ret = virJSONValueGetNumberUint(data, &prop->val.ui); + break; + case QEMU_MONITOR_OBJECT_PROPERTY_ULONG: + ret = virJSONValueGetNumberUlong(data, &prop->val.ul); + break; + case QEMU_MONITOR_OBJECT_PROPERTY_DOUBLE: + ret = virJSONValueGetNumberDouble(data, &prop->val.d); + break; + case QEMU_MONITOR_OBJECT_PROPERTY_STRING: + tmp = virJSONValueGetString(data); + if (tmp && VIR_STRDUP(prop->val.str, tmp) < 0)
Lose the 'tmp' here as VIR_STRDUP will check it for NULL anyway. In fact, these lines can be rewritten into a single line: ret = VIR_STRDUP(prop->val.str, tmp);
+ goto cleanup; + if (tmp) + ret = 0; + break; + case QEMU_MONITOR_OBJECT_PROPERTY_LAST: + default: + virReportError(VIR_ERR_INTERNAL_ERROR, + _("qom-get invalid object property type %d"), + prop->type); + goto cleanup; + } + + if (ret == -1) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("qom-get reply was missing return data")); + goto cleanup; + } + + ret = 0; +cleanup: + virJSONValueFree(cmd); + virJSONValueFree(reply); + + return ret; +} + +
Michal