From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:39725) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RJRnq-0000GI-Lt for qemu-devel@nongnu.org; Thu, 27 Oct 2011 11:23:37 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RJRnm-0005In-FI for qemu-devel@nongnu.org; Thu, 27 Oct 2011 11:23:34 -0400 Received: from mtagate2.uk.ibm.com ([194.196.100.162]:54283) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RJRnm-0005IQ-4m for qemu-devel@nongnu.org; Thu, 27 Oct 2011 11:23:30 -0400 Received: from d06nrmr1507.portsmouth.uk.ibm.com (d06nrmr1507.portsmouth.uk.ibm.com [9.149.38.233]) by mtagate2.uk.ibm.com (8.13.1/8.13.1) with ESMTP id p9RFNTrk003282 for ; Thu, 27 Oct 2011 15:23:29 GMT Received: from d06av12.portsmouth.uk.ibm.com (d06av12.portsmouth.uk.ibm.com [9.149.37.247]) by d06nrmr1507.portsmouth.uk.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id p9RFNTU62424974 for ; Thu, 27 Oct 2011 16:23:29 +0100 Received: from d06av12.portsmouth.uk.ibm.com (loopback [127.0.0.1]) by d06av12.portsmouth.uk.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id p9RFNS4O000793 for ; Thu, 27 Oct 2011 09:23:28 -0600 From: Stefan Hajnoczi Date: Thu, 27 Oct 2011 16:22:54 +0100 Message-Id: <1319728975-6069-8-git-send-email-stefanha@linux.vnet.ibm.com> In-Reply-To: <1319728975-6069-1-git-send-email-stefanha@linux.vnet.ibm.com> References: <1319728975-6069-1-git-send-email-stefanha@linux.vnet.ibm.com> Subject: [Qemu-devel] [PATCH 7/8] qmp: add query-block-jobs List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Kevin Wolf , Anthony Liguori , Marcelo Tosatti , Stefan Hajnoczi Add query-block-jobs, which shows the progress of ongoing block device operations. Signed-off-by: Stefan Hajnoczi --- blockdev.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ blockdev.h | 2 ++ monitor.c | 16 ++++++++++++++++ qmp-commands.hx | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 96 insertions(+), 0 deletions(-) diff --git a/blockdev.c b/blockdev.c index 5ad7d3b..6d78597 100644 --- a/blockdev.c +++ b/blockdev.c @@ -919,3 +919,49 @@ int do_block_job_cancel(Monitor *mon, const QDict *params, block_job_cancel(job, do_block_job_cancel_cb, cancel_data); return 0; } + +static void monitor_print_block_jobs_one(QObject *info, void *opaque) +{ + QDict *stream = qobject_to_qdict(info); + Monitor *mon = opaque; + + /* TODO libvirt searches for "Streaming device" but this might be a + * non-stream job */ + 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")); +} + +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 7d3db30..9bfc33d 100644 --- a/blockdev.h +++ b/blockdev.h @@ -71,5 +71,7 @@ int do_block_job_set_speed(Monitor *mon, const QDict *qdict, QObject **ret_data); int do_block_job_cancel(Monitor *mon, const QDict *params, MonitorCompletion *cb, void *opaque); +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 38addcf..ad878af 100644 --- a/monitor.c +++ b/monitor.c @@ -2786,6 +2786,14 @@ static const mon_cmd_t info_cmds[] = { .mhandler.info_new = bdrv_info_stats, }, { + .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 = "registers", .args_type = "", .params = "", @@ -3080,6 +3088,14 @@ static const mon_cmd_t qmp_query_cmds[] = { .mhandler.info_new = bdrv_info_stats, }, { + .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 = "cpus", .args_type = "", .params = "", diff --git a/qmp-commands.hx b/qmp-commands.hx index 741c2f8..6e8207b 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -2089,3 +2089,35 @@ Example: EQMP +SQMP + +query-block-jobs +---------------- + +Show progress of ongoing block device operations. + +Return a json-array of all block device operations. If no operation is active +then return an empty array. Each operation is a json-object with the following +data: + +- type: job type ("stream" for image streaming, json-string) +- device: device name (json-string) +- len: maximum progress value (json-int) +- offset: current progress value (json-int) +- speed: rate limit, bytes per second (json-int) + +Progress can be observed as offset increases and it reaches len when the +operation completes. Offset and len have undefined units but can be used to +calculate a percentage indicating the progress that has been made. + +Example: + +-> { "execute": "query-block-jobs" } +<- { "return":[ + { "type": "stream", "device": "virtio0", + "len": 10737418240, "offset": 709632, + "speed": 0 } + ] + } + +EQMP -- 1.7.7