qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
To: qemu-devel@nongnu.org
Cc: Kevin Wolf <kwolf@redhat.com>,
	Anthony Liguori <aliguori@us.ibm.com>,
	Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>,
	Adam Litke <agl@us.ibm.com>
Subject: [Qemu-devel] [PATCH 09/15] qmp: add block_job_cancel command
Date: Wed, 27 Jul 2011 14:44:49 +0100	[thread overview]
Message-ID: <1311774295-8696-10-git-send-email-stefanha@linux.vnet.ibm.com> (raw)
In-Reply-To: <1311774295-8696-1-git-send-email-stefanha@linux.vnet.ibm.com>

Image streaming operations can be stopped using the block_job_cancel
command.  In the future other types of background operations on block
devices can be cancelled using this command.

The command synopsis is:

block_job_cancel
----------------

Stop an active block streaming operation.

This command returns once the active block streaming operation has been
stopped.  It is an error to call this command if no operation is in
progress.

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: device name (json-string)

Errors:

DeviceNotActive: streaming is not active on this device
DeviceInUse:     cancellation already in progress

Examples:

-> { "execute": "block_job_cancel", "arguments":
    { "device": "virtio0" } }
<- { "return":  {} }

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
---
 blockdev.c      |   34 ++++++++++++++++++++++++++++++++++
 blockdev.h      |    3 +++
 hmp-commands.hx |   15 +++++++++++++++
 qmp-commands.hx |   41 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 93 insertions(+), 0 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index cd5e49c..e9bc577 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -52,6 +52,8 @@ static const int if_max_devs[IF_COUNT] = {
 };
 
 typedef struct StreamState {
+    MonitorCompletion *cancel_cb;
+    void *cancel_opaque;
     int64_t offset;             /* current position in block device */
     BlockDriverState *bs;
     QEMUTimer *timer;
@@ -90,6 +92,10 @@ static void stream_free(StreamState *s)
 {
     QLIST_REMOVE(s, list);
 
+    if (s->cancel_cb) {
+        s->cancel_cb(s->cancel_opaque, NULL);
+    }
+
     qemu_del_timer(s->timer);
     qemu_free_timer(s->timer);
     qemu_free(s);
@@ -115,6 +121,8 @@ static void stream_cb(void *opaque, int nb_sectors)
     if (s->offset == bdrv_getlength(s->bs)) {
         bdrv_change_backing_file(s->bs, NULL, NULL);
         stream_complete(s, 0);
+    } else if (s->cancel_cb) {
+        stream_free(s);
     } else {
         qemu_mod_timer(s->timer, qemu_get_clock_ns(rt_clock));
     }
@@ -176,6 +184,24 @@ static StreamState *stream_start(const char *device)
     return s;
 }
 
+static int stream_stop(const char *device, MonitorCompletion *cb, void *opaque)
+{
+    StreamState *s = stream_find(device);
+
+    if (!s) {
+        qerror_report(QERR_DEVICE_NOT_ACTIVE, device);
+        return -1;
+    }
+    if (s->cancel_cb) {
+        qerror_report(QERR_DEVICE_IN_USE, device);
+        return -1;
+    }
+
+    s->cancel_cb = cb;
+    s->cancel_opaque = opaque;
+    return 0;
+}
+
 /*
  * We automatically delete the drive when a device using it gets
  * unplugged.  Questionable feature, but we can't just drop it.
@@ -783,6 +809,14 @@ int do_block_stream(Monitor *mon, const QDict *params, QObject **ret_data)
     return stream_start(device) ? 0 : -1;
 }
 
+int do_block_job_cancel(Monitor *mon, const QDict *params,
+                        MonitorCompletion cb, void *opaque)
+{
+    const char *device = qdict_get_str(params, "device");
+
+    return stream_stop(device, cb, opaque);
+}
+
 static int eject_device(Monitor *mon, BlockDriverState *bs, int force)
 {
     if (!force) {
diff --git a/blockdev.h b/blockdev.h
index f475aa8..a3cde69 100644
--- a/blockdev.h
+++ b/blockdev.h
@@ -12,6 +12,7 @@
 
 #include "block.h"
 #include "qemu-queue.h"
+#include "monitor.h"
 
 void blockdev_mark_auto_del(BlockDriverState *bs);
 void blockdev_auto_del(BlockDriverState *bs);
@@ -66,5 +67,7 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data);
 int do_snapshot_blkdev(Monitor *mon, const QDict *qdict, QObject **ret_data);
 int do_block_resize(Monitor *mon, const QDict *qdict, 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);
 
 #endif
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 9bf1025..613eb76 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -52,6 +52,21 @@ Copy data from a backing file into a block device.
 ETEXI
 
     {
+        .name       = "block_job_cancel",
+        .args_type  = "device:B",
+        .params     = "device",
+        .help       = "Stop an active block streaming operation",
+        .mhandler.cmd_async = do_block_job_cancel,
+        .flags      = MONITOR_CMD_ASYNC,
+    },
+
+STEXI
+@item block_job_cancel
+@findex block_job_cancel
+Stop an active block streaming operation.
+ETEXI
+
+    {
         .name       = "q|quit",
         .args_type  = "",
         .params     = "",
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 80402c7..5ab15a4 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -1010,6 +1010,47 @@ Examples:
 EQMP
 
     {
+        .name       = "block_job_cancel",
+        .args_type  = "device:B",
+        .params     = "device",
+        .help       = "Stop an active streaming operation on a block device",
+        .mhandler.cmd_async = do_block_job_cancel,
+        .flags      = MONITOR_CMD_ASYNC,
+    },
+
+SQMP
+
+block_job_cancel
+----------------
+
+Stop an active block streaming operation.
+
+This command returns once the active block streaming operation has been
+stopped.  It is an error to call this command if no operation is in progress.
+
+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: device name (json-string)
+
+Errors:
+
+DeviceNotActive: streaming is not active on this device
+DeviceInUse:     cancellation already in progress
+
+Examples:
+
+-> { "execute": "block_job_cancel", "arguments": { "device": "virtio0" } }
+<- { "return":  {} }
+
+EQMP
+
+    {
         .name       = "qmp_capabilities",
         .args_type  = "",
         .params     = "",
-- 
1.7.5.4

  parent reply	other threads:[~2011-07-27 13:45 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-07-27 13:44 [Qemu-devel] [RFC v2 00/15] QED image streaming Stefan Hajnoczi
2011-07-27 13:44 ` [Qemu-devel] [PATCH 01/15] block: add -drive copy-on-read=on|off Stefan Hajnoczi
2011-07-27 13:44 ` [Qemu-devel] [PATCH 02/15] qed: replace is_write with flags field Stefan Hajnoczi
2011-07-27 13:44 ` [Qemu-devel] [PATCH 03/15] qed: extract qed_start_allocating_write() Stefan Hajnoczi
2011-07-27 13:44 ` [Qemu-devel] [PATCH 04/15] qed: make qed_aio_write_alloc() reusable Stefan Hajnoczi
2011-07-27 13:44 ` [Qemu-devel] [PATCH 05/15] qed: add support for copy-on-read Stefan Hajnoczi
2011-07-27 13:44 ` [Qemu-devel] [PATCH 06/15] qed: avoid deadlock on emulated synchronous I/O Stefan Hajnoczi
2011-07-27 13:44 ` [Qemu-devel] [PATCH 07/15] block: add bdrv_aio_copy_backing() Stefan Hajnoczi
2011-07-27 13:44 ` [Qemu-devel] [PATCH 08/15] qmp: add block_stream command Stefan Hajnoczi
2011-07-28 15:53   ` Marcelo Tosatti
2011-07-28 15:57     ` Stefan Hajnoczi
2011-07-27 13:44 ` Stefan Hajnoczi [this message]
2011-07-27 13:44 ` [Qemu-devel] [PATCH 10/15] qmp: add query-block-jobs command Stefan Hajnoczi
2011-07-27 13:44 ` [Qemu-devel] [PATCH 11/15] qmp: add block_job_set_speed command Stefan Hajnoczi
2011-07-27 13:44 ` [Qemu-devel] [PATCH 12/15] block: add -drive stream=on|off Stefan Hajnoczi
2011-07-27 13:44 ` [Qemu-devel] [PATCH 13/15] qed: intelligent streaming implementation Stefan Hajnoczi
2011-07-27 13:44 ` [Qemu-devel] [PATCH 14/15] trace: trace bdrv_aio_readv/writev error paths Stefan Hajnoczi
2011-07-27 13:44 ` [Qemu-devel] [PATCH 15/15] tests: add image streaming QMP interface tests Stefan Hajnoczi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1311774295-8696-10-git-send-email-stefanha@linux.vnet.ibm.com \
    --to=stefanha@linux.vnet.ibm.com \
    --cc=agl@us.ibm.com \
    --cc=aliguori@us.ibm.com \
    --cc=kwolf@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).