From 07c452ae11b0ada41265f6c0a442b67dd4ea4a09 Mon Sep 17 00:00:00 2001
From: Jeffrey Cody <jcody@redhat.com>
Date: Wed, 21 Mar 2012 21:55:11 +0100
Subject: [PATCH 44/55] qmp: add query-block-jobs

RH-Author: Jeffrey Cody <jcody@redhat.com>
Message-id: <d9efed8239de5bf01b96cb0b45694f8c3b96d9ec.1332362400.git.jcody@redhat.com>
Patchwork-id: 38894
O-Subject: [RHEL6.3 qemu-kvm PATCH v8 44/54] qmp: add query-block-jobs
Bugzilla: 582475
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
RH-Acked-by: Marcelo Tosatti <mtosatti@redhat.com>
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>

From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>

Add query-block-jobs, which shows the progress of ongoing block device
operations.

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Acked-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>

(cherry picked from commit fb5458cd10a199e55e622a906b24f8085d922c0f)

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Jeff Cody <jcody@redhat.com>
---
 blockdev.c      |   56 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 blockdev.h      |    2 +
 monitor.c       |    8 +++++++
 qemu-monitor.hx |   19 ++++++++++++++++++
 4 files changed, 85 insertions(+), 0 deletions(-)

Signed-off-by: Michal Novotny <minovotn@redhat.com>
---
 blockdev.c      |   56 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 blockdev.h      |    2 +
 monitor.c       |    8 +++++++
 qemu-monitor.hx |   19 ++++++++++++++++++
 4 files changed, 85 insertions(+), 0 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index ee19b39..3ef7aee 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1116,3 +1116,59 @@ int do_block_job_cancel(Monitor *mon, const QDict *params, QObject **ret_data)
     block_job_cancel(job);
     return 0;
 }
+
+static void monitor_print_block_jobs_one(QObject *info, void *opaque)
+{
+    QDict *stream = qobject_to_qdict(info);
+    Monitor *mon = opaque;
+
+    if (strcmp(qdict_get_str(stream, "type"), "stream") == 0) {
+        monitor_printf(mon, "Streaming device %s: Completed %" PRId64
+                " of %" PRId64 " bytes, speed limit %" PRId64
+                " bytes/s\n",
+                qdict_get_str(stream, "device"),
+                qdict_get_int(stream, "offset"),
+                qdict_get_int(stream, "len"),
+                qdict_get_int(stream, "speed"));
+    } else {
+        monitor_printf(mon, "Type %s, device %s: Completed %" PRId64
+                " of %" PRId64 " bytes, speed limit %" PRId64
+                " bytes/s\n",
+                qdict_get_str(stream, "type"),
+                qdict_get_str(stream, "device"),
+                qdict_get_int(stream, "offset"),
+                qdict_get_int(stream, "len"),
+                qdict_get_int(stream, "speed"));
+    }
+}
+
+void monitor_print_block_jobs(Monitor *mon, const QObject *data)
+{
+    QList *list = qobject_to_qlist(data);
+
+    assert(list);
+
+    if (qlist_empty(list)) {
+        monitor_printf(mon, "No active jobs\n");
+        return;
+    }
+
+    qlist_iter(list, monitor_print_block_jobs_one, mon);
+}
+
+static void do_info_block_jobs_one(void *opaque, BlockDriverState *bs)
+{
+    QList *list = opaque;
+    BlockJob *job = bs->job;
+
+    if (job) {
+        qlist_append_obj(list, qobject_from_block_job(job));
+    }
+}
+
+void do_info_block_jobs(Monitor *mon, QObject **ret_data)
+{
+    QList *list = qlist_new();
+    bdrv_iterate(do_info_block_jobs_one, list);
+    *ret_data = QOBJECT(list);
+}
diff --git a/blockdev.h b/blockdev.h
index 56adcd1..ae2eb5f 100644
--- a/blockdev.h
+++ b/blockdev.h
@@ -75,5 +75,7 @@ int do_block_stream(Monitor *mon, const QDict *qdict, QObject **ret_data);
 int do_block_job_set_speed(Monitor *mon, const QDict *params,
                            QObject **ret_data);
 int do_block_job_cancel(Monitor *mon, const QDict *params, QObject **ret_data);
+void monitor_print_block_jobs(Monitor *mon, const QObject *data);
+void do_info_block_jobs(Monitor *mon, QObject **ret_data);
 
 #endif
diff --git a/monitor.c b/monitor.c
index 0954ef0..e73dce7 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2993,6 +2993,14 @@ static const mon_cmd_t info_cmds[] = {
         .mhandler.info = do_info_roms,
     },
     {
+        .name       = "block-jobs",
+        .args_type  = "",
+        .params     = "",
+        .help       = "show progress of ongoing block device operations",
+        .user_print = monitor_print_block_jobs,
+        .mhandler.info_new = do_info_block_jobs,
+    },
+    {
         .name       = NULL,
     },
 };
diff --git a/qemu-monitor.hx b/qemu-monitor.hx
index 7c318ac..08e95fb 100644
--- a/qemu-monitor.hx
+++ b/qemu-monitor.hx
@@ -2991,6 +2991,25 @@ show device tree
 show qdev device model list
 @item info roms
 show roms
+@item info block-jobs
+show long-running block device operations
+ETEXI
+
+SQMP
+query-block-jobs
+----------------
+
+Return a list of block job objects for each active block job containing the
+following fields:
+
+- type: the job type (json-string, 'stream' for image streaming)
+- device: the block device name (json-string)
+- len: the maximum progress value (json-int)
+- offset: the current progress value (json-int)
+- speed: the rate limit, bytes per second (json-int)
+EQMP
+
+STEXI
 @end table
 ETEXI
 
-- 
1.7.7.6

