If the machine is stopped and 'info balloon' is invoked, instead of querying the guest and waiting for a timeout, just display the most recent stats available in this case and log an error report.
See https://bugzilla.redhat.com/show_bug.cgi?id=623903 Reported-by: <lihu...@redhat.com> Signed-off-by: Amit Shah <amit.s...@redhat.com> --- balloon.c | 11 +++++++---- balloon.h | 6 ++++-- hw/virtio-balloon.c | 9 +++++++-- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/balloon.c b/balloon.c index 8e0b7f1..8b05d20 100644 --- a/balloon.c +++ b/balloon.c @@ -43,17 +43,20 @@ void qemu_add_balloon_handler(QEMUBalloonEvent *func, void *opaque) int qemu_balloon(ram_addr_t target, MonitorCompletion cb, void *opaque) { if (qemu_balloon_event) { - qemu_balloon_event(qemu_balloon_event_opaque, target, cb, opaque); + qemu_balloon_event(qemu_balloon_event_opaque, target, cb, opaque, + false); return 1; } else { return 0; } } -int qemu_balloon_status(MonitorCompletion cb, void *opaque) +int qemu_balloon_status(MonitorCompletion cb, void *opaque, + bool get_cached_data) { if (qemu_balloon_event) { - qemu_balloon_event(qemu_balloon_event_opaque, 0, cb, opaque); + qemu_balloon_event(qemu_balloon_event_opaque, 0, cb, opaque, + get_cached_data); return 1; } else { return 0; @@ -113,7 +116,7 @@ int do_info_balloon(Monitor *mon, MonitorCompletion cb, void *opaque) return -1; } - ret = qemu_balloon_status(cb, opaque); + ret = qemu_balloon_status(cb, opaque, !vm_running); if (!ret) { qerror_report(QERR_DEVICE_NOT_ACTIVE, "balloon"); return -1; diff --git a/balloon.h b/balloon.h index d478e28..729631c 100644 --- a/balloon.h +++ b/balloon.h @@ -17,13 +17,15 @@ #include "monitor.h" typedef void (QEMUBalloonEvent)(void *opaque, ram_addr_t target, - MonitorCompletion cb, void *cb_data); + MonitorCompletion cb, void *cb_data, + bool get_cached_data); void qemu_add_balloon_handler(QEMUBalloonEvent *func, void *opaque); int qemu_balloon(ram_addr_t target, MonitorCompletion cb, void *opaque); -int qemu_balloon_status(MonitorCompletion cb, void *opaque); +int qemu_balloon_status(MonitorCompletion cb, void *opaque, + bool get_cached_data); void monitor_print_balloon(Monitor *mon, const QObject *data); int do_info_balloon(Monitor *mon, MonitorCompletion cb, void *opaque); diff --git a/hw/virtio-balloon.c b/hw/virtio-balloon.c index 309c343..50a1a34 100644 --- a/hw/virtio-balloon.c +++ b/hw/virtio-balloon.c @@ -204,7 +204,8 @@ static uint32_t virtio_balloon_get_features(VirtIODevice *vdev, uint32_t f) } static void virtio_balloon_to_target(void *opaque, ram_addr_t target, - MonitorCompletion cb, void *cb_data) + MonitorCompletion cb, void *cb_data, + bool get_cached_data) { VirtIOBalloon *dev = opaque; @@ -222,8 +223,12 @@ static void virtio_balloon_to_target(void *opaque, ram_addr_t target, return; } dev->stats_callback = cb; - dev->stats_opaque_callback_data = cb_data; + dev->stats_opaque_callback_data = cb_data; if (dev->vdev.guest_features & (1 << VIRTIO_BALLOON_F_STATS_VQ)) { + if (get_cached_data) { + show_old_stats(dev); + return; + } qemu_mod_timer(dev->timer, qemu_get_clock(rt_clock) + 5000); virtqueue_push(dev->svq, &dev->stats_vq_elem, dev->stats_vq_offset); virtio_notify(&dev->vdev, dev->svq); -- 1.7.2.2