[Qemu-devel] [PATCH v5 09/15] qmp: add query-block-jobs

2012-01-13 Thread Stefan Hajnoczi
Add query-block-jobs, which shows the progress of ongoing block device
operations.

Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
---
 blockdev.c   |   33 +
 hmp.c|   36 
 hmp.h|1 +
 monitor.c|7 +++
 qapi-schema.json |   32 
 qmp-commands.hx  |6 ++
 6 files changed, 115 insertions(+), 0 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index 35de3bc..4549c9e 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -989,3 +989,36 @@ void qmp_block_job_cancel(const char *device, Error **errp)
 trace_qmp_block_job_cancel(job);
 block_job_cancel(job);
 }
+
+static void do_qmp_query_block_jobs_one(void *opaque, BlockDriverState *bs)
+{
+BlockJobInfoList **prev = opaque;
+BlockJob *job = bs-job;
+
+if (job) {
+BlockJobInfoList *elem;
+BlockJobInfo *info = g_new(BlockJobInfo, 1);
+*info = (BlockJobInfo){
+.type   = g_strdup(job-job_type-job_type),
+.device = g_strdup(bdrv_get_device_name(bs)),
+.len= job-len,
+.offset = job-offset,
+.speed  = job-speed,
+};
+
+elem = g_new0(BlockJobInfoList, 1);
+elem-value = info;
+
+(*prev)-next = elem;
+*prev = elem;
+}
+}
+
+BlockJobInfoList *qmp_query_block_jobs(Error **errp)
+{
+/* Dummy is a fake list element for holding the head pointer */
+BlockJobInfoList dummy = {};
+BlockJobInfoList *prev = dummy;
+bdrv_iterate(do_qmp_query_block_jobs_one, prev);
+return dummy.next;
+}
diff --git a/hmp.c b/hmp.c
index 851885b..76e89f8 100644
--- a/hmp.c
+++ b/hmp.c
@@ -507,6 +507,42 @@ void hmp_info_pci(Monitor *mon)
 qapi_free_PciInfoList(info);
 }
 
+void hmp_info_block_jobs(Monitor *mon)
+{
+BlockJobInfoList *list;
+Error *err = NULL;
+
+list = qmp_query_block_jobs(err);
+assert(!err);
+
+if (!list) {
+monitor_printf(mon, No active jobs\n);
+return;
+}
+
+while (list) {
+if (strcmp(list-value-type, stream) == 0) {
+monitor_printf(mon, Streaming device %s: Completed % PRId64
+of % PRId64  bytes, speed limit % PRId64
+bytes/s\n,
+   list-value-device,
+   list-value-offset,
+   list-value-len,
+   list-value-speed);
+} else {
+monitor_printf(mon, Type %s, device %s: Completed % PRId64
+of % PRId64  bytes, speed limit % PRId64
+bytes/s\n,
+   list-value-type,
+   list-value-device,
+   list-value-offset,
+   list-value-len,
+   list-value-speed);
+}
+list = list-next;
+}
+}
+
 void hmp_quit(Monitor *mon, const QDict *qdict)
 {
 monitor_suspend(mon);
diff --git a/hmp.h b/hmp.h
index 0ad2004..23bfca2 100644
--- a/hmp.h
+++ b/hmp.h
@@ -32,6 +32,7 @@ void hmp_info_vnc(Monitor *mon);
 void hmp_info_spice(Monitor *mon);
 void hmp_info_balloon(Monitor *mon);
 void hmp_info_pci(Monitor *mon);
+void hmp_info_block_jobs(Monitor *mon);
 void hmp_quit(Monitor *mon, const QDict *qdict);
 void hmp_stop(Monitor *mon, const QDict *qdict);
 void hmp_system_reset(Monitor *mon, const QDict *qdict);
diff --git a/monitor.c b/monitor.c
index 01850ca..f96a296 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2483,6 +2483,13 @@ static mon_cmd_t info_cmds[] = {
 .mhandler.info = hmp_info_blockstats,
 },
 {
+.name   = block-jobs,
+.args_type  = ,
+.params = ,
+.help   = show progress of ongoing block device operations,
+.mhandler.info = hmp_info_block_jobs,
+},
+{
 .name   = registers,
 .args_type  = ,
 .params = ,
diff --git a/qapi-schema.json b/qapi-schema.json
index 3d23ce2..b4f6b15 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -845,6 +845,38 @@
 { 'command': 'query-pci', 'returns': ['PciInfo'] }
 
 ##
+# @BlockJobInfo:
+#
+# Information about a long-running block device operation.
+#
+# @type: the job type ('stream' for image streaming)
+#
+# @device: the block device name
+#
+# @len: the maximum progress value
+#
+# @offset: the current progress value
+#
+# @speed: the rate limit, bytes per second
+#
+# Since: 1.1
+##
+{ 'type': 'BlockJobInfo',
+  'data': {'type': 'str', 'device': 'str', 'len': 'int',
+   'offset': 'int', 'speed': 'int'} }
+
+##
+# @query-block-jobs:
+#
+# Return information about long-running block device operations.
+#
+# Returns: a list of @BlockJobInfo for each active block job
+#
+# Since: 1.1
+##
+{ 'command': 'query-block-jobs', 'returns': ['BlockJobInfo'] }
+
+##
 # @quit:
 #
 # This command will cause the 

[Qemu-devel] [PATCH v5 09/15] qmp: add query-block-jobs

2012-01-13 Thread Stefan Hajnoczi
Add query-block-jobs, which shows the progress of ongoing block device
operations.

Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com
---
 blockdev.c   |   33 +
 hmp.c|   36 
 hmp.h|1 +
 monitor.c|7 +++
 qapi-schema.json |   32 
 qmp-commands.hx  |6 ++
 6 files changed, 115 insertions(+), 0 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index 35de3bc..4549c9e 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -989,3 +989,36 @@ void qmp_block_job_cancel(const char *device, Error **errp)
 trace_qmp_block_job_cancel(job);
 block_job_cancel(job);
 }
+
+static void do_qmp_query_block_jobs_one(void *opaque, BlockDriverState *bs)
+{
+BlockJobInfoList **prev = opaque;
+BlockJob *job = bs-job;
+
+if (job) {
+BlockJobInfoList *elem;
+BlockJobInfo *info = g_new(BlockJobInfo, 1);
+*info = (BlockJobInfo){
+.type   = g_strdup(job-job_type-job_type),
+.device = g_strdup(bdrv_get_device_name(bs)),
+.len= job-len,
+.offset = job-offset,
+.speed  = job-speed,
+};
+
+elem = g_new0(BlockJobInfoList, 1);
+elem-value = info;
+
+(*prev)-next = elem;
+*prev = elem;
+}
+}
+
+BlockJobInfoList *qmp_query_block_jobs(Error **errp)
+{
+/* Dummy is a fake list element for holding the head pointer */
+BlockJobInfoList dummy = {};
+BlockJobInfoList *prev = dummy;
+bdrv_iterate(do_qmp_query_block_jobs_one, prev);
+return dummy.next;
+}
diff --git a/hmp.c b/hmp.c
index 851885b..76e89f8 100644
--- a/hmp.c
+++ b/hmp.c
@@ -507,6 +507,42 @@ void hmp_info_pci(Monitor *mon)
 qapi_free_PciInfoList(info);
 }
 
+void hmp_info_block_jobs(Monitor *mon)
+{
+BlockJobInfoList *list;
+Error *err = NULL;
+
+list = qmp_query_block_jobs(err);
+assert(!err);
+
+if (!list) {
+monitor_printf(mon, No active jobs\n);
+return;
+}
+
+while (list) {
+if (strcmp(list-value-type, stream) == 0) {
+monitor_printf(mon, Streaming device %s: Completed % PRId64
+of % PRId64  bytes, speed limit % PRId64
+bytes/s\n,
+   list-value-device,
+   list-value-offset,
+   list-value-len,
+   list-value-speed);
+} else {
+monitor_printf(mon, Type %s, device %s: Completed % PRId64
+of % PRId64  bytes, speed limit % PRId64
+bytes/s\n,
+   list-value-type,
+   list-value-device,
+   list-value-offset,
+   list-value-len,
+   list-value-speed);
+}
+list = list-next;
+}
+}
+
 void hmp_quit(Monitor *mon, const QDict *qdict)
 {
 monitor_suspend(mon);
diff --git a/hmp.h b/hmp.h
index 0ad2004..23bfca2 100644
--- a/hmp.h
+++ b/hmp.h
@@ -32,6 +32,7 @@ void hmp_info_vnc(Monitor *mon);
 void hmp_info_spice(Monitor *mon);
 void hmp_info_balloon(Monitor *mon);
 void hmp_info_pci(Monitor *mon);
+void hmp_info_block_jobs(Monitor *mon);
 void hmp_quit(Monitor *mon, const QDict *qdict);
 void hmp_stop(Monitor *mon, const QDict *qdict);
 void hmp_system_reset(Monitor *mon, const QDict *qdict);
diff --git a/monitor.c b/monitor.c
index 01850ca..f96a296 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2483,6 +2483,13 @@ static mon_cmd_t info_cmds[] = {
 .mhandler.info = hmp_info_blockstats,
 },
 {
+.name   = block-jobs,
+.args_type  = ,
+.params = ,
+.help   = show progress of ongoing block device operations,
+.mhandler.info = hmp_info_block_jobs,
+},
+{
 .name   = registers,
 .args_type  = ,
 .params = ,
diff --git a/qapi-schema.json b/qapi-schema.json
index 3d23ce2..b4f6b15 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -845,6 +845,38 @@
 { 'command': 'query-pci', 'returns': ['PciInfo'] }
 
 ##
+# @BlockJobInfo:
+#
+# Information about a long-running block device operation.
+#
+# @type: the job type ('stream' for image streaming)
+#
+# @device: the block device name
+#
+# @len: the maximum progress value
+#
+# @offset: the current progress value
+#
+# @speed: the rate limit, bytes per second
+#
+# Since: 1.1
+##
+{ 'type': 'BlockJobInfo',
+  'data': {'type': 'str', 'device': 'str', 'len': 'int',
+   'offset': 'int', 'speed': 'int'} }
+
+##
+# @query-block-jobs:
+#
+# Return information about long-running block device operations.
+#
+# Returns: a list of @BlockJobInfo for each active block job
+#
+# Since: 1.1
+##
+{ 'command': 'query-block-jobs', 'returns': ['BlockJobInfo'] }
+
+##
 # @quit:
 #
 # This command will cause the