void qmp_drive_backup(const char *device, const char *target,

                      bool has_format, const char *format,

                      enum MirrorSyncMode sync,

                      bool has_mode, enum NewImageMode mode,

                      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;

    BlockDriverState *source = NULL;

    BlockDriver *drv = NULL;

    Error *local_err = NULL;

    int flags;

    int64_t size;

    int ret;



    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;

    }

    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_op_is_blocked(bs, BLOCK_OP_TYPE_BACKUP_SOURCE, errp)) {

        return;

    }



    flags = bs->open_flags | BDRV_O_RDWR;



    /* See if we have a backing HD we can use to create our new image

     * on top of. */

    if (sync == MIRROR_SYNC_MODE_TOP) {

        source = bs->backing_hd;

        if (!source) {

            sync = MIRROR_SYNC_MODE_FULL;

        }

    }

    if (sync == MIRROR_SYNC_MODE_NONE) {

        source = bs;

    }



    size = bdrv_getlength(bs);

    if (size < 0) {

        error_setg_errno(errp, -size, "bdrv_getlength failed");

        return;

    }



    if (mode != NEW_IMAGE_MODE_EXISTING) {

        assert(format && drv);

        if (source) {

            bdrv_img_create(target, format, source->filename,

                            source->drv->format_name, NULL,

                            size, flags, &local_err, false);

        } else {

            bdrv_img_create(target, format, NULL, NULL, NULL,

                            size, flags, &local_err, false);

        }

    }



    if (local_err) {

        error_propagate(errp, local_err);

        return;

    }



    target_bs = NULL;

    ret = bdrv_open(&target_bs, target, NULL, NULL, flags, drv, &local_err);

    if (ret < 0) {

        error_propagate(errp, local_err);

        return;

    }



    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);

        return;

    }

}

void qmp_drive_backup(const char *device, const char *target,

                      bool has_format, const char *format,

                      enum MirrorSyncMode sync,

                      bool has_mode, enum NewImageMode mode,

                      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;

    BlockDriverState *source = NULL;

    BlockDriver *drv = NULL;

    Error *local_err = NULL;

    int flags;

    int64_t size;

    int ret;



    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;

    }

    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_op_is_blocked(bs, BLOCK_OP_TYPE_BACKUP_SOURCE, errp)) {

        return;

    }



    flags = bs->open_flags | BDRV_O_RDWR;



    



    if (sync == MIRROR_SYNC_MODE_TOP) {

        source = bs->backing_hd;

        if (!source) {

            sync = MIRROR_SYNC_MODE_FULL;

        }

    }

    if (sync == MIRROR_SYNC_MODE_NONE) {

        source = bs;

    }



    size = bdrv_getlength(bs);

    if (size < 0) {

        error_setg_errno(errp, -size, "bdrv_getlength failed");

        return;

    }



    if (mode != NEW_IMAGE_MODE_EXISTING) {

        assert(format && drv);

        if (source) {

            bdrv_img_create(target, format, source->filename,

                            source->drv->format_name, NULL,

                            size, flags, &local_err, false);

        } else {

            bdrv_img_create(target, format, NULL, NULL, NULL,

                            size, flags, &local_err, false);

        }

    }



    if (local_err) {

        error_propagate(errp, local_err);

        return;

    }



    target_bs = NULL;

    ret = bdrv_open(&target_bs, target, NULL, NULL, flags, drv, &local_err);

    if (ret < 0) {

        error_propagate(errp, local_err);

        return;

    }



    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);

        return;

    }

}

void FUNC_0(const char *VAR_0, const char *VAR_1,

                      bool VAR_2, const char *VAR_3,

                      enum MirrorSyncMode VAR_4,

                      bool VAR_5, enum NewImageMode VAR_6,

                      bool VAR_7, int64_t VAR_8,

                      bool VAR_9, BlockdevOnError VAR_10,

                      bool VAR_11, BlockdevOnError VAR_12,

                      Error **VAR_13)

{

    BlockDriverState *bs;

    BlockDriverState *target_bs;

    BlockDriverState *source = NULL;

    BlockDriver *drv = NULL;

    Error *local_err = NULL;

    int VAR_14;

    int64_t size;

    int VAR_15;



    if (!VAR_7) {

        VAR_8 = 0;

    }

    if (!VAR_9) {

        VAR_10 = BLOCKDEV_ON_ERROR_REPORT;

    }

    if (!VAR_11) {

        VAR_12 = BLOCKDEV_ON_ERROR_REPORT;

    }

    if (!VAR_5) {

        VAR_6 = NEW_IMAGE_MODE_ABSOLUTE_PATHS;

    }



    bs = bdrv_find(VAR_0);

    if (!bs) {

        error_set(VAR_13, QERR_DEVICE_NOT_FOUND, VAR_0);

        return;

    }



    if (!bdrv_is_inserted(bs)) {

        error_set(VAR_13, QERR_DEVICE_HAS_NO_MEDIUM, VAR_0);

        return;

    }



    if (!VAR_2) {

        VAR_3 = VAR_6 == NEW_IMAGE_MODE_EXISTING ? NULL : bs->drv->format_name;

    }

    if (VAR_3) {

        drv = bdrv_find_format(VAR_3);

        if (!drv) {

            error_set(VAR_13, QERR_INVALID_BLOCK_FORMAT, VAR_3);

            return;

        }

    }



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

        return;

    }



    VAR_14 = bs->open_flags | BDRV_O_RDWR;



    



    if (VAR_4 == MIRROR_SYNC_MODE_TOP) {

        source = bs->backing_hd;

        if (!source) {

            VAR_4 = MIRROR_SYNC_MODE_FULL;

        }

    }

    if (VAR_4 == MIRROR_SYNC_MODE_NONE) {

        source = bs;

    }



    size = bdrv_getlength(bs);

    if (size < 0) {

        error_setg_errno(VAR_13, -size, "bdrv_getlength failed");

        return;

    }



    if (VAR_6 != NEW_IMAGE_MODE_EXISTING) {

        assert(VAR_3 && drv);

        if (source) {

            bdrv_img_create(VAR_1, VAR_3, source->filename,

                            source->drv->format_name, NULL,

                            size, VAR_14, &local_err, false);

        } else {

            bdrv_img_create(VAR_1, VAR_3, NULL, NULL, NULL,

                            size, VAR_14, &local_err, false);

        }

    }



    if (local_err) {

        error_propagate(VAR_13, local_err);

        return;

    }



    target_bs = NULL;

    VAR_15 = bdrv_open(&target_bs, VAR_1, NULL, NULL, VAR_14, drv, &local_err);

    if (VAR_15 < 0) {

        error_propagate(VAR_13, local_err);

        return;

    }



    backup_start(bs, target_bs, VAR_8, VAR_4, VAR_10, VAR_12,

                 block_job_cb, bs, &local_err);

    if (local_err != NULL) {

        bdrv_unref(target_bs);

        error_propagate(VAR_13, local_err);

        return;

    }

}

void FUNC_0(const char *VAR_0, const char *VAR_1,
bool VAR_2, const char *VAR_3,
enum MirrorSyncMode VAR_4,
bool VAR_5, enum NewImageMode VAR_6,
bool VAR_7, int64_t VAR_8,
bool VAR_9, BlockdevOnError VAR_10,
bool VAR_11, BlockdevOnError VAR_12,
Error **VAR_13)
{ BlockDriverState *bs; BlockDriverState *target_bs; BlockDriverState *source = NULL; BlockDriver *drv = NULL; Error *local_err = NULL; int VAR_14; int64_t size; int VAR_15; if (!VAR_7) { VAR_8 = 0; } if (!VAR_9) { VAR_10 = BLOCKDEV_ON_ERROR_REPORT; } if (!VAR_11) { VAR_12 = BLOCKDEV_ON_ERROR_REPORT; } if (!VAR_5) { VAR_6 = NEW_IMAGE_MODE_ABSOLUTE_PATHS; } bs = bdrv_find(VAR_0); if (!bs) { error_set(VAR_13, QERR_DEVICE_NOT_FOUND, VAR_0); return; } if (!bdrv_is_inserted(bs)) { error_set(VAR_13, QERR_DEVICE_HAS_NO_MEDIUM, VAR_0); return; } if (!VAR_2) { VAR_3 = VAR_6 == NEW_IMAGE_MODE_EXISTING ? NULL : bs->drv->format_name; } if (VAR_3) { drv = bdrv_find_format(VAR_3); if (!drv) { error_set(VAR_13, QERR_INVALID_BLOCK_FORMAT, VAR_3); return; } } if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_BACKUP_SOURCE, VAR_13)) { return; } VAR_14 = bs->open_flags | BDRV_O_RDWR; if (VAR_4 == MIRROR_SYNC_MODE_TOP) { source = bs->backing_hd; if (!source) { VAR_4 = MIRROR_SYNC_MODE_FULL; } } if (VAR_4 == MIRROR_SYNC_MODE_NONE) { source = bs; } size = bdrv_getlength(bs); if (size < 0) { error_setg_errno(VAR_13, -size, "bdrv_getlength failed"); return; } if (VAR_6 != NEW_IMAGE_MODE_EXISTING) { assert(VAR_3 && drv); if (source) { bdrv_img_create(VAR_1, VAR_3, source->filename,
source->drv->format_name, NULL,
size, VAR_14, &local_err, false); } else { bdrv_img_create(VAR_1, VAR_3, NULL, NULL, NULL,
size, VAR_14, &local_err, false); } } if (local_err) { error_propagate(VAR_13, local_err); return; } target_bs = NULL; VAR_15 = bdrv_open(&target_bs, VAR_1, NULL, NULL, VAR_14, drv, &local_err); if (VAR_15 < 0) { error_propagate(VAR_13, local_err); return; } backup_start(bs, target_bs, VAR_8, VAR_4, VAR_10, VAR_12,
block_job_cb, bs, &local_err); if (local_err != NULL) { bdrv_unref(target_bs); error_propagate(VAR_13, local_err); return; } }