void backup_start(BlockDriverState *bs, BlockDriverState *target,

                  int64_t speed, MirrorSyncMode sync_mode,

                  BdrvDirtyBitmap *sync_bitmap,

                  BlockdevOnError on_source_error,

                  BlockdevOnError on_target_error,

                  BlockCompletionFunc *cb, void *opaque,

                  BlockJobTxn *txn, Error **errp)

{

    int64_t len;

    BlockDriverInfo bdi;

    int ret;



    assert(bs);

    assert(target);

    assert(cb);



    if (bs == target) {

        error_setg(errp, "Source and target cannot be the same");

        return;

    }



    if (!bdrv_is_inserted(bs)) {

        error_setg(errp, "Device is not inserted: %s",

                   bdrv_get_device_name(bs));

        return;

    }



    if (!bdrv_is_inserted(target)) {

        error_setg(errp, "Device is not inserted: %s",

                   bdrv_get_device_name(target));

        return;

    }



    if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_BACKUP_SOURCE, errp)) {

        return;

    }



    if (bdrv_op_is_blocked(target, BLOCK_OP_TYPE_BACKUP_TARGET, errp)) {

        return;

    }



    if (sync_mode == MIRROR_SYNC_MODE_INCREMENTAL) {

        if (!sync_bitmap) {

            error_setg(errp, "must provide a valid bitmap name for "

                             "\"incremental\" sync mode");

            return;

        }



        /* Create a new bitmap, and freeze/disable this one. */

        if (bdrv_dirty_bitmap_create_successor(bs, sync_bitmap, errp) < 0) {

            return;

        }

    } else if (sync_bitmap) {

        error_setg(errp,

                   "a sync_bitmap was provided to backup_run, "

                   "but received an incompatible sync_mode (%s)",

                   MirrorSyncMode_lookup[sync_mode]);

        return;

    }



    len = bdrv_getlength(bs);

    if (len < 0) {

        error_setg_errno(errp, -len, "unable to get length for '%s'",

                         bdrv_get_device_name(bs));

        goto error;

    }



    BackupBlockJob *job = block_job_create(&backup_job_driver, bs, speed,

                                           cb, opaque, errp);

    if (!job) {

        goto error;

    }



    job->on_source_error = on_source_error;

    job->on_target_error = on_target_error;

    job->target = target;

    job->sync_mode = sync_mode;

    job->sync_bitmap = sync_mode == MIRROR_SYNC_MODE_INCREMENTAL ?

                       sync_bitmap : NULL;



    /* If there is no backing file on the target, we cannot rely on COW if our

     * backup cluster size is smaller than the target cluster size. Even for

     * targets with a backing file, try to avoid COW if possible. */

    ret = bdrv_get_info(job->target, &bdi);

    if (ret < 0 && !target->backing) {

        error_setg_errno(errp, -ret,

            "Couldn't determine the cluster size of the target image, "

            "which has no backing file");

        error_append_hint(errp,

            "Aborting, since this may create an unusable destination image\n");

        goto error;

    } else if (ret < 0 && target->backing) {

        /* Not fatal; just trudge on ahead. */

        job->cluster_size = BACKUP_CLUSTER_SIZE_DEFAULT;

    } else {

        job->cluster_size = MAX(BACKUP_CLUSTER_SIZE_DEFAULT, bdi.cluster_size);

    }



    bdrv_op_block_all(target, job->common.blocker);

    job->common.len = len;

    job->common.co = qemu_coroutine_create(backup_run);

    block_job_txn_add_job(txn, &job->common);

    qemu_coroutine_enter(job->common.co, job);

    return;



 error:

    if (sync_bitmap) {

        bdrv_reclaim_dirty_bitmap(bs, sync_bitmap, NULL);

    }

}

void backup_start(BlockDriverState *bs, BlockDriverState *target,

                  int64_t speed, MirrorSyncMode sync_mode,

                  BdrvDirtyBitmap *sync_bitmap,

                  BlockdevOnError on_source_error,

                  BlockdevOnError on_target_error,

                  BlockCompletionFunc *cb, void *opaque,

                  BlockJobTxn *txn, Error **errp)

{

    int64_t len;

    BlockDriverInfo bdi;

    int ret;



    assert(bs);

    assert(target);

    assert(cb);



    if (bs == target) {

        error_setg(errp, "Source and target cannot be the same");

        return;

    }



    if (!bdrv_is_inserted(bs)) {

        error_setg(errp, "Device is not inserted: %s",

                   bdrv_get_device_name(bs));

        return;

    }



    if (!bdrv_is_inserted(target)) {

        error_setg(errp, "Device is not inserted: %s",

                   bdrv_get_device_name(target));

        return;

    }



    if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_BACKUP_SOURCE, errp)) {

        return;

    }



    if (bdrv_op_is_blocked(target, BLOCK_OP_TYPE_BACKUP_TARGET, errp)) {

        return;

    }



    if (sync_mode == MIRROR_SYNC_MODE_INCREMENTAL) {

        if (!sync_bitmap) {

            error_setg(errp, "must provide a valid bitmap name for "

                             "\"incremental\" sync mode");

            return;

        }



        

        if (bdrv_dirty_bitmap_create_successor(bs, sync_bitmap, errp) < 0) {

            return;

        }

    } else if (sync_bitmap) {

        error_setg(errp,

                   "a sync_bitmap was provided to backup_run, "

                   "but received an incompatible sync_mode (%s)",

                   MirrorSyncMode_lookup[sync_mode]);

        return;

    }



    len = bdrv_getlength(bs);

    if (len < 0) {

        error_setg_errno(errp, -len, "unable to get length for '%s'",

                         bdrv_get_device_name(bs));

        goto error;

    }



    BackupBlockJob *job = block_job_create(&backup_job_driver, bs, speed,

                                           cb, opaque, errp);

    if (!job) {

        goto error;

    }



    job->on_source_error = on_source_error;

    job->on_target_error = on_target_error;

    job->target = target;

    job->sync_mode = sync_mode;

    job->sync_bitmap = sync_mode == MIRROR_SYNC_MODE_INCREMENTAL ?

                       sync_bitmap : NULL;



    





    ret = bdrv_get_info(job->target, &bdi);

    if (ret < 0 && !target->backing) {

        error_setg_errno(errp, -ret,

            "Couldn't determine the cluster size of the target image, "

            "which has no backing file");

        error_append_hint(errp,

            "Aborting, since this may create an unusable destination image\n");

        goto error;

    } else if (ret < 0 && target->backing) {

        

        job->cluster_size = BACKUP_CLUSTER_SIZE_DEFAULT;

    } else {

        job->cluster_size = MAX(BACKUP_CLUSTER_SIZE_DEFAULT, bdi.cluster_size);

    }



    bdrv_op_block_all(target, job->common.blocker);

    job->common.len = len;

    job->common.co = qemu_coroutine_create(backup_run);

    block_job_txn_add_job(txn, &job->common);

    qemu_coroutine_enter(job->common.co, job);

    return;



 error:

    if (sync_bitmap) {

        bdrv_reclaim_dirty_bitmap(bs, sync_bitmap, NULL);

    }

}

    BackupBlockJob *job = block_job_create(&backup_job_driver, bs, speed,                                            cb, opaque, errp);
void FUNC_0(BlockDriverState *VAR_0, BlockDriverState *VAR_1,

                  int64_t VAR_2, MirrorSyncMode VAR_3,

                  BdrvDirtyBitmap *VAR_4,

                  BlockdevOnError VAR_5,

                  BlockdevOnError VAR_6,

                  BlockCompletionFunc *VAR_7, void *VAR_8,

                  BlockJobTxn *VAR_9, Error **VAR_10)

{

    int64_t len;

    BlockDriverInfo bdi;

    int VAR_11;



    assert(VAR_0);

    assert(VAR_1);

    assert(VAR_7);



    if (VAR_0 == VAR_1) {

        error_setg(VAR_10, "Source and VAR_1 cannot be the same");

        return;

    }



    if (!bdrv_is_inserted(VAR_0)) {

        error_setg(VAR_10, "Device is not inserted: %s",

                   bdrv_get_device_name(VAR_0));

        return;

    }



    if (!bdrv_is_inserted(VAR_1)) {

        error_setg(VAR_10, "Device is not inserted: %s",

                   bdrv_get_device_name(VAR_1));

        return;

    }



    if (bdrv_op_is_blocked(VAR_0, BLOCK_OP_TYPE_BACKUP_SOURCE, VAR_10)) {

        return;

    }



    if (bdrv_op_is_blocked(VAR_1, BLOCK_OP_TYPE_BACKUP_TARGET, VAR_10)) {

        return;

    }



    if (VAR_3 == MIRROR_SYNC_MODE_INCREMENTAL) {

        if (!VAR_4) {

            error_setg(VAR_10, "must provide a valid bitmap name for "

                             "\"incremental\" sync mode");

            return;

        }



        

        if (bdrv_dirty_bitmap_create_successor(VAR_0, VAR_4, VAR_10) < 0) {

            return;

        }

    } else if (VAR_4) {

        error_setg(VAR_10,

                   "a VAR_4 was provided to backup_run, "

                   "but received an incompatible VAR_3 (%s)",

                   MirrorSyncMode_lookup[VAR_3]);

        return;

    }



    len = bdrv_getlength(VAR_0);

    if (len < 0) {

        error_setg_errno(VAR_10, -len, "unable to get length for '%s'",

                         bdrv_get_device_name(VAR_0));

        goto error;

    }



    BackupBlockJob *job = block_job_create(&backup_job_driver, VAR_0, VAR_2,

                                           VAR_7, VAR_8, VAR_10);

    if (!job) {

        goto error;

    }



    job->VAR_5 = VAR_5;

    job->VAR_6 = VAR_6;

    job->VAR_1 = VAR_1;

    job->VAR_3 = VAR_3;

    job->VAR_4 = VAR_3 == MIRROR_SYNC_MODE_INCREMENTAL ?

                       VAR_4 : NULL;



    





    VAR_11 = bdrv_get_info(job->VAR_1, &bdi);

    if (VAR_11 < 0 && !VAR_1->backing) {

        error_setg_errno(VAR_10, -VAR_11,

            "Couldn't determine the cluster size of the VAR_1 image, "

            "which has no backing file");

        error_append_hint(VAR_10,

            "Aborting, since this may create an unusable destination image\n");

        goto error;

    } else if (VAR_11 < 0 && VAR_1->backing) {

        

        job->cluster_size = BACKUP_CLUSTER_SIZE_DEFAULT;

    } else {

        job->cluster_size = MAX(BACKUP_CLUSTER_SIZE_DEFAULT, bdi.cluster_size);

    }



    bdrv_op_block_all(VAR_1, job->common.blocker);

    job->common.len = len;

    job->common.co = qemu_coroutine_create(backup_run);

    block_job_txn_add_job(VAR_9, &job->common);

    qemu_coroutine_enter(job->common.co, job);

    return;



 error:

    if (VAR_4) {

        bdrv_reclaim_dirty_bitmap(VAR_0, VAR_4, NULL);

    }

}

void FUNC_0(BlockDriverState *VAR_0, BlockDriverState *VAR_1,
int64_t VAR_2, MirrorSyncMode VAR_3,
BdrvDirtyBitmap *VAR_4,
BlockdevOnError VAR_5,
BlockdevOnError VAR_6,
BlockCompletionFunc *VAR_7, void *VAR_8,
BlockJobTxn *VAR_9, Error **VAR_10)
{ int64_t len; BlockDriverInfo bdi; int VAR_11; assert(VAR_0); assert(VAR_1); assert(VAR_7); if (VAR_0 == VAR_1) { error_setg(VAR_10, "Source and VAR_1 cannot be the same"); return; } if (!bdrv_is_inserted(VAR_0)) { error_setg(VAR_10, "Device is not inserted: %s",
bdrv_get_device_name(VAR_0)); return; } if (!bdrv_is_inserted(VAR_1)) { error_setg(VAR_10, "Device is not inserted: %s",
bdrv_get_device_name(VAR_1)); return; } if (bdrv_op_is_blocked(VAR_0, BLOCK_OP_TYPE_BACKUP_SOURCE, VAR_10)) { return; } if (bdrv_op_is_blocked(VAR_1, BLOCK_OP_TYPE_BACKUP_TARGET, VAR_10)) { return; } if (VAR_3 == MIRROR_SYNC_MODE_INCREMENTAL) { if (!VAR_4) { error_setg(VAR_10, "must provide a valid bitmap name for "
"\"incremental\" sync mode"); return; } if (bdrv_dirty_bitmap_create_successor(VAR_0, VAR_4, VAR_10) < 0) { return; } } else if (VAR_4) { error_setg(VAR_10,
"a VAR_4 was provided to backup_run, "
"but received an incompatible VAR_3 (%s)",
MirrorSyncMode_lookup[VAR_3]); return; } len = bdrv_getlength(VAR_0); if (len < 0) { error_setg_errno(VAR_10, -len, "unable to get length for '%s'",
bdrv_get_device_name(VAR_0)); goto error; } BackupBlockJob *job = block_job_create(&backup_job_driver, VAR_0, VAR_2,
VAR_7, VAR_8, VAR_10); if (!job) { goto error; } job->VAR_5 = VAR_5; job->VAR_6 = VAR_6; job->VAR_1 = VAR_1; job->VAR_3 = VAR_3; job->VAR_4 = VAR_3 == MIRROR_SYNC_MODE_INCREMENTAL ?
VAR_4 : NULL; VAR_11 = bdrv_get_info(job->VAR_1, &bdi); if (VAR_11 < 0 && !VAR_1->backing) { error_setg_errno(VAR_10, -VAR_11,
"Couldn't determine the cluster size of the VAR_1 image, "
"which has no backing file"); error_append_hint(VAR_10,
"Aborting, since this may create an unusable destination image\n"); goto error; } else if (VAR_11 < 0 && VAR_1->backing) { job->cluster_size = BACKUP_CLUSTER_SIZE_DEFAULT; } else { job->cluster_size = MAX(BACKUP_CLUSTER_SIZE_DEFAULT, bdi.cluster_size); } bdrv_op_block_all(VAR_1, job->common.blocker); job->common.len = len; job->common.co = qemu_coroutine_create(backup_run); block_job_txn_add_job(VAR_9, &job->common); qemu_coroutine_enter(job->common.co, job); return; error:
if (VAR_4) { bdrv_reclaim_dirty_bitmap(VAR_0, VAR_4, NULL); } }