From 298a7536dae5069c9e7ffae5c76c25ff5c6f5533 Mon Sep 17 00:00:00 2001 From: Anthony Liguori Date: Fri, 12 Aug 2011 15:38:20 +0200 Subject: [PATCH 12/15] qmp: add query-block-jobs command RH-Author: Anthony Liguori Message-id: <1313163503-2523-13-git-send-email-aliguori@redhat.com> Patchwork-id: 31337 O-Subject: [RHEL6.2 qemu PATCH 12/15] qmp: add query-block-jobs command Bugzilla: 633370 RH-Acked-by: Marcelo Tosatti RH-Acked-by: Kevin Wolf RH-Acked-by: Orit Wasserman RH-Acked-by: Christoph Hellwig From: Stefan Hajnoczi Active image streaming operations can be enumerated with the query-block-jobs command. Each operation is listed along with its total progress. The command synopsis is: 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) - end: maximum progress value (json-int) - position: current progress value (json-int) - speed: rate limit, bytes per second (json-int) Progress can be observed as position increases and it reaches end when the operation completes. Position and end 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", "end": 10737418240, "position": 709632, "speed": 0 } ] } Signed-off-by: Stefan Hajnoczi Signed-off-by: Anthony Liguori Bugzilla: 633370 --- blockdev.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ blockdev.h | 2 ++ monitor.c | 8 ++++++++ qemu-monitor.hx | 34 ++++++++++++++++++++++++++++++++++ 4 files changed, 92 insertions(+), 0 deletions(-) Signed-off-by: Michal Novotny --- blockdev.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ blockdev.h | 2 ++ monitor.c | 8 ++++++++ qemu-monitor.hx | 34 ++++++++++++++++++++++++++++++++++ 4 files changed, 92 insertions(+), 0 deletions(-) diff --git a/blockdev.c b/blockdev.c index 133e3eb..cb1ee85 100644 --- a/blockdev.c +++ b/blockdev.c @@ -860,6 +860,54 @@ out: return ret; } +static void monitor_print_block_stream(Monitor *mon, const QObject *data) +{ + QDict *stream; + + assert(data); + stream = qobject_to_qdict(data); + + 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"), + (int64_t)0); +} + +static void monitor_print_block_job(QObject *obj, void *opaque) +{ + monitor_print_block_stream((Monitor *)opaque, obj); +} + +void monitor_print_block_jobs(Monitor *mon, const QObject *data) +{ + QList *streams; + + assert(data); + streams = qobject_to_qlist(data); + assert(streams); /* we pass a list of stream objects to ourselves */ + + if (qlist_empty(streams)) { + monitor_printf(mon, "No active jobs\n"); + return; + } + + qlist_iter(streams, monitor_print_block_job, mon); +} + +void do_info_block_jobs(Monitor *mon, QObject **ret_data) +{ + QList *streams; + StreamState *s; + + streams = qlist_new(); + QLIST_FOREACH(s, &block_streams, list) { + qlist_append_obj(streams, stream_get_qobject(s)); + } + *ret_data = QOBJECT(streams); +} + int do_block_stream(Monitor *mon, const QDict *params, QObject **ret_data) { const char *device = qdict_get_str(params, "device"); diff --git a/blockdev.h b/blockdev.h index cd399ee..71f9c46 100644 --- a/blockdev.h +++ b/blockdev.h @@ -73,6 +73,8 @@ int do_change_block(Monitor *mon, const char *device, const char *filename, const char *fmt); int simple_drive_add(Monitor *mon, const QDict *qdict, QObject **ret_data); int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data); +void monitor_print_block_jobs(Monitor *mon, const QObject *data); +void do_info_block_jobs(Monitor *mon, QObject **ret_data); int do_block_stream(Monitor *mon, const QDict *params, QObject **ret_data); int do_block_job_cancel(Monitor *mon, const QDict *params, MonitorCompletion cb, void *opaque); diff --git a/monitor.c b/monitor.c index 2081bf3..a3bb9c6 100644 --- a/monitor.c +++ b/monitor.c @@ -2921,6 +2921,14 @@ static const mon_cmd_t info_cmds[] = { .mhandler.info = do_info_roms, }, { + .name = "block-jobs", + .args_type = "", + .params = "", + .help = "show block job status", + .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 e846e61..f78fda0 100644 --- a/qemu-monitor.hx +++ b/qemu-monitor.hx @@ -2884,9 +2884,43 @@ show device tree show qdev device model list @item info roms show roms +@item info block-jobs +show progress of background block device operations @end table ETEXI +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) +- end: maximum progress value (json-int) +- position: current progress value (json-int) +- speed: rate limit, bytes per second (json-int) + +Progress can be observed as position increases and it reaches end when +the operation completes. Position and end 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", + "end": 10737418240, "position": 709632, + "speed": 0 } + ] + } + +EQMP + HXCOMM DO NOT add new commands after 'info', move your addition before it! STEXI -- 1.7.4.4