]> xenbits.xensource.com Git - libvirt.git/commitdiff
Fix QEMU memory stats JSON mode
authorDaniel P. Berrange <berrange@redhat.com>
Mon, 12 Apr 2010 11:31:15 +0000 (12:31 +0100)
committerDaniel P. Berrange <berrange@redhat.com>
Thu, 15 Apr 2010 16:55:58 +0000 (17:55 +0100)
The QEMU driver is mistakenly calling directly into the text
mode monitor for the domain memory stats query.

* src/qemu/qemu_driver.c: Replace qemuMonitorTextGetMemoryStats with
  qemuMonitorGetMemoryStats
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h: Add the new
  wrapper for qemuMonitorGetMemoryStats
* src/qemu/qemu_monitor_json.c, src/qemu/qemu_monitor_json.h: Add
  qemuMonitorJSONGetMemoryStats implementation

src/qemu/qemu_driver.c
src/qemu/qemu_monitor.c
src/qemu/qemu_monitor.h
src/qemu/qemu_monitor_json.c
src/qemu/qemu_monitor_json.h

index f6fdb280f594418fcf640f799ca0f5b38d2e5407..0189dcf010970ec055b020b7f31f9cdf58f651c9 100644 (file)
@@ -60,7 +60,6 @@
 #include "qemu_driver.h"
 #include "qemu_conf.h"
 #include "qemu_monitor.h"
-#include "qemu_monitor_text.h"
 #include "qemu_bridge_filter.h"
 #include "c-ctype.h"
 #include "event.h"
@@ -8699,7 +8698,7 @@ qemudDomainMemoryStats (virDomainPtr dom,
     if (virDomainObjIsActive(vm)) {
         qemuDomainObjPrivatePtr priv = vm->privateData;
         qemuDomainObjEnterMonitor(vm);
-        ret = qemuMonitorTextGetMemoryStats(priv->mon, stats, nr_stats);
+        ret = qemuMonitorGetMemoryStats(priv->mon, stats, nr_stats);
         qemuDomainObjExitMonitor(vm);
     } else {
         qemuReportError(VIR_ERR_OPERATION_INVALID,
index 01e3a464f35be897a7a16cbf4071f478a30a5702..20eaa1165b74e9ab1d962f6be83ea200bc3b07a0 100644 (file)
@@ -960,6 +960,21 @@ int qemuMonitorGetBalloonInfo(qemuMonitorPtr mon,
 }
 
 
+int qemuMonitorGetMemoryStats(qemuMonitorPtr mon,
+                              virDomainMemoryStatPtr stats,
+                              unsigned int nr_stats)
+{
+    int ret;
+    DEBUG("mon=%p, fd=%d stats=%p nstats=%u", mon, mon->fd, stats, nr_stats);
+
+    if (mon->json)
+        ret = qemuMonitorJSONGetMemoryStats(mon, stats, nr_stats);
+    else
+        ret = qemuMonitorTextGetMemoryStats(mon, stats, nr_stats);
+    return ret;
+}
+
+
 int qemuMonitorGetBlockStatsInfo(qemuMonitorPtr mon,
                                  const char *devname,
                                  long long *rd_req,
index 21b8989c0bb68d270c48b3e6db14409f6a02bd68..8410b022f7cd183ca16d292729335a9b91db7af6 100644 (file)
@@ -172,6 +172,9 @@ int qemuMonitorGetCPUInfo(qemuMonitorPtr mon,
                           int **pids);
 int qemuMonitorGetBalloonInfo(qemuMonitorPtr mon,
                               unsigned long *currmem);
+int qemuMonitorGetMemoryStats(qemuMonitorPtr mon,
+                              virDomainMemoryStatPtr stats,
+                              unsigned int nr_stats);
 int qemuMonitorGetBlockStatsInfo(qemuMonitorPtr mon,
                                  const char *devname,
                                  long long *rd_req,
index 29042017ba776fceee125fc8290322bb00217e6d..0f64ea748c36fd21e1334c7792c7b34196ab0fa0 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,
index e7baf8489f624d8a82b3f04f21d697da8b4ec87b..53d374e5ab8f08e4e93b950c9aac448cd176c010 100644 (file)
@@ -46,6 +46,9 @@ int qemuMonitorJSONGetCPUInfo(qemuMonitorPtr mon,
                               int **pids);
 int qemuMonitorJSONGetBalloonInfo(qemuMonitorPtr mon,
                                   unsigned long *currmem);
+int qemuMonitorJSONGetMemoryStats(qemuMonitorPtr mon,
+                                  virDomainMemoryStatPtr stats,
+                                  unsigned int nr_stats);
 int qemuMonitorJSONGetBlockStatsInfo(qemuMonitorPtr mon,
                                      const char *devname,
                                      long long *rd_req,