From 9374b98eb452b82fcd60a20f30a111be02fa8930 Mon Sep 17 00:00:00 2001 From: Jeffrey Cody Date: Wed, 21 Mar 2012 21:55:10 +0100 Subject: [PATCH 43/55] qmp: add block_job_cancel command RH-Author: Jeffrey Cody Message-id: <2f125facc24af1180b063232a4c573a332f7a27c.1332362400.git.jcody@redhat.com> Patchwork-id: 38893 O-Subject: [RHEL6.3 qemu-kvm PATCH v8 43/54] qmp: add block_job_cancel command Bugzilla: 582475 RH-Acked-by: Paolo Bonzini RH-Acked-by: Marcelo Tosatti RH-Acked-by: Kevin Wolf From: Stefan Hajnoczi Add block_job_cancel, which stops an active block streaming operation. When the operation has been cancelled the new BLOCK_JOB_CANCELLED event is emitted. Signed-off-by: Stefan Hajnoczi Acked-by: Luiz Capitulino Signed-off-by: Kevin Wolf (cherry picked from commit 370521a1d6f5537ea7271c119f3fbb7b0fa57063) Signed-off-by: Stefan Hajnoczi Signed-off-by: Anthony Liguori Signed-off-by: Jeff Cody --- QMP/qmp-events.txt | 23 +++++++++++++++++++++++ blockdev.c | 21 ++++++++++++++++++++- blockdev.h | 1 + monitor.c | 3 +++ monitor.h | 1 + qemu-monitor.hx | 46 ++++++++++++++++++++++++++++++++++++++++++++++ trace-events | 1 + 7 files changed, 95 insertions(+), 1 deletions(-) Signed-off-by: Michal Novotny --- QMP/qmp-events.txt | 23 +++++++++++++++++++++++ blockdev.c | 21 ++++++++++++++++++++- blockdev.h | 1 + monitor.c | 3 +++ monitor.h | 1 + qemu-monitor.hx | 46 ++++++++++++++++++++++++++++++++++++++++++++++ trace-events | 1 + 7 files changed, 95 insertions(+), 1 deletions(-) diff --git a/QMP/qmp-events.txt b/QMP/qmp-events.txt index cb43ba7..75f4708 100644 --- a/QMP/qmp-events.txt +++ b/QMP/qmp-events.txt @@ -326,3 +326,26 @@ Example: "len": 10737418240, "offset": 10737418240, "speed": 0 }, "timestamp": { "seconds": 1267061043, "microseconds": 959568 } } + +BLOCK_JOB_CANCELLED +------------------- + +Emitted when a block job has been cancelled. + +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) + On success this is equal to len. + On failure this is less than len. +- "speed": Rate limit, bytes per second (json-int) + +Example: + +{ "event": "BLOCK_JOB_CANCELLED", + "data": { "type": "stream", "device": "virtio-disk0", + "len": 10737418240, "offset": 134217728, + "speed": 0 }, + "timestamp": { "seconds": 1267061043, "microseconds": 959568 } } diff --git a/blockdev.c b/blockdev.c index 3d7e3a7..ee19b39 100644 --- a/blockdev.c +++ b/blockdev.c @@ -1029,7 +1029,11 @@ static void block_stream_cb(void *opaque, int ret) qdict_put(dict, "error", qstring_from_str(strerror(-ret))); } - monitor_protocol_event(QEVENT_BLOCK_JOB_COMPLETED, obj); + if (block_job_is_cancelled(bs->job)) { + monitor_protocol_event(QEVENT_BLOCK_JOB_CANCELLED, obj); + } else { + monitor_protocol_event(QEVENT_BLOCK_JOB_COMPLETED, obj); + } qobject_decref(obj); } @@ -1097,3 +1101,18 @@ int do_block_job_set_speed(Monitor *mon, const QDict *params, } return 0; } + +int do_block_job_cancel(Monitor *mon, const QDict *params, QObject **ret_data) +{ + const char *device = qdict_get_str(params, "device"); + BlockJob *job = find_block_job(device); + + if (!job) { + qerror_report(QERR_DEVICE_NOT_ACTIVE, device); + return -1; + } + + trace_do_block_job_cancel(job); + block_job_cancel(job); + return 0; +} diff --git a/blockdev.h b/blockdev.h index 32e516b..56adcd1 100644 --- a/blockdev.h +++ b/blockdev.h @@ -74,5 +74,6 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data); 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); #endif diff --git a/monitor.c b/monitor.c index ff688a0..0954ef0 100644 --- a/monitor.c +++ b/monitor.c @@ -481,6 +481,9 @@ void monitor_protocol_event(MonitorEvent event, QObject *data) case QEVENT_BLOCK_JOB_COMPLETED: event_name = "BLOCK_JOB_COMPLETED"; break; + case QEVENT_BLOCK_JOB_CANCELLED: + event_name = "BLOCK_JOB_CANCELLED"; + break; case QEVENT_RH_SPICE_INITIALIZED: event_name = RFQDN_REDHAT "SPICE_INITIALIZED"; break; diff --git a/monitor.h b/monitor.h index f315a92..bbd50f1 100644 --- a/monitor.h +++ b/monitor.h @@ -40,6 +40,7 @@ typedef enum MonitorEvent { QEVENT_SPICE_DISCONNECTED, QEVENT_DEVICE_TRAY_MOVED, QEVENT_BLOCK_JOB_COMPLETED, + QEVENT_BLOCK_JOB_CANCELLED, QEVENT_RH_SPICE_INITIALIZED, QEVENT_RH_SPICE_DISCONNECTED, QEVENT_SUSPEND, diff --git a/qemu-monitor.hx b/qemu-monitor.hx index af9a69e..7c318ac 100644 --- a/qemu-monitor.hx +++ b/qemu-monitor.hx @@ -2121,6 +2121,52 @@ Example: "arguments": { "device": "virtio0", "value": 1024 } } EQMP + { + .name = "block_job_cancel", + .args_type = "device:B", + .params = "device", + .help = "stop an active block streaming operation", + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_block_job_cancel, + }, + +STEXI +@item block_job_cancel +@findex block_job_cancel +Stop an active block streaming operation. +ETEXI + +SQMP +block_job_cancel +---------------- + +Stop an active block streaming operation. + +This command returns immediately after marking the active block streaming +operation for cancellation. It is an error to call this command if no +operation is in progress. + +The operation will cancel as soon as possible and then emit the +BLOCK_JOB_CANCELLED event. Before that happens the job is still visible when +enumerated using query-block-jobs. + +The image file retains its backing file unless the streaming operation happens +to complete just as it is being cancelled. + +A new block streaming operation can be started at a later time to finish +copying all data from the backing file. + +Arguments: + +- device: the device name + +Returns: + +Nothing on success +If streaming is not active on this device, DeviceNotActive +If cancellation already in progress, DeviceInUse +EQMP + HXCOMM Keep the 'info' command at the end! HXCOMM This is required for the QMP documentation layout. diff --git a/trace-events b/trace-events index f226c1c..872fa27 100644 --- a/trace-events +++ b/trace-events @@ -67,6 +67,7 @@ disable stream_one_iteration(void *s, int64_t sector_num, int nb_sectors, int is disable stream_start(void *bs, void *base, void *s, void *co, void *opaque) "bs %p base %p s %p co %p opaque %p" # blockdev.c +disable do_block_job_cancel(void *job) "job %p" disable block_stream_cb(void *bs, void *job, int ret) "bs %p job %p ret %d" disable do_block_stream(void *bs, void *job) "bs %p job %p" -- 1.7.7.6