Fix QEMU memory stats JSON mode
[libvirt.git] / src / qemu / qemu_monitor_json.c
index 2904201..0f64ea7 100644 (file)
@@ -886,6 +886,121 @@ cleanup:
 }
 
 
+int qemuMonitorJSONGetMemoryStats(qemuMonitorPtr mon,
+                                  virDomainMemoryStatPtr stats,
+                                  unsigned int nr_stats)
+{
+    int ret;
+    int got = 0;
+    virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("query-balloon",
+                                                     NULL);
+    virJSONValuePtr reply = NULL;
+
+    if (!cmd)
+        return -1;
+
+    ret = qemuMonitorJSONCommand(mon, cmd, &reply);
+
+    if (ret == 0) {
+        /* See if balloon soft-failed */
+        if (qemuMonitorJSONHasError(reply, "DeviceNotActive") ||
+            qemuMonitorJSONHasError(reply, "KVMMissingCap"))
+            goto cleanup;
+
+        /* See if any other fatal error occurred */
+        ret = qemuMonitorJSONCheckError(cmd, reply);
+
+        /* Success */
+        if (ret == 0) {
+            virJSONValuePtr data;
+            unsigned long long mem;
+
+            if (!(data = virJSONValueObjectGet(reply, "return"))) {
+                qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                                _("info balloon reply was missing return data"));
+                ret = -1;
+                goto cleanup;
+            }
+
+            if (virJSONValueObjectHasKey(data, "mem_swapped_in") && (got < nr_stats)) {
+                if (virJSONValueObjectGetNumberUlong(data, "mem_swapped_in", &mem) < 0) {
+                    qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                                    _("info balloon reply was missing balloon mem_swapped_in"));
+                    ret = -1;
+                    goto cleanup;
+                }
+                stats[got].tag = VIR_DOMAIN_MEMORY_STAT_SWAP_IN;
+                stats[got].val = (mem/1024);
+                got++;
+            }
+            if (virJSONValueObjectHasKey(data, "mem_swapped_out") && (got < nr_stats)) {
+                if (virJSONValueObjectGetNumberUlong(data, "mem_swapped_out", &mem) < 0) {
+                    qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                                    _("info balloon reply was missing balloon mem_swapped_out"));
+                    ret = -1;
+                    goto cleanup;
+                }
+                stats[got].tag = VIR_DOMAIN_MEMORY_STAT_SWAP_OUT;
+                stats[got].val = (mem/1024);
+                got++;
+            }
+            if (virJSONValueObjectHasKey(data, "major_page_faults") && (got < nr_stats)) {
+                if (virJSONValueObjectGetNumberUlong(data, "major_page_faults", &mem) < 0) {
+                    qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                                    _("info balloon reply was missing balloon major_page_faults"));
+                    ret = -1;
+                    goto cleanup;
+                }
+                stats[got].tag = VIR_DOMAIN_MEMORY_STAT_MAJOR_FAULT;
+                stats[got].val = mem;
+                got++;
+            }
+            if (virJSONValueObjectHasKey(data, "minor_page_faults") && (got < nr_stats)) {
+                if (virJSONValueObjectGetNumberUlong(data, "minor_page_faults", &mem) < 0) {
+                    qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                                    _("info balloon reply was missing balloon minor_page_faults"));
+                    ret = -1;
+                    goto cleanup;
+                }
+                stats[got].tag = VIR_DOMAIN_MEMORY_STAT_MINOR_FAULT;
+                stats[got].val = mem;
+                got++;
+            }
+            if (virJSONValueObjectHasKey(data, "free_mem") && (got < nr_stats)) {
+                if (virJSONValueObjectGetNumberUlong(data, "free_mem", &mem) < 0) {
+                    qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                                    _("info balloon reply was missing balloon free_mem"));
+                    ret = -1;
+                    goto cleanup;
+                }
+                stats[got].tag = VIR_DOMAIN_MEMORY_STAT_UNUSED;
+                stats[got].val = (mem/1024);
+                got++;
+            }
+            if (virJSONValueObjectHasKey(data, "total_mem") && (got < nr_stats)) {
+                if (virJSONValueObjectGetNumberUlong(data, "total_mem", &mem) < 0) {
+                    qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                                    _("info balloon reply was missing balloon total_mem"));
+                    ret = -1;
+                    goto cleanup;
+                }
+                stats[got].tag = VIR_DOMAIN_MEMORY_STAT_AVAILABLE;
+                stats[got].val = (mem/1024);
+                got++;
+            }
+        }
+    }
+
+    if (got > 0)
+        ret = got;
+
+cleanup:
+    virJSONValueFree(cmd);
+    virJSONValueFree(reply);
+    return ret;
+}
+
+
 int qemuMonitorJSONGetBlockStatsInfo(qemuMonitorPtr mon,
                                      const char *devname,
                                      long long *rd_req,