From: Paolo Bonzini <pbonzini@redhat.com>
To: Stefan Hajnoczi <stefanha@redhat.com>
Cc: Kevin Wolf <kwolf@redhat.com>,
Markus Armbruster <armbru@redhat.com>,
qemu-devel@nongnu.org, dietmar@proxmox.com
Subject: Re: [Qemu-devel] [RFC 4/8] block: add block_backup QMP command
Date: Thu, 11 Apr 2013 14:32:16 +0200 [thread overview]
Message-ID: <5166AD50.8090507@redhat.com> (raw)
In-Reply-To: <1362867748-30528-5-git-send-email-stefanha@redhat.com>
Il 09/03/2013 23:22, Stefan Hajnoczi ha scritto:
> @block-backup
>
> Start a point-in-time copy of a block device to a new destination.
>
> @device: the name of the device whose writes should be mirrored.
>
> @target: the target of the new image. If the file exists, or if it
> is a device, the existing file/device will be used as the new
> destination. If it does not exist, a new file will be created.
>
> @format: #optional the format of the new destination, default is to
> probe if @mode is 'existing', else the format of the source
>
> @mode: #optional whether and how QEMU should create a new image, default is
> 'absolute-paths'.
>
> @speed: #optional the maximum speed, in bytes per second
>
> Returns: nothing on success
> If @device is not a valid block device, DeviceNotFound
Two features that would be nice to have:
1) a sync mode (full/top/none) like drive-mirror;
2) transaction support to start multiple backups live without stopping
the VM (for use cases that do not include migration)
Thanks,
Paolo
> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
> ---
> blockdev.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> qapi-schema.json | 28 +++++++++++++++++
> qmp-commands.hx | 6 ++++
> 3 files changed, 126 insertions(+)
>
> diff --git a/blockdev.c b/blockdev.c
> index 0e67d06..95a72de 100644
> --- a/blockdev.c
> +++ b/blockdev.c
> @@ -1208,6 +1208,98 @@ void qmp_block_commit(const char *device,
> drive_get_ref(drive_get_by_blockdev(bs));
> }
>
> +void qmp_block_backup(const char *device, const char *target,
> + bool has_format, const char *format,
> + bool has_mode, enum NewImageMode mode,
> + bool has_speed, int64_t speed,
> + Error **errp)
> +{
> + BlockDriverState *bs;
> + BlockDriverState *target_bs;
> + BlockDriver *proto_drv;
> + BlockDriver *drv = NULL;
> + Error *local_err = NULL;
> + int flags;
> + uint64_t size;
> + int ret;
> +
> + if (!has_speed) {
> + speed = 0;
> + }
> + if (!has_mode) {
> + mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS;
> + }
> +
> + bs = bdrv_find(device);
> + if (!bs) {
> + error_set(errp, QERR_DEVICE_NOT_FOUND, device);
> + return;
> + }
> +
> + if (!bdrv_is_inserted(bs)) {
> + error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
> + return;
> + }
> +
> + if (!has_format) {
> + format = mode == NEW_IMAGE_MODE_EXISTING ? NULL : bs->drv->format_name;
> + }
> + if (format) {
> + drv = bdrv_find_format(format);
> + if (!drv) {
> + error_set(errp, QERR_INVALID_BLOCK_FORMAT, format);
> + return;
> + }
> + }
> +
> + if (bdrv_in_use(bs)) {
> + error_set(errp, QERR_DEVICE_IN_USE, device);
> + return;
> + }
> +
> + flags = bs->open_flags | BDRV_O_RDWR;
> +
> + proto_drv = bdrv_find_protocol(target);
> + if (!proto_drv) {
> + error_set(errp, QERR_INVALID_BLOCK_FORMAT, format);
> + return;
> + }
> +
> + bdrv_get_geometry(bs, &size);
> + size *= 512;
> + if (mode != NEW_IMAGE_MODE_EXISTING) {
> + assert(format && drv);
> + bdrv_img_create(target, format,
> + NULL, NULL, NULL, size, flags, &local_err, false);
> + }
> +
> + if (error_is_set(&local_err)) {
> + error_propagate(errp, local_err);
> + return;
> + }
> +
> + target_bs = bdrv_new("");
> + ret = bdrv_open(target_bs, target, flags, drv);
> +
> + if (ret < 0) {
> + bdrv_delete(target_bs);
> + error_set(errp, QERR_OPEN_FILE_FAILED, target);
> + return;
> + }
> +
> + backup_start(bs, target_bs, speed, block_job_cb, bs, &local_err);
> + if (local_err != NULL) {
> + bdrv_delete(target_bs);
> + 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));
> +}
> +
> #define DEFAULT_MIRROR_BUF_SIZE (10 << 20)
>
> void qmp_drive_mirror(const char *device, const char *target,
> diff --git a/qapi-schema.json b/qapi-schema.json
> index 6b64aec..1dbf7b5 100644
> --- a/qapi-schema.json
> +++ b/qapi-schema.json
> @@ -1716,6 +1716,34 @@
> '*speed': 'int' } }
>
> ##
> +# @block-backup
> +#
> +# Start a point-in-time copy of a block device to a new destination.
> +#
> +# @device: the name of the device whose writes should be mirrored.
> +#
> +# @target: the target of the new image. If the file exists, or if it
> +# is a device, the existing file/device will be used as the new
> +# destination. If it does not exist, a new file will be created.
> +#
> +# @format: #optional the format of the new destination, default is to
> +# probe if @mode is 'existing', else the format of the source
> +#
> +# @mode: #optional whether and how QEMU should create a new image, default is
> +# 'absolute-paths'.
> +#
> +# @speed: #optional the maximum speed, in bytes per second
> +#
> +# Returns: nothing on success
> +# If @device is not a valid block device, DeviceNotFound
> +#
> +# Since 1.5
> +##
> +{ 'command': 'block-backup',
> + 'data': { 'device': 'str', 'target': 'str', '*format': 'str',
> + '*mode': 'NewImageMode', '*speed': 'int' } }
> +
> +##
> # @drive-mirror
> #
> # Start mirroring a block device's writes to a new destination.
> diff --git a/qmp-commands.hx b/qmp-commands.hx
> index 95022e2..bda8eb4 100644
> --- a/qmp-commands.hx
> +++ b/qmp-commands.hx
> @@ -889,6 +889,12 @@ EQMP
> },
>
> {
> + .name = "block-backup",
> + .args_type = "device:B,target:s,speed:i?,mode:s?,format:s?",
> + .mhandler.cmd_new = qmp_marshal_input_block_backup,
> + },
> +
> + {
> .name = "block-job-set-speed",
> .args_type = "device:B,speed:o",
> .mhandler.cmd_new = qmp_marshal_input_block_job_set_speed,
>
next prev parent reply other threads:[~2013-04-11 12:32 UTC|newest]
Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-03-09 22:22 [Qemu-devel] [RFC 0/8] block: Live backup prototype Stefan Hajnoczi
2013-03-09 22:22 ` [Qemu-devel] [RFC 1/8] block: add virtual_size to query-block QMP output Stefan Hajnoczi
2013-03-11 17:35 ` Eric Blake
2013-03-09 22:22 ` [Qemu-devel] [RFC 2/8] add basic backup support to block driver Stefan Hajnoczi
2013-03-09 22:22 ` [Qemu-devel] [RFC 3/8] backup: write to BlockDriverState instead of BackupDumpFunc Stefan Hajnoczi
2013-03-10 10:05 ` Dietmar Maurer
2013-03-10 11:13 ` Stefan Hajnoczi
2013-03-09 22:22 ` [Qemu-devel] [RFC 4/8] block: add block_backup QMP command Stefan Hajnoczi
2013-03-14 21:46 ` Eric Blake
2013-03-14 21:52 ` Eric Blake
2013-03-15 8:38 ` Stefan Hajnoczi
2013-04-11 12:32 ` Paolo Bonzini [this message]
2013-03-09 22:22 ` [Qemu-devel] [RFC 5/8] Add nbd server Python module Stefan Hajnoczi
2013-03-09 22:22 ` [Qemu-devel] [RFC 6/8] Add VMA backup archive writer " Stefan Hajnoczi
2013-03-09 22:22 ` [Qemu-devel] [RFC 7/8] Add vma-writer.py tool Stefan Hajnoczi
2013-03-09 22:22 ` [Qemu-devel] [RFC 8/8] Add backup.py tool Stefan Hajnoczi
2013-03-10 9:14 ` [Qemu-devel] [RFC 0/8] block: Live backup prototype Dietmar Maurer
2013-03-10 10:19 ` Stefan Hajnoczi
2013-03-10 10:38 ` Dietmar Maurer
2013-03-10 11:09 ` Stefan Hajnoczi
2013-03-10 10:50 ` Dietmar Maurer
2013-03-10 11:10 ` Stefan Hajnoczi
2013-03-11 8:58 ` Dietmar Maurer
2013-03-11 9:26 ` Dietmar Maurer
2013-03-11 14:27 ` Stefan Hajnoczi
2013-03-11 15:00 ` Dietmar Maurer
2013-03-11 17:11 ` Stefan Hajnoczi
2013-03-10 9:57 ` Dietmar Maurer
2013-03-10 10:41 ` Stefan Hajnoczi
2013-03-12 9:18 ` Kevin Wolf
2013-03-12 10:50 ` Stefan Hajnoczi
2013-03-12 11:15 ` Dietmar Maurer
2013-03-12 12:18 ` Stefan Hajnoczi
2013-03-12 11:22 ` Kevin Wolf
2013-03-12 11:31 ` Dietmar Maurer
2013-03-12 11:37 ` Dietmar Maurer
2013-03-12 12:17 ` Stefan Hajnoczi
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=5166AD50.8090507@redhat.com \
--to=pbonzini@redhat.com \
--cc=armbru@redhat.com \
--cc=dietmar@proxmox.com \
--cc=kwolf@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@redhat.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.