[libvirt] [PATCH 3/8] Add qemuMonitorSetObjectProperty() method for QMP qom-set command

John Ferlan jferlan at redhat.com
Tue Jul 2 13:39:21 UTC 2013


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




More information about the libvir-list mailing list