Add a new qemuMonitorJSONGetObjectProperty() method to support invocation of the 'qom-get' JSON monitor command with a provided path, property, and expected data type return. The qemuMonitorJSONObjectProperty 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_json.c | 86 ++++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_monitor_json.h | 34 ++++++++++++++++++ tests/qemumonitorjsontest.c | 48 +++++++++++++++++++++++++ 3 files changed, 168 insertions(+) diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 216a58c..62f2bf0 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -4605,6 +4605,92 @@ void qemuMonitorJSONListPathFree(qemuMonitorJSONListPathPtr paths) VIR_FREE(paths); } + +int qemuMonitorJSONGetObjectProperty(qemuMonitorPtr mon, + const char *path, + const char *property, + qemuMonitorJSONObjectPropertyPtr 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 ((qemuMonitorJSONObjectPropertyType) 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.iv); + 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) + goto cleanup; + if (tmp) + ret = 0; + break; + case QEMU_MONITOR_OBJECT_PROPERTY_LAST: + virReportError(VIR_ERR_INTERNAL_ERROR, + _("qom-get invalid object property type %d"), + prop->type); + goto cleanup; + break; + } + + 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; +} + + int qemuMonitorJSONGetObjectProps(qemuMonitorPtr mon, const char *type, char ***props) diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index e7ce145..322e3fd 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -348,6 +348,40 @@ int qemuMonitorJSONGetObjectListPaths(qemuMonitorPtr mon, void qemuMonitorJSONListPathFree(qemuMonitorJSONListPathPtr paths); +/* Flags for the 'type' field in _qemuMonitorJSONObjectProperty */ +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 +} qemuMonitorJSONObjectPropertyType; + +typedef struct _qemuMonitorJSONObjectProperty qemuMonitorJSONObjectProperty; +typedef qemuMonitorJSONObjectProperty *qemuMonitorJSONObjectPropertyPtr; +struct _qemuMonitorJSONObjectProperty { + int type; /* qemuMonitorJSONObjectPropertyType */ + union { + bool b; + int iv; + long long l; + unsigned int ui; + unsigned long long ul; + double d; + char *str; + } val; +}; + +int qemuMonitorJSONGetObjectProperty(qemuMonitorPtr mon, + const char *path, + const char *property, + qemuMonitorJSONObjectPropertyPtr prop) + ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4); + int qemuMonitorJSONGetObjectProps(qemuMonitorPtr mon, const char *type, char ***props) diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c index 7841658..660f251 100644 --- a/tests/qemumonitorjsontest.c +++ b/tests/qemumonitorjsontest.c @@ -673,6 +673,53 @@ cleanup: } +/* + * This test will use a path to /machine/i440fx which should exist in order + * to ensure that the qom-get property fetch works properly. The following + * is the execution and expected return: + * + * + * { "execute": "qom-get","arguments": \ + * { "path": "/machine/i440fx","property": "realized"}} + * {"return": true} + */ +static int +testQemuMonitorJSONGetObjectProperty(const void *data) +{ + const virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data; + qemuMonitorTestPtr test = qemuMonitorTestNew(true, xmlopt); + int ret = -1; + qemuMonitorJSONObjectProperty prop; + + if (!test) + return -1; + + if (qemuMonitorTestAddItem(test, "qom-get", + "{ \"return\": true }") < 0) + goto cleanup; + + /* Present with path and property */ + memset(&prop, 0, sizeof(qemuMonitorJSONObjectProperty)); + prop.type = QEMU_MONITOR_OBJECT_PROPERTY_BOOLEAN; + if (qemuMonitorJSONGetObjectProperty(qemuMonitorTestGetMonitor(test), + "/machine/i440fx", + "realized", + &prop) < 0) + goto cleanup; + + if (!prop.val.b) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + "expected true, but false returned"); + goto cleanup; + } + + ret = 0; +cleanup: + qemuMonitorTestFree(test); + return ret; +} + + static int mymain(void) { @@ -702,6 +749,7 @@ mymain(void) DO_TEST(GetTPMModels); DO_TEST(GetCommandLineOptionParameters); DO_TEST(GetListPaths); + DO_TEST(GetObjectProperty); virObjectUnref(xmlopt); -- 1.8.1.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list