[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC PATCH 06/36] qmp: add block-job-pause and block-job-re
From: |
Paolo Bonzini |
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 |
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 <address@hidden>
---
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
address@hidden block_job_pause
address@hidden 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
address@hidden block_job_resume
address@hidden 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
- [Qemu-devel] [RFC PATCH 00/36] A peek at the current block job patches, Paolo Bonzini, 2012/06/15
- [Qemu-devel] [RFC PATCH 01/36] qapi: generalize documentation of streaming commands, Paolo Bonzini, 2012/06/15
- [Qemu-devel] [RFC PATCH 02/36] qerror/block: introduce QERR_BLOCK_JOB_NOT_ACTIVE, Paolo Bonzini, 2012/06/15
- [Qemu-devel] [RFC PATCH 04/36] block: add block_job_query, Paolo Bonzini, 2012/06/15
- [Qemu-devel] [RFC PATCH 03/36] block: move job APIs to separate files, Paolo Bonzini, 2012/06/15
- [Qemu-devel] [RFC PATCH 06/36] qmp: add block-job-pause and block-job-resume,
Paolo Bonzini <=
- [Qemu-devel] [RFC PATCH 05/36] block: add support for job pause/resume, Paolo Bonzini, 2012/06/15
- [Qemu-devel] [RFC PATCH 08/36] block: rename block_job_complete to block_job_completed, Paolo Bonzini, 2012/06/15
- [Qemu-devel] [RFC PATCH 07/36] qemu-iotests: add test for pausing a streaming operation, Paolo Bonzini, 2012/06/15
- [Qemu-devel] [RFC PATCH 10/36] block: move BlockdevOnError declaration to QAPI, Paolo Bonzini, 2012/06/15
- [Qemu-devel] [RFC PATCH 09/36] block: rename BlockErrorAction, BlockQMPEventAction, Paolo Bonzini, 2012/06/15
- [Qemu-devel] [RFC PATCH 12/36] block: sort BlockDeviceIoStatus errors by severity, Paolo Bonzini, 2012/06/15
- [Qemu-devel] [RFC PATCH 11/36] block: reorganize io error code, Paolo Bonzini, 2012/06/15