From: John Ferlan Date: Wed, 3 Jul 2013 18:42:40 +0000 (-0400) Subject: Add qemuMonitorJSONSetObjectProperty() method for QMP qom-set command X-Git-Tag: CVE-2013-4154~16 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=50336d871ad23308d215c815e0a4bc28eeb07cc5;p=thirdparty%2Flibvirt.git Add qemuMonitorJSONSetObjectProperty() method for QMP qom-set command Add a new qemuMonitorJSONSetObjectProperty() method to support invocation of the 'qom-set' JSON monitor command with a provided path, property, and expected data type to set. NOTE: The set API was added only for the purpose of the qemumonitorjsontest 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). --- diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 96213807e4..81af4f3795 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -4691,6 +4691,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, + qemuMonitorJSONObjectPropertyPtr prop) +{ + int ret = -1; + virJSONValuePtr cmd = NULL; + virJSONValuePtr reply = NULL; + + 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: + MAKE_SET_CMD("b:value", prop->val.b); + break; + case QEMU_MONITOR_OBJECT_PROPERTY_INT: + MAKE_SET_CMD("i:value", prop->val.iv); + 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: + 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; +} +#undef MAKE_SET_CMD + + 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 2ff08f2262..658c451660 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -349,7 +349,9 @@ int qemuMonitorJSONGetObjectListPaths(qemuMonitorPtr mon, void qemuMonitorJSONListPathFree(qemuMonitorJSONListPathPtr paths); -/* ObjectProperty structures and API are public only for qemumonitorjsontest */ +/* ObjectProperty structures and Get/Set API's are public only + * for qemumonitorjsontest + */ /* Flags for the 'type' field in _qemuMonitorJSONObjectProperty */ typedef enum { QEMU_MONITOR_OBJECT_PROPERTY_BOOLEAN=1, @@ -384,6 +386,12 @@ int qemuMonitorJSONGetObjectProperty(qemuMonitorPtr mon, qemuMonitorJSONObjectPropertyPtr prop) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4); +int qemuMonitorJSONSetObjectProperty(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 580cf5b20a..3d2ed4b800 100644 --- a/tests/qemumonitorjsontest.c +++ b/tests/qemumonitorjsontest.c @@ -824,6 +824,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; + qemuMonitorJSONObjectProperty 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(qemuMonitorJSONObjectProperty)); + prop.type = QEMU_MONITOR_OBJECT_PROPERTY_BOOLEAN; + prop.val.b = true; + if (qemuMonitorJSONSetObjectProperty(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(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) { @@ -856,6 +914,7 @@ mymain(void) DO_TEST(DetachChardev); DO_TEST(GetListPaths); DO_TEST(GetObjectProperty); + DO_TEST(SetObjectProperty); virObjectUnref(xmlopt);