diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index f6fdb280f5..0189dcf010 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -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, diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 01e3a464f3..20eaa1165b 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -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, diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 21b8989c0b..8410b022f7 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -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, diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 29042017ba..0f64ea748c 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -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, diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index e7baf8489f..53d374e5ab 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -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,