* src/qemu/qemu_monitor_text.c: BALLOON_PREFIX was defined as "balloon: actual=", which cause "actual=" is stripped early before the real parsing. This patch changes BALLOON_PREFIX into "balloon: ", and modifies related functions, also renames "qemuMonitorParseExtraBalloonInfo" to "qemuMonitorParseBalloonInfo", as after the changing, it parses all the info returned by "info balloon". v2: Adopted Adam's suggestion, parse "actual=" outside of the loop of qemuMonitorParseBalloonInfo, and use qemuMonitorParseBalloonInfo for qemuMonitorTextGetBalloonInfo. --- src/qemu/qemu_monitor_text.c | 53 +++++++++++++++++++++++++++-------------- 1 files changed, 35 insertions(+), 18 deletions(-) diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c index 335e39e..a661626 100644 --- a/src/qemu/qemu_monitor_text.c +++ b/src/qemu/qemu_monitor_text.c @@ -547,8 +547,12 @@ static int parseMemoryStat(char **text, unsigned int tag, return 0; } - /* Convert bytes to kilobytes for libvirt */ switch (tag) { + /* Convert megabytes to kilobytes for libvirt */ + case VIR_DOMAIN_MEMORY_STAT_ACTUAL_BALLOON: + value = value << 10; + break; + /* Convert bytes to kilobytes for libvirt */ case VIR_DOMAIN_MEMORY_STAT_SWAP_IN: case VIR_DOMAIN_MEMORY_STAT_SWAP_OUT: case VIR_DOMAIN_MEMORY_STAT_UNUSED: @@ -563,15 +567,25 @@ static int parseMemoryStat(char **text, unsigned int tag, } /* The reply from the 'info balloon' command may contain additional memory - * statistics in the form: '[,<tag>=<val>]*' + * statistics in the form: 'actual=<val> [,<tag>=<val>]*' */ -static int qemuMonitorParseExtraBalloonInfo(char *text, - virDomainMemoryStatPtr stats, - unsigned int nr_stats) +static int qemuMonitorParseBalloonInfo(char *text, + virDomainMemoryStatPtr stats, + unsigned int nr_stats) { char *p = text; unsigned int nr_stats_found = 0; + /* Since "actual=" always comes first in the returned string, + * and sometime we only care about the value of "actual", such + * as qemuMonitorGetBalloonInfo, so parse it outside of the + * loop. + */ + if (parseMemoryStat(&p, VIR_DOMAIN_MEMORY_STAT_ACTUAL_BALLOON, + "actual=", &stats[nr_stats_found]) == 1) { + nr_stats_found++; + } + while (*p && nr_stats_found < nr_stats) { if (parseMemoryStat(&p, VIR_DOMAIN_MEMORY_STAT_SWAP_IN, ",mem_swapped_in=", &stats[nr_stats_found]) || @@ -584,9 +598,7 @@ static int qemuMonitorParseExtraBalloonInfo(char *text, parseMemoryStat(&p, VIR_DOMAIN_MEMORY_STAT_UNUSED, ",free_mem=", &stats[nr_stats_found]) || parseMemoryStat(&p, VIR_DOMAIN_MEMORY_STAT_AVAILABLE, - ",total_mem=", &stats[nr_stats_found]) || - parseMemoryStat(&p, VIR_DOMAIN_MEMORY_STAT_ACTUAL_BALLOON, - ",actual=", &stats[nr_stats_found])) + ",total_mem=", &stats[nr_stats_found])) nr_stats_found++; /* Skip to the next label. When *p is ',' the last match attempt @@ -602,7 +614,7 @@ static int qemuMonitorParseExtraBalloonInfo(char *text, /* The reply from QEMU contains 'ballon: actual=421' where value is in MB */ -#define BALLOON_PREFIX "balloon: actual=" +#define BALLOON_PREFIX "balloon: " /* * Returns: 0 if balloon not supported, +1 if balloon query worked @@ -622,15 +634,22 @@ int qemuMonitorTextGetBalloonInfo(qemuMonitorPtr mon, } if ((offset = strstr(reply, BALLOON_PREFIX)) != NULL) { - unsigned int memMB; - char *end; offset += strlen(BALLOON_PREFIX); - if (virStrToLong_ui(offset, &end, 10, &memMB) < 0) { - qemuReportError(VIR_ERR_OPERATION_FAILED, - _("could not parse memory balloon allocation from '%s'"), reply); + struct _virDomainMemoryStat stats[1]; + + if (qemuMonitorParseBalloonInfo(offset, stats, 1) == 0) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + _("unexpected balloon information '%s'"), reply); goto cleanup; } - *currmem = memMB * 1024; + + if (stats[0].tag != VIR_DOMAIN_MEMORY_STAT_ACTUAL_BALLOON) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + _("unexpected balloon information '%s'"), reply); + goto cleanup; + } + + *currmem = stats[0].val; ret = 1; } else { /* We don't raise an error here, since its to be expected that @@ -660,9 +679,7 @@ int qemuMonitorTextGetMemoryStats(qemuMonitorPtr mon, if ((offset = strstr(reply, BALLOON_PREFIX)) != NULL) { offset += strlen(BALLOON_PREFIX); - if ((offset = strchr(offset, ',')) != NULL) { - ret = qemuMonitorParseExtraBalloonInfo(offset, stats, nr_stats); - } + ret = qemuMonitorParseBalloonInfo(offset, stats, nr_stats); } VIR_FREE(reply); -- 1.7.6 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list