* [Qemu-devel] [RFC PATCH v3 0/2] Point-in-time snapshot exporting over NBD @ 2013-10-17 5:36 Fam Zheng 2013-10-17 5:36 ` [Qemu-devel] [RFC PATCH v3 1/2] block: parse "backing" option to reference existing BDS Fam Zheng ` (2 more replies) 0 siblings, 3 replies; 8+ messages in thread From: Fam Zheng @ 2013-10-17 5:36 UTC (permalink / raw) To: qemu-devel; +Cc: kwolf, hbrock, rjones, imain, stefanha, pbonzini This series adds for point-in-time snapshot NBD exporting based on blockdev-backup (variant of drive-backup with existing device as target). We get a thin point-in-time snapshot by COW mechanism of drive-backup, and export it through built in NBD server. The steps are as below: 1. (SHELL) qemu-img create -f qcow2 BACKUP.qcow2 <source size here> (Alternatively we can use -o backing_file=RUNNING-VM.img to omit explicitly providing the size by ourselves, but it's risky because RUNNING-VM.qcow2 is used r/w by guest. Whether or not setting backing file in the image file doesn't matter, as we are going to override the backing hd in the next step) 2. (QMP) blockdev-add backing=source-drive file.driver=file file.filename=BACKUP.qcow2 id=target0 if=none driver=qcow2 (where ide0-hd0 is the running BlockDriverState name for RUNNING-VM.img. This patch implements "backing=" option to override backing_hd for added drive) 3. (QMP) blockdev-backup device=source-drive sync=none target=target0 (this is the QMP command introduced by this series, which use a named device as target of drive-backup) 4. (QMP) nbd-server-add device=target0 When image fleecing done: 1. (QMP) block-job-complete device=ide0-hd0 2. (HMP) drive_del target0 3. (SHELL) rm BACKUP.qcow2 v3: Base on blockdev-add. The syntax blockdev-add backing=<id> is new: This will make referenced BDS in the middle of a backing chain, which has significant effects over all existing block operations in QMP. It needs to be reviewed and tested carefully. I'm listing the commands here that can take a device id as parameter (but may not be complete). These commands do not mutate the backing chain (not directly, at least) and should be safe: block_passwd block_set_io_throttle block-job-set-speed block-job-cancel block-job-pause block-job-resume block-job-complete drive-backup blockdev-snapshot-sync blockdev-snapshot-internal-sync blockdev-snapshot-delete-internal-sync: These should be safe. nbd-server-add These can mutates the chain (removing, closing or swapping BDS), need more work to convert them to safe operations with a BDS in the middle. device_del eject: it does bdrv_close the device. change: internally calls eject. block-commit: it deletes intermediate BDSes, which may include other named BDS. block-stream: drive-mirror: it swaps active with target when complete. Resizing a middle BDS need to be reviewed too: block_resize: TBD. Adding and backing HD referencing will put other BDS in middle, but should not immediately break things: blockdev-add Fam Zheng (2): block: parse "backing" option to reference existing BDS qmp: add command 'blockdev-backup' block.c | 27 +++++++++++++++++++----- blockdev.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ qapi-schema.json | 49 +++++++++++++++++++++++++++++++++++++++++++ qmp-commands.hx | 46 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 180 insertions(+), 5 deletions(-) -- 1.8.3.1 ^ permalink raw reply [flat|nested] 8+ messages in thread
* [Qemu-devel] [RFC PATCH v3 1/2] block: parse "backing" option to reference existing BDS 2013-10-17 5:36 [Qemu-devel] [RFC PATCH v3 0/2] Point-in-time snapshot exporting over NBD Fam Zheng @ 2013-10-17 5:36 ` Fam Zheng 2013-10-18 10:04 ` Fam Zheng 2013-10-17 5:36 ` [Qemu-devel] [RFC PATCH v3 2/2] qmp: add command 'blockdev-backup' Fam Zheng 2013-11-20 2:32 ` [Qemu-devel] [RFC PATCH v3 0/2] Point-in-time snapshot exporting over NBD Ian Main 2 siblings, 1 reply; 8+ messages in thread From: Fam Zheng @ 2013-10-17 5:36 UTC (permalink / raw) To: qemu-devel; +Cc: kwolf, hbrock, rjones, imain, stefanha, pbonzini Signed-off-by: Fam Zheng <famz@redhat.com> --- block.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/block.c b/block.c index fd05a80..38b3e80 100644 --- a/block.c +++ b/block.c @@ -1158,11 +1158,28 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options, /* If there is a backing file, use it */ if ((flags & BDRV_O_NO_BACKING) == 0) { QDict *backing_options; - - qdict_extract_subqdict(options, &backing_options, "backing."); - ret = bdrv_open_backing_file(bs, backing_options, &local_err); - if (ret < 0) { - goto close_and_fail; + const char *backing_bs; + + backing_bs = qdict_get_try_str(options, "backing"); + if (backing_bs) { + bs->backing_hd = bdrv_find(backing_bs); + bdrv_ref(bs->backing_hd); + qdict_del(options, "backing"); + if (bs->backing_hd) { + pstrcpy(bs->backing_file, sizeof(bs->backing_file), + bs->backing_hd->filename); + pstrcpy(bs->backing_format, sizeof(bs->backing_format), + bs->backing_hd->drv->format_name); + } else { + error_setg(errp, "Backing device not found: %s", backing_bs); + goto close_and_fail; + } + } else { + qdict_extract_subqdict(options, &backing_options, "backing."); + ret = bdrv_open_backing_file(bs, backing_options, &local_err); + if (ret < 0) { + goto close_and_fail; + } } } -- 1.8.3.1 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] [RFC PATCH v3 1/2] block: parse "backing" option to reference existing BDS 2013-10-17 5:36 ` [Qemu-devel] [RFC PATCH v3 1/2] block: parse "backing" option to reference existing BDS Fam Zheng @ 2013-10-18 10:04 ` Fam Zheng 0 siblings, 0 replies; 8+ messages in thread From: Fam Zheng @ 2013-10-18 10:04 UTC (permalink / raw) To: qemu-devel; +Cc: kwolf, hbrock, rjones, imain, stefanha, pbonzini On Thu, 10/17 13:36, Fam Zheng wrote: > Signed-off-by: Fam Zheng <famz@redhat.com> > --- > block.c | 27 ++++++++++++++++++++++----- > 1 file changed, 22 insertions(+), 5 deletions(-) > > diff --git a/block.c b/block.c > index fd05a80..38b3e80 100644 > --- a/block.c > +++ b/block.c > @@ -1158,11 +1158,28 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options, > /* If there is a backing file, use it */ > if ((flags & BDRV_O_NO_BACKING) == 0) { > QDict *backing_options; > - > - qdict_extract_subqdict(options, &backing_options, "backing."); > - ret = bdrv_open_backing_file(bs, backing_options, &local_err); > - if (ret < 0) { > - goto close_and_fail; > + const char *backing_bs; > + > + backing_bs = qdict_get_try_str(options, "backing"); > + if (backing_bs) { > + bs->backing_hd = bdrv_find(backing_bs); > + bdrv_ref(bs->backing_hd); This should be moved down into if. Fam > + qdict_del(options, "backing"); > + if (bs->backing_hd) { > + pstrcpy(bs->backing_file, sizeof(bs->backing_file), > + bs->backing_hd->filename); > + pstrcpy(bs->backing_format, sizeof(bs->backing_format), > + bs->backing_hd->drv->format_name); > + } else { > + error_setg(errp, "Backing device not found: %s", backing_bs); > + goto close_and_fail; > + } > + } else { > + qdict_extract_subqdict(options, &backing_options, "backing."); > + ret = bdrv_open_backing_file(bs, backing_options, &local_err); > + if (ret < 0) { > + goto close_and_fail; > + } > } > } > > -- > 1.8.3.1 > > ^ permalink raw reply [flat|nested] 8+ messages in thread
* [Qemu-devel] [RFC PATCH v3 2/2] qmp: add command 'blockdev-backup' 2013-10-17 5:36 [Qemu-devel] [RFC PATCH v3 0/2] Point-in-time snapshot exporting over NBD Fam Zheng 2013-10-17 5:36 ` [Qemu-devel] [RFC PATCH v3 1/2] block: parse "backing" option to reference existing BDS Fam Zheng @ 2013-10-17 5:36 ` Fam Zheng 2013-10-18 9:54 ` Paolo Bonzini 2013-11-20 2:32 ` [Qemu-devel] [RFC PATCH v3 0/2] Point-in-time snapshot exporting over NBD Ian Main 2 siblings, 1 reply; 8+ messages in thread From: Fam Zheng @ 2013-10-17 5:36 UTC (permalink / raw) To: qemu-devel; +Cc: kwolf, hbrock, rjones, imain, stefanha, pbonzini Similar to drive-backup, but this command uses a device id as target instead of creating/opening an image file. Signed-off-by: Fam Zheng <famz@redhat.com> --- blockdev.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ qapi-schema.json | 49 +++++++++++++++++++++++++++++++++++++++++++ qmp-commands.hx | 46 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 158 insertions(+) diff --git a/blockdev.c b/blockdev.c index 4f76e28..c53d597 100644 --- a/blockdev.c +++ b/blockdev.c @@ -1937,6 +1937,69 @@ void qmp_drive_backup(const char *device, const char *target, } } +void qmp_blockdev_backup(const char *device, const char *target, + enum MirrorSyncMode sync, + bool has_speed, int64_t speed, + bool has_on_source_error, + BlockdevOnError on_source_error, + bool has_on_target_error, + BlockdevOnError on_target_error, + Error **errp) +{ + BlockDriverState *bs; + BlockDriverState *target_bs; + Error *local_err = NULL; + + if (!has_speed) { + speed = 0; + } + if (!has_on_source_error) { + on_source_error = BLOCKDEV_ON_ERROR_REPORT; + } + if (!has_on_target_error) { + on_target_error = BLOCKDEV_ON_ERROR_REPORT; + } + + 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 (bdrv_in_use(bs)) { + error_set(errp, QERR_DEVICE_IN_USE, device); + return; + } + + target_bs = bdrv_find(target); + if (!target_bs) { + error_set(errp, QERR_DEVICE_NOT_FOUND, target); + return; + } + + if (!bdrv_is_inserted(target_bs)) { + error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, target); + return; + } + + if (bdrv_in_use(target_bs)) { + error_set(errp, QERR_DEVICE_IN_USE, target); + return; + } + + bdrv_ref(target_bs); + backup_start(bs, target_bs, speed, sync, on_source_error, on_target_error, + block_job_cb, bs, &local_err); + if (local_err != NULL) { + error_propagate(errp, local_err); + } +} + #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 60f3fd1..89bc510 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -1794,6 +1794,40 @@ '*on-target-error': 'BlockdevOnError' } } ## +# @BlockdevBackup +# +# @device: the name of the device which should be copied. +# +# @target: the name of the backup target device +# +# @sync: what parts of the disk image should be copied to the destination +# (all the disk, only the sectors allocated in the topmost image, or +# only new I/O). +# +# @speed: #optional the maximum speed, in bytes per second +# +# @on-source-error: #optional the action to take on an error on the source, +# default 'report'. 'stop' and 'enospc' can only be used +# if the block device supports io-status (see BlockInfo). +# +# @on-target-error: #optional the action to take on an error on the target, +# default 'report' (no limitations, since this applies to +# a different block device than @device). +# +# Note that @on-source-error and @on-target-error only affect background I/O. +# If an error occurs during a guest write request, the device's rerror/werror +# actions will be used. +# +# Since: 1.7 +## +{ 'type': 'BlockdevBackup', + 'data': { 'device': 'str', 'target': 'str', + 'sync': 'MirrorSyncMode', + '*speed': 'int', + '*on-source-error': 'BlockdevOnError', + '*on-target-error': 'BlockdevOnError' } } + +## # @Abort # # This action can be used to test transaction failure. @@ -1983,6 +2017,21 @@ { 'command': 'drive-backup', 'data': 'DriveBackup' } ## +# @blockdev-backup +# +# Block device version for drive-backup command. Use existing device as target +# of backup. +# +# For the arguments, see the documentation of BlockdevBackup. +# +# Returns: nothing on success +# If @device or @target is not a valid block device, DeviceNotFound +# +# Since 1.7 +## +{ 'command': 'blockdev-backup', 'data': 'BlockdevBackup' } + +## # @drive-mirror # # Start mirroring a block device's writes to a new destination. diff --git a/qmp-commands.hx b/qmp-commands.hx index fba15cd..4116a8d 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -963,6 +963,52 @@ Example: "sync": "full", "target": "backup.img" } } <- { "return": {} } + +EQMP + + { + .name = "blockdev-backup", + .args_type = "sync:s,device:B,target:B,speed:i?," + "on-source-error:s?,on-target-error:s?", + .mhandler.cmd_new = qmp_marshal_input_blockdev_backup, + }, + +SQMP +blockdev-backup +------------ + +The device version of drive-backup: this command takes a existing named device +as backup target. + +Arguments: + +- "device": the name of the device which should be copied. + (json-string) +- "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. + (json-string) +- "sync": what parts of the disk image should be copied to the destination; + possibilities include "full" for all the disk, "top" for only the sectors + allocated in the topmost image, or "none" to only replicate new I/O + (MirrorSyncMode). +- "mode": whether and how QEMU should create a new image + (NewImageMode, optional, default 'absolute-paths') +- "speed": the maximum speed, in bytes per second (json-int, optional) +- "on-source-error": the action to take on an error on the source, default + 'report'. 'stop' and 'enospc' can only be used + if the block device supports io-status. + (BlockdevOnError, optional) +- "on-target-error": the action to take on an error on the target, default + 'report' (no limitations, since this applies to + a different block device than device). + (BlockdevOnError, optional) + +Example: +-> { "execute": "blockdev-backup", "arguments": { "device": "src-id", + "target": "tgt-id" } } +<- { "return": {} } + EQMP { -- 1.8.3.1 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] [RFC PATCH v3 2/2] qmp: add command 'blockdev-backup' 2013-10-17 5:36 ` [Qemu-devel] [RFC PATCH v3 2/2] qmp: add command 'blockdev-backup' Fam Zheng @ 2013-10-18 9:54 ` Paolo Bonzini 0 siblings, 0 replies; 8+ messages in thread From: Paolo Bonzini @ 2013-10-18 9:54 UTC (permalink / raw) To: Fam Zheng; +Cc: kwolf, hbrock, qemu-devel, rjones, imain, stefanha Il 17/10/2013 07:36, Fam Zheng ha scritto: > Similar to drive-backup, but this command uses a device id as target > instead of creating/opening an image file. > > Signed-off-by: Fam Zheng <famz@redhat.com> > --- > blockdev.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > qapi-schema.json | 49 +++++++++++++++++++++++++++++++++++++++++++ > qmp-commands.hx | 46 +++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 158 insertions(+) > > diff --git a/blockdev.c b/blockdev.c > index 4f76e28..c53d597 100644 > --- a/blockdev.c > +++ b/blockdev.c > @@ -1937,6 +1937,69 @@ void qmp_drive_backup(const char *device, const char *target, > } > } > > +void qmp_blockdev_backup(const char *device, const char *target, > + enum MirrorSyncMode sync, > + bool has_speed, int64_t speed, > + bool has_on_source_error, > + BlockdevOnError on_source_error, > + bool has_on_target_error, > + BlockdevOnError on_target_error, > + Error **errp) > +{ > + BlockDriverState *bs; > + BlockDriverState *target_bs; > + Error *local_err = NULL; > + > + if (!has_speed) { > + speed = 0; > + } > + if (!has_on_source_error) { > + on_source_error = BLOCKDEV_ON_ERROR_REPORT; > + } > + if (!has_on_target_error) { > + on_target_error = BLOCKDEV_ON_ERROR_REPORT; > + } > + > + 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 (bdrv_in_use(bs)) { > + error_set(errp, QERR_DEVICE_IN_USE, device); > + return; > + } Should these two checks be moved to backup_start? > + target_bs = bdrv_find(target); > + if (!target_bs) { > + error_set(errp, QERR_DEVICE_NOT_FOUND, target); > + return; > + } > + > + if (!bdrv_is_inserted(target_bs)) { > + error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, target); > + return; > + } > + > + if (bdrv_in_use(target_bs)) { > + error_set(errp, QERR_DEVICE_IN_USE, target); > + return; > + } Same for these two. > + bdrv_ref(target_bs); > + backup_start(bs, target_bs, speed, sync, on_source_error, on_target_error, > + block_job_cb, bs, &local_err); > + if (local_err != NULL) { > + error_propagate(errp, local_err); Missing bdrv_unref. Otherwise looks good! Paolo > + } > +} > + > #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 60f3fd1..89bc510 100644 > --- a/qapi-schema.json > +++ b/qapi-schema.json > @@ -1794,6 +1794,40 @@ > '*on-target-error': 'BlockdevOnError' } } > > ## > +# @BlockdevBackup > +# > +# @device: the name of the device which should be copied. > +# > +# @target: the name of the backup target device > +# > +# @sync: what parts of the disk image should be copied to the destination > +# (all the disk, only the sectors allocated in the topmost image, or > +# only new I/O). > +# > +# @speed: #optional the maximum speed, in bytes per second > +# > +# @on-source-error: #optional the action to take on an error on the source, > +# default 'report'. 'stop' and 'enospc' can only be used > +# if the block device supports io-status (see BlockInfo). > +# > +# @on-target-error: #optional the action to take on an error on the target, > +# default 'report' (no limitations, since this applies to > +# a different block device than @device). > +# > +# Note that @on-source-error and @on-target-error only affect background I/O. > +# If an error occurs during a guest write request, the device's rerror/werror > +# actions will be used. > +# > +# Since: 1.7 > +## > +{ 'type': 'BlockdevBackup', > + 'data': { 'device': 'str', 'target': 'str', > + 'sync': 'MirrorSyncMode', > + '*speed': 'int', > + '*on-source-error': 'BlockdevOnError', > + '*on-target-error': 'BlockdevOnError' } } > + > +## > # @Abort > # > # This action can be used to test transaction failure. > @@ -1983,6 +2017,21 @@ > { 'command': 'drive-backup', 'data': 'DriveBackup' } > > ## > +# @blockdev-backup > +# > +# Block device version for drive-backup command. Use existing device as target > +# of backup. > +# > +# For the arguments, see the documentation of BlockdevBackup. > +# > +# Returns: nothing on success > +# If @device or @target is not a valid block device, DeviceNotFound > +# > +# Since 1.7 > +## > +{ 'command': 'blockdev-backup', 'data': 'BlockdevBackup' } > + > +## > # @drive-mirror > # > # Start mirroring a block device's writes to a new destination. > diff --git a/qmp-commands.hx b/qmp-commands.hx > index fba15cd..4116a8d 100644 > --- a/qmp-commands.hx > +++ b/qmp-commands.hx > @@ -963,6 +963,52 @@ Example: > "sync": "full", > "target": "backup.img" } } > <- { "return": {} } > + > +EQMP > + > + { > + .name = "blockdev-backup", > + .args_type = "sync:s,device:B,target:B,speed:i?," > + "on-source-error:s?,on-target-error:s?", > + .mhandler.cmd_new = qmp_marshal_input_blockdev_backup, > + }, > + > +SQMP > +blockdev-backup > +------------ > + > +The device version of drive-backup: this command takes a existing named device > +as backup target. > + > +Arguments: > + > +- "device": the name of the device which should be copied. > + (json-string) > +- "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. > + (json-string) > +- "sync": what parts of the disk image should be copied to the destination; > + possibilities include "full" for all the disk, "top" for only the sectors > + allocated in the topmost image, or "none" to only replicate new I/O > + (MirrorSyncMode). > +- "mode": whether and how QEMU should create a new image > + (NewImageMode, optional, default 'absolute-paths') > +- "speed": the maximum speed, in bytes per second (json-int, optional) > +- "on-source-error": the action to take on an error on the source, default > + 'report'. 'stop' and 'enospc' can only be used > + if the block device supports io-status. > + (BlockdevOnError, optional) > +- "on-target-error": the action to take on an error on the target, default > + 'report' (no limitations, since this applies to > + a different block device than device). > + (BlockdevOnError, optional) > + > +Example: > +-> { "execute": "blockdev-backup", "arguments": { "device": "src-id", > + "target": "tgt-id" } } > +<- { "return": {} } > + > EQMP > > { > ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] [RFC PATCH v3 0/2] Point-in-time snapshot exporting over NBD 2013-10-17 5:36 [Qemu-devel] [RFC PATCH v3 0/2] Point-in-time snapshot exporting over NBD Fam Zheng 2013-10-17 5:36 ` [Qemu-devel] [RFC PATCH v3 1/2] block: parse "backing" option to reference existing BDS Fam Zheng 2013-10-17 5:36 ` [Qemu-devel] [RFC PATCH v3 2/2] qmp: add command 'blockdev-backup' Fam Zheng @ 2013-11-20 2:32 ` Ian Main 2013-11-22 5:47 ` Fam Zheng 2 siblings, 1 reply; 8+ messages in thread From: Ian Main @ 2013-11-20 2:32 UTC (permalink / raw) To: Fam Zheng; +Cc: kwolf, hbrock, qemu-devel, rjones, stefanha, pbonzini On Thu, Oct 17, 2013 at 01:36:41PM +0800, Fam Zheng wrote: > This series adds for point-in-time snapshot NBD exporting based on > blockdev-backup (variant of drive-backup with existing device as target). In general this seems to work great. I did a bunch of testing and was able to mount filesystems over NBD, do many writes (on backed up image)/reads (on target), intense IO etc and all held up fine. There are definitely some issues with some of the commands allowing you to blow things up. I'm interested to hear opinions on whether this is a showstopper at this time or not. > We get a thin point-in-time snapshot by COW mechanism of drive-backup, and > export it through built in NBD server. The steps are as below: > > 1. (SHELL) qemu-img create -f qcow2 BACKUP.qcow2 <source size here> > > (Alternatively we can use -o backing_file=RUNNING-VM.img to omit explicitly > providing the size by ourselves, but it's risky because RUNNING-VM.qcow2 is > used r/w by guest. Whether or not setting backing file in the image file > doesn't matter, as we are going to override the backing hd in the next > step) > > 2. (QMP) blockdev-add backing=source-drive file.driver=file file.filename=BACKUP.qcow2 id=target0 if=none driver=qcow2 I had to create a custom python script to make these commands work as they require nested dicts. Is that normal or did I miss something entirely? > (where ide0-hd0 is the running BlockDriverState name for > RUNNING-VM.img. This patch implements "backing=" option to override > backing_hd for added drive) > > 3. (QMP) blockdev-backup device=source-drive sync=none target=target0 > > (this is the QMP command introduced by this series, which use a named > device as target of drive-backup) > > 4. (QMP) nbd-server-add device=target0 > > When image fleecing done: > > 1. (QMP) block-job-complete device=ide0-hd0 To be clear it is block-job-cancel that is used. There is no 'complete' handler for the backup block job so this just returns an error. > 2. (HMP) drive_del target0 In order for this to work with libvirt I think we are going to need a QMP interface for this. > 3. (SHELL) rm BACKUP.qcow2 > > v3: Base on blockdev-add. > The syntax blockdev-add backing=<id> is new: This will make referenced BDS > in the middle of a backing chain, which has significant effects over all > existing block operations in QMP. It needs to be reviewed and tested carefully. > > I'm listing the commands here that can take a device id as parameter (but > may not be complete). > > These commands do not mutate the backing chain (not directly, at least) and > should be safe: > block_passwd > block_set_io_throttle > block-job-set-speed > block-job-cancel > block-job-pause > block-job-resume > block-job-complete > drive-backup > blockdev-snapshot-sync > blockdev-snapshot-internal-sync > blockdev-snapshot-delete-internal-sync: These should be safe. > nbd-server-add > > These can mutates the chain (removing, closing or swapping BDS), need more > work to convert them to safe operations with a BDS in the middle. > device_del I couldn't figure out how to make this operate on block devices or how to make it break things.. :) > eject: it does bdrv_close the device. > change: internally calls eject. Calling eject or change on the target causes a 'failed command: WRITE DMA' backtrace in the VM which causes the root fs to be remounted read only. I'm guessing from the CoW failing.. > block-commit: it deletes intermediate BDSes, which may include other named BDS. > block-stream: > drive-mirror: it swaps active with target when complete. Doing a mirror of the target causes a segfault when completed.. :) I gather you are not allowed to perform multiple block jobs on 1 BDS at a time as I get 'in use' errors when trying to do the same BDS as the one you are backing up. Doing a drive-mirror on the bottom-most image of 3 seemed to work ok. > Resizing a middle BDS need to be reviewed too: > block_resize: TBD. I tried resizing a middle BDS and got a 'middle0 is in use' error. The topmost BDS got a 'feature/command not supported' error. I was able to resize the bottom BDS and then got I/O errors, eg: {u'timestamp': {u'seconds': 1384913492, u'microseconds': 993397}, u'data': {u'device': u'ide0-hd0', u'action': u'report', u'operation': u'read'}, u'event': u'BLOCK_IO_ERROR'} However the NBD export *seemed* to be ok and everything kept running.. > Adding and backing HD referencing will put other BDS in middle, but should > not immediately break things: > blockdev-add Not quite sure what you mean here. I can add other BDS's but could I put one in the middle while in a backup? That would require being able to change the 'backing' on the fly which I don't think we can do? (or should be able to do.. heh). > Fam Zheng (2): > block: parse "backing" option to reference existing BDS > qmp: add command 'blockdev-backup' > > block.c | 27 +++++++++++++++++++----- > blockdev.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > qapi-schema.json | 49 +++++++++++++++++++++++++++++++++++++++++++ > qmp-commands.hx | 46 +++++++++++++++++++++++++++++++++++++++++ > 4 files changed, 180 insertions(+), 5 deletions(-) > > -- > 1.8.3.1 > ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] [RFC PATCH v3 0/2] Point-in-time snapshot exporting over NBD 2013-11-20 2:32 ` [Qemu-devel] [RFC PATCH v3 0/2] Point-in-time snapshot exporting over NBD Ian Main @ 2013-11-22 5:47 ` Fam Zheng 2013-11-22 20:11 ` Ian Main 0 siblings, 1 reply; 8+ messages in thread From: Fam Zheng @ 2013-11-22 5:47 UTC (permalink / raw) To: Ian Main; +Cc: kwolf, hbrock, qemu-devel, rjones, stefanha, pbonzini On 2013年11月20日 10:32, Ian Main wrote: > On Thu, Oct 17, 2013 at 01:36:41PM +0800, Fam Zheng wrote: >> This series adds for point-in-time snapshot NBD exporting based on >> blockdev-backup (variant of drive-backup with existing device as target). > > In general this seems to work great. I did a bunch of testing and was > able to mount filesystems over NBD, do many writes (on backed up > image)/reads (on target), intense IO etc and all held up fine. > > There are definitely some issues with some of the commands allowing you > to blow things up. I'm interested to hear opinions on whether this is a > showstopper at this time or not. > Thanks very much for your testing, Ian. QEMU should report error instead of crashing with invalid operations. I added an "operation blocker" and incorporated into the next version. In the future, we still want to review more on those commands and try to enable safe ones, and possibly also allow multiple block jobs on a BDS. For now it is good enough to only allow blockdev-backup on the source and NBD export on the target (which is safe, and all what we need for image fleecing, as this version shows). With that being a working implementation, I've posted v4. Please test and free to make comments. >> We get a thin point-in-time snapshot by COW mechanism of drive-backup, and >> export it through built in NBD server. The steps are as below: >> >> 1. (SHELL) qemu-img create -f qcow2 BACKUP.qcow2 <source size here> >> >> (Alternatively we can use -o backing_file=RUNNING-VM.img to omit explicitly >> providing the size by ourselves, but it's risky because RUNNING-VM.qcow2 is >> used r/w by guest. Whether or not setting backing file in the image file >> doesn't matter, as we are going to override the backing hd in the next >> step) >> >> 2. (QMP) blockdev-add backing=source-drive file.driver=file file.filename=BACKUP.qcow2 id=target0 if=none driver=qcow2 > > I had to create a custom python script to make these commands work as > they require nested dicts. Is that normal or did I miss something > entirely? > Yes, I use a python script locally to test it too. Fam ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] [RFC PATCH v3 0/2] Point-in-time snapshot exporting over NBD 2013-11-22 5:47 ` Fam Zheng @ 2013-11-22 20:11 ` Ian Main 0 siblings, 0 replies; 8+ messages in thread From: Ian Main @ 2013-11-22 20:11 UTC (permalink / raw) To: Fam Zheng; +Cc: kwolf, hbrock, qemu-devel, rjones, stefanha, pbonzini On Fri, Nov 22, 2013 at 01:47:26PM +0800, Fam Zheng wrote: > On 2013年11月20日 10:32, Ian Main wrote: > >On Thu, Oct 17, 2013 at 01:36:41PM +0800, Fam Zheng wrote: > >>This series adds for point-in-time snapshot NBD exporting based on > >>blockdev-backup (variant of drive-backup with existing device as target). > > > >In general this seems to work great. I did a bunch of testing and was > >able to mount filesystems over NBD, do many writes (on backed up > >image)/reads (on target), intense IO etc and all held up fine. > > > >There are definitely some issues with some of the commands allowing you > >to blow things up. I'm interested to hear opinions on whether this is a > >showstopper at this time or not. > > > > Thanks very much for your testing, Ian. QEMU should report error > instead of crashing with invalid operations. I added an "operation > blocker" and incorporated into the next version. > > In the future, we still want to review more on those commands and > try to enable safe ones, and possibly also allow multiple block jobs > on a BDS. For now it is good enough to only allow blockdev-backup on > the source and NBD export on the target (which is safe, and all what > we need for image fleecing, as this version shows). With that being > a working implementation, I've posted v4. Please test and free to > make comments. That's great. Interesting solution you have come up with. I will give it a try and let you know how it goes. > >>We get a thin point-in-time snapshot by COW mechanism of drive-backup, and > >>export it through built in NBD server. The steps are as below: > >> > >> 1. (SHELL) qemu-img create -f qcow2 BACKUP.qcow2 <source size here> > >> > >> (Alternatively we can use -o backing_file=RUNNING-VM.img to omit explicitly > >> providing the size by ourselves, but it's risky because RUNNING-VM.qcow2 is > >> used r/w by guest. Whether or not setting backing file in the image file > >> doesn't matter, as we are going to override the backing hd in the next > >> step) > >> > >> 2. (QMP) blockdev-add backing=source-drive file.driver=file file.filename=BACKUP.qcow2 id=target0 if=none driver=qcow2 > > > >I had to create a custom python script to make these commands work as > >they require nested dicts. Is that normal or did I miss something > >entirely? > > > > Yes, I use a python script locally to test it too. I like your notation.. I might try to make a patch for qmp/qmp-shell to allow it to create nested dicts using the dot notation. Ian ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2013-11-22 20:11 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2013-10-17 5:36 [Qemu-devel] [RFC PATCH v3 0/2] Point-in-time snapshot exporting over NBD Fam Zheng 2013-10-17 5:36 ` [Qemu-devel] [RFC PATCH v3 1/2] block: parse "backing" option to reference existing BDS Fam Zheng 2013-10-18 10:04 ` Fam Zheng 2013-10-17 5:36 ` [Qemu-devel] [RFC PATCH v3 2/2] qmp: add command 'blockdev-backup' Fam Zheng 2013-10-18 9:54 ` Paolo Bonzini 2013-11-20 2:32 ` [Qemu-devel] [RFC PATCH v3 0/2] Point-in-time snapshot exporting over NBD Ian Main 2013-11-22 5:47 ` Fam Zheng 2013-11-22 20:11 ` Ian Main
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).