On Wed, Nov 05, 2014 at 10:57:09AM +0800, Fam Zheng wrote:
> +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;
> +    }
> +
> +    target_bs = bdrv_find(target);
> +    if (!target_bs) {
> +        error_set(errp, QERR_DEVICE_NOT_FOUND, 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) {
> +        bdrv_unref(target_bs);
> +        error_propagate(errp, local_err);
> +    }
> +}

Please make sure to acquire AioContext so that this is safe with
dataplane.

Here the tricky thing is that bs and target_bs must have the same
AioContext.  The easiest thing is to refuse if their AioContexts are not
identical, but that puts the onus on the user to put the
BlockDriverStates into the same AioContext.

Attachment: pgpHRUWK1TDe2.pgp
Description: PGP signature

Reply via email to