Add a new qemuMonitorSetObjectProperty() method to support invocation of the 'qom-set' JSON monitor command with a provided path, property, and expected data type to set. The test code uses the same "/machine/i440fx" property as the get test and attempts to set the "realized" property to "true" (which it should be set at anyway). --- src/qemu/qemu_monitor.c | 23 ++++++++++++++++ src/qemu/qemu_monitor.h | 5 ++++ src/qemu/qemu_monitor_json.c | 62 ++++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_monitor_json.h | 6 +++++ tests/qemumonitorjsontest.c | 59 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 155 insertions(+) diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 6737a63..c46b1e5 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -3491,6 +3491,29 @@ int qemuMonitorGetObjectProperty(qemuMonitorPtr mon, } +int qemuMonitorSetObjectProperty(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 qemuMonitorJSONSetObjectProperty(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 cc22123..b822b97 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -727,6 +727,11 @@ int qemuMonitorGetObjectProperty(qemuMonitorPtr mon, const char *property, qemuMonitorObjectPropertyPtr prop); +int qemuMonitorSetObjectProperty(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 a725903..c599626 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -4712,6 +4712,68 @@ cleanup: } +#define MAKE_SET_CMD(STRING, VALUE) \ + cmd = qemuMonitorJSONMakeCommand("qom-set", \ + "s:path", path, \ + "s:property", property, \ + STRING, VALUE, \ + NULL) +int qemuMonitorJSONSetObjectProperty(qemuMonitorPtr mon, + const char *path, + const char *property, + qemuMonitorObjectPropertyPtr prop) +{ + int ret = -1; + virJSONValuePtr cmd = NULL; + virJSONValuePtr reply = NULL; + + 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: + MAKE_SET_CMD("b:value", prop->val.b); + break; + case QEMU_MONITOR_OBJECT_PROPERTY_INT: + MAKE_SET_CMD("i:value", prop->val.i); + break; + case QEMU_MONITOR_OBJECT_PROPERTY_LONG: + MAKE_SET_CMD("I:value", prop->val.l); + break; + case QEMU_MONITOR_OBJECT_PROPERTY_UINT: + MAKE_SET_CMD("u:value", prop->val.ui); + break; + case QEMU_MONITOR_OBJECT_PROPERTY_ULONG: + MAKE_SET_CMD("U:value", prop->val.ul); + break; + case QEMU_MONITOR_OBJECT_PROPERTY_DOUBLE: + MAKE_SET_CMD("d:value", prop->val.d); + break; + case QEMU_MONITOR_OBJECT_PROPERTY_STRING: + MAKE_SET_CMD("s:value", prop->val.str); + break; + case QEMU_MONITOR_OBJECT_PROPERTY_LAST: + default: + virReportError(VIR_ERR_INTERNAL_ERROR, + _("qom-set invalid object property type %d"), + prop->type); + goto cleanup; + + } + if (!cmd) + return -1; + + if ((ret = qemuMonitorJSONCommand(mon, cmd, &reply)) == 0) + ret = qemuMonitorJSONCheckError(cmd, reply); + +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 63807df..1da4c44 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -344,6 +344,12 @@ int qemuMonitorJSONGetObjectProperty(qemuMonitorPtr mon, qemuMonitorObjectPropertyPtr prop) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4); +int qemuMonitorJSONSetObjectProperty(qemuMonitorPtr mon, + const char *path, + const char *property, + qemuMonitorObjectPropertyPtr 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 4544676..c0987c6 100644 --- a/tests/qemumonitorjsontest.c +++ b/tests/qemumonitorjsontest.c @@ -718,6 +718,64 @@ cleanup: } +/* + * This test will use a path to /machine/i440fx which should exist in order + * to ensure that the qom-set property set works properly. The test will + * set a true property to true just as a proof of concept. Setting it to + * false is not a good idea... + */ +static int +testQemuMonitorJSONSetObjectProperty(const void *data) +{ + const virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data; + qemuMonitorTestPtr test = qemuMonitorTestNew(true, xmlopt); + int ret = -1; + qemuMonitorObjectProperty prop; + + if (!test) + return -1; + + if (qemuMonitorTestAddItem(test, "qom-set", + "{ \"return\": {} }") < 0) + goto cleanup; + if (qemuMonitorTestAddItem(test, "qom-get", + "{ \"return\": true }") < 0) + goto cleanup; + + /* Let's attempt the setting */ + memset(&prop, 0, sizeof(qemuMonitorObjectProperty)); + prop.type = QEMU_MONITOR_OBJECT_PROPERTY_BOOLEAN; + prop.val.b = true; + if (qemuMonitorSetObjectProperty(qemuMonitorTestGetMonitor(test), + "/machine/i440fx", + "realized", + &prop) < 0) + goto cleanup; + + /* To make sure it worked, fetch the property - if this succeeds then + * we didn't hose things + */ + memset(&prop, 0, sizeof(qemuMonitorObjectProperty)); + prop.type = QEMU_MONITOR_OBJECT_PROPERTY_BOOLEAN; + if (qemuMonitorGetObjectProperty(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) { @@ -748,6 +806,7 @@ mymain(void) DO_TEST(GetCommandLineOptionParameters); DO_TEST(GetListPaths); DO_TEST(GetObjectProperty); + DO_TEST(SetObjectProperty); virObjectUnref(xmlopt); -- 1.8.1.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list