[libvirt] [PATCH 3/4] Misc fixes to QMP monitor support for QEMU

Daniel P. Berrange berrange at redhat.com
Fri Jan 22 17:01:13 UTC 2010


* src/util/json.c, src/util/json.h: Declare returned strings
  to be const
* src/qemu/qemu_monitor.c: Wire up JSON mode for qemuMonitorGetPtyPaths
* src/qemu/qemu_monitor_json.c, src/qemu/qemu_monitor_json.h: Fix
  const correctness. Add missing error message in the function
  qemuMonitorJSONGetAllPCIAddresses. Add implementation of the
  qemuMonitorGetPtyPaths function calling 'query-chardev'.
---
 src/qemu/qemu_monitor.c      |    7 ++-
 src/qemu/qemu_monitor_json.c |  121 +++++++++++++++++++++++++++++++++++++++--
 src/qemu/qemu_monitor_json.h |    3 +
 src/util/json.c              |    4 +-
 src/util/json.h              |    4 +-
 5 files changed, 128 insertions(+), 11 deletions(-)

diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 031df30..817ccd7 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -1245,10 +1245,15 @@ int qemuMonitorRemoveHostNetwork(qemuMonitorPtr mon,
 int qemuMonitorGetPtyPaths(qemuMonitorPtr mon,
                            virHashTablePtr paths)
 {
+    int ret;
     DEBUG("mon=%p, fd=%d",
           mon, mon->fd);
 
-    return qemuMonitorTextGetPtyPaths(mon, paths);
+    if (mon->json)
+        ret = qemuMonitorJSONGetPtyPaths(mon, paths);
+    else
+        ret = qemuMonitorTextGetPtyPaths(mon, paths);
+    return ret;
 }
 
 
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 57e2ad9..7dd2bdb 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -65,7 +65,7 @@ static int
 qemuMonitorJSONIOProcessEvent(qemuMonitorPtr mon,
                               virJSONValuePtr obj)
 {
-    char *type;
+    const char *type;
     int i;
     VIR_DEBUG("mon=%p obj=%p", mon, obj);
 
@@ -248,7 +248,7 @@ qemuMonitorJSONCommand(qemuMonitorPtr mon,
  */
 static char *qemuMonitorJSONStringifyError(virJSONValuePtr error)
 {
-    char *klass = virJSONValueObjectGetString(error, "class");
+    const char *klass = virJSONValueObjectGetString(error, "class");
 
     if (klass) {
         return strdup(klass);
@@ -304,7 +304,7 @@ qemuMonitorJSONHasError(virJSONValuePtr reply,
                         const char *klass)
 {
     virJSONValuePtr error;
-    char *thisklass;
+    const char *thisklass;
 
     if (!virJSONValueObjectHasKey(reply, "error"))
         return 0;
@@ -592,11 +592,19 @@ int qemuMonitorJSONGetBalloonInfo(qemuMonitorPtr mon,
 
         /* Success */
         if (ret == 0) {
+            virJSONValuePtr data;
             unsigned long long mem;
 
-            if (virJSONValueObjectGetNumberUlong(reply, "return", &mem) < 0) {
+            if (!(data = virJSONValueObjectGet(reply, "return"))) {
                 qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "%s",
-                                 _("info balloon reply was missing mem return data"));
+                                 _("info balloon reply was missing return data"));
+                ret = -1;
+                goto cleanup;
+            }
+
+            if (virJSONValueObjectGetNumberUlong(data, "balloon", &mem) < 0) {
+                qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "%s",
+                                 _("info balloon reply was missing balloon data"));
                 ret = -1;
                 goto cleanup;
             }
@@ -916,7 +924,7 @@ qemuMonitorJSONGetMigrationStatusReply(virJSONValuePtr reply,
                                        unsigned long long *total)
 {
     virJSONValuePtr ret;
-    char *statusstr;
+    const char *statusstr;
 
     if (!(ret = virJSONValueObjectGet(reply, "return"))) {
         qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "%s",
@@ -1483,6 +1491,105 @@ int qemuMonitorJSONRemoveHostNetwork(qemuMonitorPtr mon,
 }
 
 
+/*
+ * Example return data
+ *
+ * {"return": [
+ *      {"filename": "stdio", "label": "monitor"},
+ *      {"filename": "pty:/dev/pts/6", "label": "serial0"},
+ *      {"filename": "pty:/dev/pts/7", "label": "parallel0"}
+ * ]}
+ *
+ */
+static int qemuMonitorJSONExtractPtyPaths(virJSONValuePtr reply,
+                                          virHashTablePtr paths)
+{
+    virJSONValuePtr data;
+    int ret = -1;
+    int i;
+
+    if (!(data = virJSONValueObjectGet(reply, "return"))) {
+        qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "%s",
+                         _("character device reply was missing return data"));
+        goto cleanup;
+    }
+
+    if (data->type != VIR_JSON_TYPE_ARRAY) {
+        qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "%s",
+                         _("character device information was not an array"));
+        goto cleanup;
+    }
+
+    for (i = 0 ; i < virJSONValueArraySize(data) ; i++) {
+        virJSONValuePtr entry = virJSONValueArrayGet(data, i);
+        const char *type;
+        const char *id;
+        if (!entry) {
+            qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "%s",
+                             _("character device information was missing aray element"));
+            goto cleanup;
+        }
+
+        if (!(type = virJSONValueObjectGetString(entry, "filename"))) {
+            qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "%s",
+                             _("character device information was missing filename"));
+            goto cleanup;
+        }
+
+        if (!(id = virJSONValueObjectGetString(entry, "label"))) {
+            qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "%s",
+                             _("character device information was missing filename"));
+            goto cleanup;
+        }
+
+        if (STRPREFIX(type, "pty:")) {
+            char *path = strdup(type + strlen("pty:"));
+            if (!path) {
+                virReportOOMError(NULL);
+                goto cleanup;
+            }
+
+            if (virHashAddEntry(paths, id, path) < 0) {
+                qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED,
+                                 _("failed to save chardev path '%s'"), path);
+                VIR_FREE(path);
+                goto cleanup;
+            }
+        }
+    }
+
+    ret = 0;
+
+cleanup:
+    return ret;
+}
+
+int qemuMonitorJSONGetPtyPaths(qemuMonitorPtr mon,
+                               virHashTablePtr paths)
+
+{
+    int ret;
+    virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("query-chardev",
+                                                     NULL);
+    virJSONValuePtr reply = NULL;
+
+    if (!cmd)
+        return -1;
+
+    ret = qemuMonitorJSONCommand(mon, cmd, &reply);
+
+    if (ret == 0)
+        ret = qemuMonitorJSONCheckError(cmd, reply);
+
+    if (ret == 0)
+        ret = qemuMonitorJSONExtractPtyPaths(reply, paths);
+
+    virJSONValueFree(cmd);
+    virJSONValueFree(reply);
+    return ret;
+}
+
+
 int qemuMonitorJSONAttachPCIDiskController(qemuMonitorPtr mon,
                                            const char *bus,
                                            virDomainDevicePCIAddress *guestAddr)
@@ -1594,5 +1701,7 @@ int qemuMonitorJSONAttachDrive(qemuMonitorPtr mon,
 int qemuMonitorJSONGetAllPCIAddresses(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
                                       qemuMonitorPCIAddress **addrs ATTRIBUTE_UNUSED)
 {
+    qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR, "%s",
+                     _("query-pci not suppported in JSON mode"));
     return -1;
 }
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index 7db9785..858aac0 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -141,6 +141,9 @@ int qemuMonitorJSONRemoveHostNetwork(qemuMonitorPtr mon,
                                      int vlan,
                                      const char *netname);
 
+int qemuMonitorJSONGetPtyPaths(qemuMonitorPtr mon,
+                               virHashTablePtr paths);
+
 int qemuMonitorJSONAttachPCIDiskController(qemuMonitorPtr mon,
                                            const char *bus,
                                            virDomainDevicePCIAddress *guestAddr);
diff --git a/src/util/json.c b/src/util/json.c
index 4b3e629..a292e1b 100644
--- a/src/util/json.c
+++ b/src/util/json.c
@@ -440,7 +440,7 @@ virJSONValuePtr virJSONValueArrayGet(virJSONValuePtr array, unsigned int element
     return array->data.array.values[element];
 }
 
-char *virJSONValueGetString(virJSONValuePtr string)
+const char *virJSONValueGetString(virJSONValuePtr string)
 {
     if (string->type != VIR_JSON_TYPE_STRING)
         return NULL;
@@ -508,7 +508,7 @@ int virJSONValueIsNull(virJSONValuePtr val)
 }
 
 
-char *virJSONValueObjectGetString(virJSONValuePtr object, const char *key)
+const char *virJSONValueObjectGetString(virJSONValuePtr object, const char *key)
 {
     virJSONValuePtr val;
     if (object->type != VIR_JSON_TYPE_OBJECT)
diff --git a/src/util/json.h b/src/util/json.h
index 7468628..1af9d9d 100644
--- a/src/util/json.h
+++ b/src/util/json.h
@@ -99,7 +99,7 @@ virJSONValuePtr virJSONValueObjectGet(virJSONValuePtr object, const char *key);
 int virJSONValueArraySize(virJSONValuePtr object);
 virJSONValuePtr virJSONValueArrayGet(virJSONValuePtr object, unsigned int element);
 
-char *virJSONValueGetString(virJSONValuePtr object);
+const char *virJSONValueGetString(virJSONValuePtr object);
 int virJSONValueGetNumberInt(virJSONValuePtr object, int *value);
 int virJSONValueGetNumberUint(virJSONValuePtr object, unsigned int *value);
 int virJSONValueGetNumberLong(virJSONValuePtr object, long long *value);
@@ -108,7 +108,7 @@ int virJSONValueGetNumberDouble(virJSONValuePtr object, double *value);
 int virJSONValueGetBoolean(virJSONValuePtr object);
 int virJSONValueIsNull(virJSONValuePtr object);
 
-char *virJSONValueObjectGetString(virJSONValuePtr object, const char *key);
+const char *virJSONValueObjectGetString(virJSONValuePtr object, const char *key);
 int virJSONValueObjectGetNumberInt(virJSONValuePtr object, const char *key, int *value);
 int virJSONValueObjectGetNumberUint(virJSONValuePtr object, const char *key, unsigned int *value);
 int virJSONValueObjectGetNumberLong(virJSONValuePtr object, const char *key, long long *value);
-- 
1.6.6




More information about the libvir-list mailing list