qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Cc: kwolf@redhat.com, stefanha@linux.vnet.ibm.com, lcapitulino@redhat.com
Subject: [Qemu-devel] [RFC PATCH 06/36] qmp: add block-job-pause and block-job-resume
Date: Fri, 15 Jun 2012 17:05:29 +0200	[thread overview]
Message-ID: <1339772759-31004-7-git-send-email-pbonzini@redhat.com> (raw)
In-Reply-To: <1339772759-31004-1-git-send-email-pbonzini@redhat.com>

Add QMP commands matching the functionality.

Paused jobs cannot be canceled without first resuming them.  This
ensures that I/O errors are never missed by management.  However, an
optional force argument can be specified to allow that.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 blockdev.c       |   35 +++++++++++++++++++++++++++++++++--
 hmp-commands.hx  |   35 ++++++++++++++++++++++++++++++++---
 hmp.c            |   23 ++++++++++++++++++++++-
 hmp.h            |    2 ++
 qapi-schema.json |   47 +++++++++++++++++++++++++++++++++++++++++++++--
 qmp-commands.hx  |   12 +++++++++++-
 trace-events     |    2 ++
 7 files changed, 147 insertions(+), 9 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index 8bf659a..1ea6e94 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1151,15 +1151,20 @@ void qmp_block_job_set_speed(const char *device, int64_t speed, Error **errp)
     block_job_set_speed(job, speed, errp);
 }
 
-void qmp_block_job_cancel(const char *device, Error **errp)
+void qmp_block_job_cancel(const char *device,
+                          bool has_force, bool force, Error **errp)
 {
     BlockJob *job = find_block_job(device);
 
+    if (!has_force) {
+        force = false;
+    }
+
     if (!job) {
         error_set(errp, QERR_BLOCK_JOB_NOT_ACTIVE, device);
         return;
     }
-    if (job->paused) {
+    if (job->paused && !force) {
         error_set(errp, QERR_BLOCK_JOB_PAUSED, device);
         return;
     }
@@ -1168,6 +1173,32 @@ void qmp_block_job_cancel(const char *device, Error **errp)
     block_job_cancel(job);
 }
 
+void qmp_block_job_pause(const char *device, Error **errp)
+{
+    BlockJob *job = find_block_job(device);
+
+    if (!job) {
+        error_set(errp, QERR_BLOCK_JOB_NOT_ACTIVE, device);
+        return;
+    }
+
+    trace_qmp_block_job_pause(job);
+    block_job_pause(job);
+}
+
+void qmp_block_job_resume(const char *device, Error **errp)
+{
+    BlockJob *job = find_block_job(device);
+
+    if (!job) {
+        error_set(errp, QERR_BLOCK_JOB_NOT_ACTIVE, device);
+        return;
+    }
+
+    trace_qmp_block_job_resume(job);
+    block_job_resume(job);
+}
+
 static void do_qmp_query_block_jobs_one(void *opaque, BlockDriverState *bs)
 {
     BlockJobInfoList **prev = opaque;
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 26a4d8d..836564c 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -99,9 +99,10 @@ ETEXI
 
     {
         .name       = "block_job_cancel",
-        .args_type  = "device:B",
-        .params     = "device",
-        .help       = "stop an active background block operation",
+        .args_type  = "force:-f,device:B",
+        .params     = "[-f] device",
+        .help       = "stop an active background block operation (use -f"
+                      "\n\t\t\t if the operation is currently paused)",
         .mhandler.cmd = hmp_block_job_cancel,
     },
 
@@ -112,6 +113,34 @@ Stop an active block streaming operation.
 ETEXI
 
     {
+        .name       = "block_job_pause",
+        .args_type  = "device:B",
+        .params     = "device",
+        .help       = "pause an active background block operation",
+        .mhandler.cmd = hmp_block_job_pause,
+    },
+
+STEXI
+@item block_job_pause
+@findex block_job_pause
+Pause an active block streaming operation.
+ETEXI
+
+    {
+        .name       = "block_job_resume",
+        .args_type  = "device:B",
+        .params     = "device",
+        .help       = "resume a paused background block operation",
+        .mhandler.cmd = hmp_block_job_resume,
+    },
+
+STEXI
+@item block_job_resume
+@findex block_job_resume
+Resume a paused block streaming operation.
+ETEXI
+
+    {
         .name       = "eject",
         .args_type  = "force:-f,device:B",
         .params     = "[-f] device",
diff --git a/hmp.c b/hmp.c
index b9cec1d..9f6b255 100644
--- a/hmp.c
+++ b/hmp.c
@@ -863,8 +863,29 @@ void hmp_block_job_cancel(Monitor *mon, const QDict *qdict)
 {
     Error *error = NULL;
     const char *device = qdict_get_str(qdict, "device");
+    bool force = qdict_get_try_bool(qdict, "force", 0);
 
-    qmp_block_job_cancel(device, &error);
+    qmp_block_job_cancel(device, true, force, &error);
+
+    hmp_handle_error(mon, &error);
+}
+
+void hmp_block_job_pause(Monitor *mon, const QDict *qdict)
+{
+    Error *error = NULL;
+    const char *device = qdict_get_str(qdict, "device");
+
+    qmp_block_job_pause(device, &error);
+
+    hmp_handle_error(mon, &error);
+}
+
+void hmp_block_job_resume(Monitor *mon, const QDict *qdict)
+{
+    Error *error = NULL;
+    const char *device = qdict_get_str(qdict, "device");
+
+    qmp_block_job_resume(device, &error);
 
     hmp_handle_error(mon, &error);
 }
diff --git a/hmp.h b/hmp.h
index 79d138d..6a16eec 100644
--- a/hmp.h
+++ b/hmp.h
@@ -59,6 +59,8 @@ void hmp_block_set_io_throttle(Monitor *mon, const QDict *qdict);
 void hmp_block_stream(Monitor *mon, const QDict *qdict);
 void hmp_block_job_set_speed(Monitor *mon, const QDict *qdict);
 void hmp_block_job_cancel(Monitor *mon, const QDict *qdict);
+void hmp_block_job_pause(Monitor *mon, const QDict *qdict);
+void hmp_block_job_resume(Monitor *mon, const QDict *qdict);
 void hmp_migrate(Monitor *mon, const QDict *qdict);
 void hmp_device_del(Monitor *mon, const QDict *qdict);
 void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict);
diff --git a/qapi-schema.json b/qapi-schema.json
index 178549d..c16e1ea 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -1680,13 +1680,56 @@
 #
 # @device: the device name
 #
+# @force: #optional whether to allow cancellation of a paused job (default false)
+#
 # Returns: Nothing on success
 #          If no background operation is active on this device, BlockJobNotActive
-#          If the job is currently paused, BlockJobPaused
+#          If the job is paused and force is absent or false, BlockJobPaused
+#
+# Since: 1.1
+##
+{ 'command': 'block-job-cancel', 'data': { 'device': 'str', '*force': 'bool' } }
+
+##
+# @block-job-pause:
+#
+# Pause an active background block operation.
+#
+# This command returns immediately after marking the active background block
+# operation for pausing.  It is an error to call this command if no
+# operation is in progress.
+#
+# The operation will pause as soon as possible.  No event is emitted when
+# the operation is actually paused.  Cancelling a paused job automatically
+# resumes it.
+#
+# @device: the device name
+#
+# Returns: Nothing on success
+#          If no background operation is active on this device, DeviceNotActive
+#
+# Since: 1.1
+##
+{ 'command': 'block-job-pause', 'data': { 'device': 'str' } }
+
+##
+# @block-job-resume:
+#
+# Resume an active background block operation.
+#
+# This command returns immediately after resuming a paused background block
+# operation for cancellation.  It is an error to call this command if no
+# operation is in progress.
+#
+# @device: the device name
+#
+# Returns: Nothing on success
+#          If no background operation is active on this device, DeviceNotActive
+#          If cancellation already in progress, DeviceInUse
 #
 # Since: 1.1
 ##
-{ 'command': 'block-job-cancel', 'data': { 'device': 'str' } }
+{ 'command': 'block-job-resume', 'data': { 'device': 'str' } }
 
 ##
 # @ObjectTypeInfo:
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 2e1a38e..f20754a 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -730,10 +730,20 @@ EQMP
 
     {
         .name       = "block-job-cancel",
-        .args_type  = "device:B",
+        .args_type  = "device:B,force:b?",
         .mhandler.cmd_new = qmp_marshal_input_block_job_cancel,
     },
     {
+        .name       = "block-job-pause",
+        .args_type  = "device:B",
+        .mhandler.cmd_new = qmp_marshal_input_block_job_pause,
+    },
+    {
+        .name       = "block-job-resume",
+        .args_type  = "device:B",
+        .mhandler.cmd_new = qmp_marshal_input_block_job_resume,
+    },
+    {
         .name       = "transaction",
         .args_type  = "actions:q",
         .mhandler.cmd_new = qmp_marshal_input_transaction,
diff --git a/trace-events b/trace-events
index f70523c..25ebfe9 100644
--- a/trace-events
+++ b/trace-events
@@ -77,6 +77,8 @@ stream_start(void *bs, void *base, void *s, void *co, void *opaque) "bs %p base
 
 # blockdev.c
 qmp_block_job_cancel(void *job) "job %p"
+qmp_block_job_pause(void *job) "job %p"
+qmp_block_job_resume(void *job) "job %p"
 block_stream_cb(void *bs, void *job, int ret) "bs %p job %p ret %d"
 qmp_block_stream(void *bs, void *job) "bs %p job %p"
 
-- 
1.7.10.2

  parent reply	other threads:[~2012-06-15 15:06 UTC|newest]

Thread overview: 65+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-06-15 15:05 [Qemu-devel] [RFC PATCH 00/36] A peek at the current block job patches Paolo Bonzini
2012-06-15 15:05 ` [Qemu-devel] [RFC PATCH 01/36] qapi: generalize documentation of streaming commands Paolo Bonzini
2012-06-15 16:45   ` Eric Blake
2012-07-11 16:00     ` Paolo Bonzini
2012-07-12  8:07       ` Kevin Wolf
2012-07-12 20:41         ` Blue Swirl
2012-07-13  9:13           ` Kevin Wolf
2012-06-15 15:05 ` [Qemu-devel] [RFC PATCH 02/36] qerror/block: introduce QERR_BLOCK_JOB_NOT_ACTIVE Paolo Bonzini
2012-06-15 16:51   ` Eric Blake
2012-06-15 16:56     ` Paolo Bonzini
2012-06-15 15:05 ` [Qemu-devel] [RFC PATCH 03/36] block: move job APIs to separate files Paolo Bonzini
2012-06-15 15:05 ` [Qemu-devel] [RFC PATCH 04/36] block: add block_job_query Paolo Bonzini
2012-06-15 15:05 ` [Qemu-devel] [RFC PATCH 05/36] block: add support for job pause/resume Paolo Bonzini
2012-06-15 17:22   ` Eric Blake
2012-06-15 15:05 ` Paolo Bonzini [this message]
2012-06-15 17:32   ` [Qemu-devel] [RFC PATCH 06/36] qmp: add block-job-pause and block-job-resume Eric Blake
2012-07-11 16:02     ` Paolo Bonzini
2012-06-15 15:05 ` [Qemu-devel] [RFC PATCH 07/36] qemu-iotests: add test for pausing a streaming operation Paolo Bonzini
2012-06-15 15:05 ` [Qemu-devel] [RFC PATCH 08/36] block: rename block_job_complete to block_job_completed Paolo Bonzini
2012-06-15 15:05 ` [Qemu-devel] [RFC PATCH 09/36] block: rename BlockErrorAction, BlockQMPEventAction Paolo Bonzini
2012-06-15 15:05 ` [Qemu-devel] [RFC PATCH 10/36] block: move BlockdevOnError declaration to QAPI Paolo Bonzini
2012-06-15 15:05 ` [Qemu-devel] [RFC PATCH 11/36] block: reorganize io error code Paolo Bonzini
2012-06-15 15:05 ` [Qemu-devel] [RFC PATCH 12/36] block: sort BlockDeviceIoStatus errors by severity Paolo Bonzini
2012-06-15 17:45   ` Eric Blake
2012-07-11 16:03     ` Paolo Bonzini
2012-06-15 15:05 ` [Qemu-devel] [RFC PATCH 13/36] block: introduce block job error Paolo Bonzini
2012-06-15 17:50   ` Eric Blake
2012-07-11 16:10     ` Paolo Bonzini
2012-06-15 15:05 ` [Qemu-devel] [RFC PATCH 14/36] stream: add on_error argument Paolo Bonzini
2012-06-15 17:58   ` Eric Blake
2012-07-11 16:12     ` Paolo Bonzini
2012-06-15 15:05 ` [Qemu-devel] [RFC PATCH 15/36] qemu-iotests: add tests for streaming error handling Paolo Bonzini
2012-06-15 15:05 ` [Qemu-devel] [RFC PATCH 16/36] block: add bdrv_query_info Paolo Bonzini
2012-06-15 15:05 ` [Qemu-devel] [RFC PATCH 17/36] block: add bdrv_query_stats Paolo Bonzini
2012-06-15 15:05 ` [Qemu-devel] [RFC PATCH 18/36] block: make device optional in BlockInfo Paolo Bonzini
2012-06-15 15:05 ` [Qemu-devel] [RFC PATCH 19/36] block: add target info to QMP query-blockjobs command Paolo Bonzini
2012-06-15 15:05 ` [Qemu-devel] [RFC PATCH 20/36] block: forward bdrv_iostatus_reset to block job Paolo Bonzini
2012-06-15 15:05 ` [Qemu-devel] [RFC PATCH 21/36] block: introduce new dirty bitmap functionality Paolo Bonzini
2012-06-15 15:05 ` [Qemu-devel] [RFC PATCH 22/36] block: add mirror job Paolo Bonzini
2012-06-15 18:20   ` Eric Blake
2012-07-12 13:45     ` Paolo Bonzini
2012-06-15 15:05 ` [Qemu-devel] [RFC PATCH 23/36] qmp: add drive-mirror command Paolo Bonzini
2012-06-15 20:12   ` Eric Blake
2012-07-11 16:23     ` Paolo Bonzini
2012-06-15 15:05 ` [Qemu-devel] [RFC PATCH 24/36] mirror: support querying target file Paolo Bonzini
2012-06-15 15:05 ` [Qemu-devel] [RFC PATCH 25/36] mirror: add support for on_source_error/on_target_error Paolo Bonzini
2012-06-15 21:12   ` Eric Blake
2012-07-11 16:28     ` Paolo Bonzini
2012-06-15 15:05 ` [Qemu-devel] [RFC PATCH 26/36] block: live snapshot documentation tweaks Paolo Bonzini
2012-06-15 21:14   ` Eric Blake
2012-07-11 16:16     ` Paolo Bonzini
2012-06-15 15:05 ` [Qemu-devel] [RFC PATCH 27/36] block: add bdrv_ensure_backing_file Paolo Bonzini
2012-06-15 15:05 ` [Qemu-devel] [RFC PATCH 28/36] block: add block-job-complete Paolo Bonzini
2012-06-15 21:42   ` Eric Blake
2012-06-15 15:05 ` [Qemu-devel] [RFC PATCH 29/36] mirror: implement completion Paolo Bonzini
2012-06-15 15:05 ` [Qemu-devel] [RFC PATCH 30/36] add hierarchical bitmap data type and test cases Paolo Bonzini
2012-06-15 23:02   ` Eric Blake
2012-07-11 16:35     ` Paolo Bonzini
2012-06-15 15:05 ` [Qemu-devel] [RFC PATCH 31/36] block: implement dirty bitmap using HBitmap Paolo Bonzini
2012-06-15 15:05 ` [Qemu-devel] [RFC PATCH 32/36] block: make round_to_clusters public Paolo Bonzini
2012-06-15 15:05 ` [Qemu-devel] [RFC PATCH 33/36] mirror: perform COW if the cluster size is bigger than the granularity Paolo Bonzini
2012-06-15 15:05 ` [Qemu-devel] [RFC PATCH 34/36] block: return count of dirty sectors, not chunks Paolo Bonzini
2012-06-15 15:05 ` [Qemu-devel] [RFC PATCH 35/36] block: allow customizing the granularity of the dirty bitmap Paolo Bonzini
2012-06-15 15:05 ` [Qemu-devel] [RFC PATCH 36/36] mirror: allow customizing the granularity Paolo Bonzini
2012-06-15 23:24   ` Eric Blake

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=1339772759-31004-7-git-send-email-pbonzini@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=lcapitulino@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@linux.vnet.ibm.com \
    /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).