From patchwork Wed Sep 26 15:56:13 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 187127 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id C86932C0094 for ; Thu, 27 Sep 2012 02:39:57 +1000 (EST) Received: from localhost ([::1]:43655 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TGu0J-0002us-5L for incoming@patchwork.ozlabs.org; Wed, 26 Sep 2012 11:58:27 -0400 Received: from eggs.gnu.org ([208.118.235.92]:48324) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TGtzU-00011f-6N for qemu-devel@nongnu.org; Wed, 26 Sep 2012 11:57:42 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TGtzO-0004hm-Mo for qemu-devel@nongnu.org; Wed, 26 Sep 2012 11:57:36 -0400 Received: from mail-pb0-f45.google.com ([209.85.160.45]:36644) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TGtzO-0004Z6-Gv for qemu-devel@nongnu.org; Wed, 26 Sep 2012 11:57:30 -0400 Received: by mail-pb0-f45.google.com with SMTP id rp2so2106416pbb.4 for ; Wed, 26 Sep 2012 08:57:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references; bh=m66fGCDwF7PdzeZSiPhifYCHmtpZ4cZIACrSS+pSk0c=; b=YceufBTxhucdyPEJW+dJYWODOuWnpFBaog3DTZv2EHkwAmZ4jcG7p77ocaIMIwpNMx vDYj5HjkMW+Nv6vXKSpMpaBaNya9i80wxDDaf9efYyU6m4kymBMpw2995z8Dw6WRiCrN Q5eGJ4HH35Kb7o41/U0jXwDmkJ28gSPM+DmkiH3yY827GPg7n4+cDgmfMHp8f0pVQ6Hx dwMw3YlQBtNDzd9i0qIKwofcTL1Ue6GImIuzP0oOsIg0i0FFf3obOla/raKzm0DHS4RI Jacv4SJcgQtfzgQjwupFhMtV5mY5gFtc9N7RhnIJwlLujiAWsf3NnT3h4gxCneojppPd HZhg== Received: by 10.68.233.136 with SMTP id tw8mr3708763pbc.133.1348675050079; Wed, 26 Sep 2012 08:57:30 -0700 (PDT) Received: from yakj.usersys.redhat.com (93-34-169-1.ip50.fastwebnet.it. [93.34.169.1]) by mx.google.com with ESMTPS id i2sm2114149pav.13.2012.09.26.08.57.26 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 26 Sep 2012 08:57:28 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Wed, 26 Sep 2012 17:56:13 +0200 Message-Id: <1348675011-8794-8-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.7.12 In-Reply-To: <1348675011-8794-1-git-send-email-pbonzini@redhat.com> References: <1348675011-8794-1-git-send-email-pbonzini@redhat.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.85.160.45 Cc: kwolf@redhat.com, jcody@redhat.com Subject: [Qemu-devel] [PATCH v2 07/45] qmp: add block-job-pause and block-job-resume X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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 --- v1->v2: document that the commands do not nest; a single resume command will always resume. blockdev.c | 35 +++++++++++++++++++++++++++++++++-- hmp-commands.hx | 35 ++++++++++++++++++++++++++++++++--- hmp.c | 23 ++++++++++++++++++++++- hmp.h | 2 ++ qapi-schema.json | 45 ++++++++++++++++++++++++++++++++++++++++++++- qmp-commands.hx | 12 +++++++++++- trace-events | 2 ++ 7 file modificati, 146 inserzioni(+), 8 rimozioni(-) diff --git a/blockdev.c b/blockdev.c index df0c449..a718380 100644 --- a/blockdev.c +++ b/blockdev.c @@ -1150,15 +1150,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; } @@ -1167,6 +1172,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 ed67e99..27d90a2 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 ba6fbd3..55601f7 100644 --- a/hmp.c +++ b/hmp.c @@ -950,8 +950,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 48b9c59..71ea384 100644 --- a/hmp.h +++ b/hmp.h @@ -64,6 +64,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 f8a67ae..2bd94dc 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -1855,12 +1855,55 @@ # # @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, DeviceNotActive # # Since: 1.1 ## -{ 'command': 'block-job-cancel', 'data': { 'device': 'str' } } +{ '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. Pausing an already paused job has no cumulative +# effect; a single block-job-resume command will resume the job. +# +# 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.3 +## +{ '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. It is an error to call this command if no operation is in +# progress. Resuming an already running job is not an error. +# +# @device: the device name +# +# Returns: Nothing on success +# If no background operation is active on this device, DeviceNotActive +# +# Since: 1.3 +## +{ 'command': 'block-job-resume', 'data': { 'device': 'str' } } ## # @ObjectTypeInfo: diff --git a/qmp-commands.hx b/qmp-commands.hx index 6e21ddb..85eacb5 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -799,10 +799,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 e90de71..75f7357 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_job_cb(void *bs, void *job, int ret) "bs %p job %p ret %d" qmp_block_stream(void *bs, void *job) "bs %p job %p"