From patchwork Tue Aug 23 12:58:22 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 111090 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 02AA0B6FAF for ; Tue, 23 Aug 2011 22:59:30 +1000 (EST) Received: from localhost ([::1]:51589 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QvqZj-0001sZ-Ar for incoming@patchwork.ozlabs.org; Tue, 23 Aug 2011 08:59:27 -0400 Received: from eggs.gnu.org ([140.186.70.92]:32867) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QvqYx-0007md-DL for qemu-devel@nongnu.org; Tue, 23 Aug 2011 08:58:40 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QvqYs-00023o-2D for qemu-devel@nongnu.org; Tue, 23 Aug 2011 08:58:39 -0400 Received: from mtagate2.uk.ibm.com ([194.196.100.162]:60931) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QvqYr-00023a-KD for qemu-devel@nongnu.org; Tue, 23 Aug 2011 08:58:34 -0400 Received: from d06nrmr1507.portsmouth.uk.ibm.com (d06nrmr1507.portsmouth.uk.ibm.com [9.149.38.233]) by mtagate2.uk.ibm.com (8.13.1/8.13.1) with ESMTP id p7NCwWe5013341 for ; Tue, 23 Aug 2011 12:58:32 GMT Received: from d06av08.portsmouth.uk.ibm.com (d06av08.portsmouth.uk.ibm.com [9.149.37.249]) by d06nrmr1507.portsmouth.uk.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id p7NCwUhg2568278 for ; Tue, 23 Aug 2011 13:58:32 +0100 Received: from d06av08.portsmouth.uk.ibm.com (loopback [127.0.0.1]) by d06av08.portsmouth.uk.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id p7NCwUKC021069 for ; Tue, 23 Aug 2011 13:58:30 +0100 Received: from stefanha-thinkpad.manchester-maybrook.uk.ibm.com (dyn-9-174-219-30.manchester-maybrook.uk.ibm.com [9.174.219.30]) by d06av08.portsmouth.uk.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id p7NCwT1W021041; Tue, 23 Aug 2011 13:58:29 +0100 From: Stefan Hajnoczi To: Date: Tue, 23 Aug 2011 13:58:22 +0100 Message-Id: <1314104305-20523-2-git-send-email-stefanha@linux.vnet.ibm.com> X-Mailer: git-send-email 1.7.5.4 In-Reply-To: <1314104305-20523-1-git-send-email-stefanha@linux.vnet.ibm.com> References: <1314104305-20523-1-git-send-email-stefanha@linux.vnet.ibm.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6, seldom 2.4 (older, 4) X-Received-From: 194.196.100.162 Cc: Anthony Liguori , Stefan Hajnoczi , Adam Litke Subject: [Qemu-devel] [PATCH 1/4] qmp: add block_stream command 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 This patch introduces the block_stream HMP/QMP command. It is currently unimplemented and returns the 'NotSupported' error. block_stream ------------ Copy data from a backing file into a block device. The block streaming operation is performed in the background until the entire backing file has been copied. This command returns immediately once streaming has started. The status of ongoing block streaming operations can be checked with query-block-jobs. The operation can be stopped before it has completed using the block_job_cancel command. If a base file is specified then sectors are not copied from that base file and its backing chain. When streaming completes the image file will have the base file as its backing file. This can be used to stream a subset of the backing file chain instead of flattening the entire image. On successful completion the image file is updated to drop the backing file. Arguments: - device: device name (json-string) - base: common backing file (json-string, optional) Errors: DeviceInUse: streaming is already active on this device DeviceNotFound: device name is invalid NotSupported: image streaming is not supported by this device Events: On completion the BLOCK_JOB_COMPLETED event is raised with the following fields: - type: job type ("stream" for image streaming, json-string) - device: device name (json-string) - end: maximum progress value (json-int) - position: current progress value (json-int) - speed: rate limit, bytes per second (json-int) - error: error message (json-string, only on error) The completion event is raised both on success and on failure. On success position is equal to end. On failure position and end can be used to indicate at which point the operation failed. On failure the error field contains a human-readable error message. There are no semantics other than that streaming has failed and clients should not try to interpret the error string. Examples: -> { "execute": "block_stream", "arguments": { "device": "virtio0" } } <- { "return": {} } Signed-off-by: Stefan Hajnoczi --- blockdev.c | 18 +++++++++++++++ blockdev.h | 1 + hmp-commands.hx | 14 +++++++++++ monitor.c | 3 ++ monitor.h | 1 + qerror.h | 3 ++ qmp-commands.hx | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 105 insertions(+), 0 deletions(-) diff --git a/blockdev.c b/blockdev.c index d272659..208bfc9 100644 --- a/blockdev.c +++ b/blockdev.c @@ -790,3 +790,21 @@ int do_block_resize(Monitor *mon, const QDict *qdict, QObject **ret_data) return 0; } + +int do_block_stream(Monitor *mon, const QDict *params, QObject **ret_data) +{ + const char *device = qdict_get_str(params, "device"); + BlockDriverState *bs; + + bs = bdrv_find(device); + if (!bs) { + qerror_report(QERR_DEVICE_NOT_FOUND, device); + return -1; + } + + /* This command is not yet implemented. The device not found check above + * is done so that error ordering will not change when fully implemented. + */ + qerror_report(QERR_NOT_SUPPORTED); + return -1; +} diff --git a/blockdev.h b/blockdev.h index 3587786..ad98d37 100644 --- a/blockdev.h +++ b/blockdev.h @@ -65,5 +65,6 @@ int do_change_block(Monitor *mon, const char *device, 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 *qdict, QObject **ret_data); #endif diff --git a/hmp-commands.hx b/hmp-commands.hx index 0ccfb28..2a16fd9 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -70,6 +70,20 @@ but should be used with extreme caution. Note that this command only resizes image files, it can not resize block devices like LVM volumes. ETEXI + { + .name = "block_stream", + .args_type = "device:B,base:s?", + .params = "device [base]", + .help = "copy data from a backing file into a block device", + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_block_stream, + }, + +STEXI +@item block_stream +@findex block_stream +Copy data from a backing file into a block device. +ETEXI { .name = "eject", diff --git a/monitor.c b/monitor.c index ada51d0..dc55fca 100644 --- a/monitor.c +++ b/monitor.c @@ -468,6 +468,9 @@ void monitor_protocol_event(MonitorEvent event, QObject *data) case QEVENT_SPICE_DISCONNECTED: event_name = "SPICE_DISCONNECTED"; break; + case QEVENT_BLOCK_JOB_COMPLETED: + event_name = "BLOCK_JOB_COMPLETED"; + break; default: abort(); break; diff --git a/monitor.h b/monitor.h index 4f2d328..135c927 100644 --- a/monitor.h +++ b/monitor.h @@ -35,6 +35,7 @@ typedef enum MonitorEvent { QEVENT_SPICE_CONNECTED, QEVENT_SPICE_INITIALIZED, QEVENT_SPICE_DISCONNECTED, + QEVENT_BLOCK_JOB_COMPLETED, QEVENT_MAX, } MonitorEvent; diff --git a/qerror.h b/qerror.h index 8058456..eba9238 100644 --- a/qerror.h +++ b/qerror.h @@ -139,6 +139,9 @@ QError *qobject_to_qerror(const QObject *obj); #define QERR_NO_BUS_FOR_DEVICE \ "{ 'class': 'NoBusForDevice', 'data': { 'device': %s, 'bus': %s } }" +#define QERR_NOT_SUPPORTED \ + "{ 'class': 'NotSupported', 'data': {} }" + #define QERR_OPEN_FILE_FAILED \ "{ 'class': 'OpenFileFailed', 'data': { 'filename': %s } }" diff --git a/qmp-commands.hx b/qmp-commands.hx index 03f67da..60c9bdf 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -694,6 +694,71 @@ Example: EQMP { + .name = "block_stream", + .args_type = "device:B,base:s?", + .params = "device [base]", + .user_print = monitor_user_noop, + .mhandler.cmd_new = do_block_stream, + }, + +SQMP +block_stream +------------ + +Copy data from a backing file into a block device. + +The block streaming operation is performed in the background until the entire +backing file has been copied. This command returns immediately once streaming +has started. The status of ongoing block streaming operations can be checked +with query-block-jobs. The operation can be stopped before it has completed +using the block_job_cancel command. + +If a base file is specified then sectors are not copied from that base file and +its backing chain. When streaming completes the image file will have the base +file as its backing file. This can be used to stream a subset of the backing +file chain instead of flattening the entire image. + +On successful completion the image file is updated to drop the backing file. + +Arguments: + +- device: device name (json-string) +- base: common backing file (json-string, optional) + +Errors: + +DeviceInUse: streaming is already active on this device +DeviceNotFound: device name is invalid +NotSupported: image streaming is not supported by this device + +Events: + +On completion the BLOCK_JOB_COMPLETED event is raised with the following +fields: + +- type: job type ("stream" for image streaming, json-string) +- device: device name (json-string) +- end: maximum progress value (json-int) +- position: current progress value (json-int) +- speed: rate limit, bytes per second (json-int) +- error: error message (json-string, only on error) + +The completion event is raised both on success and on failure. On +success position is equal to end. On failure position and end can be +used to indicate at which point the operation failed. + +On failure the error field contains a human-readable error message. There are +no semantics other than that streaming has failed and clients should not try +to interpret the error string. + +Examples: + +-> { "execute": "block_stream", "arguments": { "device": "virtio0" } } +<- { "return": {} } + +EQMP + + { .name = "blockdev-snapshot-sync", .args_type = "device:B,snapshot-file:s?,format:s?", .params = "device [new-image-file] [format]",