From f39c1bf8af1313407582f638940d6d52a4d13973 Mon Sep 17 00:00:00 2001 Message-Id: In-Reply-To: References: From: Jeffrey Cody Date: Wed, 17 Oct 2012 05:59:46 +0200 Subject: [PATCH 33/35] QAPI: add command for live block commit, 'block-commit' RH-Author: Jeffrey Cody Message-id: <17be362c347955c993cc911b8a7fc5b26b3de1cf.1350447475.git.jcody@redhat.com> Patchwork-id: 43291 O-Subject: [RHEL6.4 qemu-kvm PATCH v4 33/35] QAPI: add command for live block commit, 'block-commit' Bugzilla: 767233 RH-Acked-by: Paolo Bonzini RH-Acked-by: Eric Blake RH-Acked-by: Kevin Wolf The command for live block commit is added, which has the following arguments: device: the block device to perform the commit on (mandatory) base: the base image to commit into; optional (if not specified, it is the underlying original image) top: the top image of the commit - all data from inside top down to base will be committed into base (mandatory for now; see note, below) speed: maximum speed, in bytes/sec Note: Eventually this command will support merging down the active layer, but that code is not yet complete. If the active layer is passed in as top, then an error will be returned. Once merging down the active layer is supported, the 'top' argument may become optional, and default to the active layer. The is done as a block job, so upon completion a BLOCK_JOB_COMPLETED will be emitted. RHEL-only change: The block commit command is named __com.redhat_block-commit, as opposed to the upstream naming of block-commit. Signed-off-by: Jeff Cody Reviewed-by: Eric Blake Signed-off-by: Kevin Wolf (cherry picked from commit ed61fc10e8c8d2d1287f7edae92e44f5c97c540d) Conflicts: QMP/qmp-events.txt qapi-schema.json qmp-commands.hx --- QMP/qmp-events.txt | 6 ++++-- blockdev.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ qapi-schema.json | 35 ++++++++++++++++++++++++++++++++ qemu-monitor.hx | 7 +++++++ 4 files changed, 104 insertions(+), 2 deletions(-) Signed-off-by: Michal Novotny --- QMP/qmp-events.txt | 6 ++++-- blockdev.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ qapi-schema.json | 35 ++++++++++++++++++++++++++++++++ qemu-monitor.hx | 7 +++++++ 4 files changed, 104 insertions(+), 2 deletions(-) diff --git a/QMP/qmp-events.txt b/QMP/qmp-events.txt index 9042297..8e805a7 100644 --- a/QMP/qmp-events.txt +++ b/QMP/qmp-events.txt @@ -343,7 +343,8 @@ Emitted when a block job has completed. Data: -- "type": Job type ("stream" for image streaming, json-string) +- "type": Job type (json-string; "stream" for image streaming + "commit" for block commit) - "device": Device name (json-string) - "len": Maximum progress value (json-int) - "offset": Current progress value (json-int) @@ -371,7 +372,8 @@ Emitted when a block job has been cancelled. Data: -- "type": Job type ("stream" for image streaming, json-string) +- "type": Job type (json-string; "stream" for image streaming + "commit" for block commit) - "device": Device name (json-string) - "len": Maximum progress value (json-int) - "offset": Current progress value (json-int) diff --git a/blockdev.c b/blockdev.c index f187c90..cbe67c1 100644 --- a/blockdev.c +++ b/blockdev.c @@ -1340,6 +1340,64 @@ int do_block_stream(Monitor *mon, const QDict *params, QObject **ret_data) return 0; } +void qmp___com_redhat_block_commit(const char *device, + bool has_base, const char *base, const char *top, + bool has_speed, int64_t speed, + Error **errp) +{ + BlockDriverState *bs; + BlockDriverState *base_bs, *top_bs; + Error *local_err = NULL; + /* This will be part of the QMP command, if/when the + * BlockdevOnError change for blkmirror makes it in + */ + BlockErrorAction on_error = BLOCK_ERR_REPORT; + + /* drain all i/o before commits */ + bdrv_drain_all(); + + bs = bdrv_find(device); + if (!bs) { + error_set(errp, QERR_DEVICE_NOT_FOUND, device); + return; + } + if (base && has_base) { + base_bs = bdrv_find_backing_image(bs, base); + } else { + base_bs = bdrv_find_base(bs); + } + + if (base_bs == NULL) { + error_set(errp, QERR_BASE_NOT_FOUND, base ? base : "NULL"); + return; + } + + /* default top_bs is the active layer */ + top_bs = bs; + + if (top) { + if (strcmp(bs->filename, top) != 0) { + top_bs = bdrv_find_backing_image(bs, top); + } + } + + if (top_bs == NULL) { + error_set(errp, QERR_TOP_NOT_FOUND, top ? top : "NULL"); + return; + } + + commit_start(bs, base_bs, top_bs, speed, on_error, block_job_cb, bs, + &local_err); + if (local_err != NULL) { + error_propagate(errp, local_err); + return; + } + /* Grab a reference so hotplug does not delete the BlockDriverState from + * underneath us. + */ + drive_get_ref(drive_get_by_blockdev(bs)); +} + static BlockJob *find_block_job(const char *device) { BlockDriverState *bs; diff --git a/qapi-schema.json b/qapi-schema.json index e529c51..18931fb 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -2,6 +2,41 @@ # # QAPI Schema +## +# @__com.redhat_block-commit +# +# Live commit of data from overlay image nodes into backing nodes - i.e., +# writes data between 'top' and 'base' into 'base'. +# +# @device: the name of the device +# +# @base: #optional The file name of the backing image to write data into. +# If not specified, this is the deepest backing image +# +# @top: The file name of the backing image within the image chain, +# which contains the topmost data to be committed down. +# Note, the active layer as 'top' is currently unsupported. +# +# If top == base, that is an error. +# +# +# @speed: #optional the maximum speed, in bytes per second +# +# Returns: Nothing on success +# If commit or stream is already active on this device, DeviceInUse +# If @device does not exist, DeviceNotFound +# If image commit is not supported by this device, NotSupported +# If @base or @top is invalid, a generic error is returned +# If @top is the active layer, or omitted, a generic error is returned +# If @speed is invalid, InvalidParameter +# +# Since: 1.3 +# +## +{ 'command': '__com.redhat_block-commit', + 'data': { 'device': 'str', '*base': 'str', 'top': 'str', + '*speed': 'int' } } + #ifdef CONFIG_LIVE_SNAPSHOTS ## # @NewImageMode diff --git a/qemu-monitor.hx b/qemu-monitor.hx index 112fc5c..05adea9 100644 --- a/qemu-monitor.hx +++ b/qemu-monitor.hx @@ -2263,6 +2263,13 @@ If base does not exist, BaseNotFound EQMP { + .name = "__com.redhat_block-commit", + .args_type = "device:B,base:s?,top:s,speed:o?", + .user_print = monitor_user_noop, + .mhandler.cmd_new = qmp_marshal_input___com_redhat_block_commit, + }, + + { .name = "block-job-set-speed", .args_type = "device:B,speed:o", .params = "device speed", -- 1.7.11.7