block: Add status callback to bdrv_amend_options()
Depending on the changed options and the image format, bdrv_amend_options() may take a significant amount of time. In these cases, a way to be informed about the operation's status is desirable. Since the operation is rather complex and may fundamentally change the image, implementing it as AIO or a coroutine does not seem feasible. On the other hand, implementing it as a block job would be significantly more difficult than a simple callback and would not add benefits other than progress report to the amending operation, because it should not actually be run as a block job at all. A callback may not be very pretty, but it's very easy to implement and perfectly fits its purpose here. Signed-off-by: Max Reitz <mreitz@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Benoît Canet <benoit.canet@nodalink.com> Reviewed-by: Kevin Wolf <kwolf@redhat.com> Message-id: 1414404776-4919-2-git-send-email-mreitz@redhat.com Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
parent
9ea92c2106
commit
7748543420
5
block.c
5
block.c
@ -5759,12 +5759,13 @@ void bdrv_add_before_write_notifier(BlockDriverState *bs,
|
||||
notifier_with_return_list_add(&bs->before_write_notifiers, notifier);
|
||||
}
|
||||
|
||||
int bdrv_amend_options(BlockDriverState *bs, QemuOpts *opts)
|
||||
int bdrv_amend_options(BlockDriverState *bs, QemuOpts *opts,
|
||||
BlockDriverAmendStatusCB *status_cb)
|
||||
{
|
||||
if (!bs->drv->bdrv_amend_options) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
return bs->drv->bdrv_amend_options(bs, opts);
|
||||
return bs->drv->bdrv_amend_options(bs, opts, status_cb);
|
||||
}
|
||||
|
||||
/* This function will be called by the bdrv_recurse_is_first_non_filter method
|
||||
|
@ -2613,7 +2613,8 @@ static int qcow2_downgrade(BlockDriverState *bs, int target_version)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts)
|
||||
static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
|
||||
BlockDriverAmendStatusCB *status_cb)
|
||||
{
|
||||
BDRVQcowState *s = bs->opaque;
|
||||
int old_version = s->qcow_version, new_version = old_version;
|
||||
|
@ -268,7 +268,13 @@ typedef enum {
|
||||
|
||||
int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res, BdrvCheckMode fix);
|
||||
|
||||
int bdrv_amend_options(BlockDriverState *bs_new, QemuOpts *opts);
|
||||
/* The units of offset and total_work_size may be chosen arbitrarily by the
|
||||
* block driver; total_work_size may change during the course of the amendment
|
||||
* operation */
|
||||
typedef void BlockDriverAmendStatusCB(BlockDriverState *bs, int64_t offset,
|
||||
int64_t total_work_size);
|
||||
int bdrv_amend_options(BlockDriverState *bs_new, QemuOpts *opts,
|
||||
BlockDriverAmendStatusCB *status_cb);
|
||||
|
||||
/* external snapshots */
|
||||
bool bdrv_recurse_is_first_non_filter(BlockDriverState *bs,
|
||||
|
@ -232,7 +232,8 @@ struct BlockDriver {
|
||||
int (*bdrv_check)(BlockDriverState* bs, BdrvCheckResult *result,
|
||||
BdrvCheckMode fix);
|
||||
|
||||
int (*bdrv_amend_options)(BlockDriverState *bs, QemuOpts *opts);
|
||||
int (*bdrv_amend_options)(BlockDriverState *bs, QemuOpts *opts,
|
||||
BlockDriverAmendStatusCB *status_cb);
|
||||
|
||||
void (*bdrv_debug_event)(BlockDriverState *bs, BlkDebugEvent event);
|
||||
|
||||
|
@ -2968,7 +2968,7 @@ static int img_amend(int argc, char **argv)
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = bdrv_amend_options(bs, opts);
|
||||
ret = bdrv_amend_options(bs, opts, NULL);
|
||||
if (ret < 0) {
|
||||
error_report("Error while amending options: %s", strerror(-ret));
|
||||
goto out;
|
||||
|
Loading…
Reference in New Issue
Block a user