void qmp_drive_mirror(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, Error **errp)

{

    BlockDriverInfo bdi;

    BlockDriverState *bs;

    BlockDriverState *source, *target_bs;

    BlockDriver *proto_drv;

    BlockDriver *drv = NULL;

    Error *local_err = NULL;

    int flags;

    uint64_t size;

    int ret;



    if (!has_speed) {

        speed = 0;

    }

    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_in_use(bs)) {

        error_set(errp, QERR_DEVICE_IN_USE, device);

        return;

    }



    flags = bs->open_flags | BDRV_O_RDWR;

    source = bs->backing_hd;

    if (!source && sync == MIRROR_SYNC_MODE_TOP) {

        sync = MIRROR_SYNC_MODE_FULL;

    }



    proto_drv = bdrv_find_protocol(target);

    if (!proto_drv) {

        error_set(errp, QERR_INVALID_BLOCK_FORMAT, format);

        return;

    }



    if (sync == MIRROR_SYNC_MODE_FULL && mode != NEW_IMAGE_MODE_EXISTING) {

        /* create new image w/o backing file */

        assert(format && drv);

        bdrv_get_geometry(bs, &size);

        size *= 512;

        ret = bdrv_img_create(target, format,

                              NULL, NULL, NULL, size, flags);

    } else {

        switch (mode) {

        case NEW_IMAGE_MODE_EXISTING:

            ret = 0;

            break;

        case NEW_IMAGE_MODE_ABSOLUTE_PATHS:

            /* create new image with backing file */

            ret = bdrv_img_create(target, format,

                                  source->filename,

                                  source->drv->format_name,

                                  NULL, -1, flags);

            break;

        default:

            abort();

        }

    }



    if (ret) {

        error_set(errp, QERR_OPEN_FILE_FAILED, target);

        return;

    }



    target_bs = bdrv_new("");

    ret = bdrv_open(target_bs, target, flags | BDRV_O_NO_BACKING, drv);



    if (ret < 0) {

        bdrv_delete(target_bs);

        error_set(errp, QERR_OPEN_FILE_FAILED, target);

        return;

    }



    /* We need a backing file if we will copy parts of a cluster.  */

    if (bdrv_get_info(target_bs, &bdi) >= 0 && bdi.cluster_size != 0 &&

        bdi.cluster_size >= BDRV_SECTORS_PER_DIRTY_CHUNK * 512) {

        ret = bdrv_open_backing_file(target_bs);

        if (ret < 0) {

            bdrv_delete(target_bs);

            error_set(errp, QERR_OPEN_FILE_FAILED, target);

            return;

        }

    }



    mirror_start(bs, target_bs, speed, sync, block_job_cb, bs, &local_err);

    if (local_err != NULL) {

        bdrv_delete(target_bs);

        error_propagate(errp, local_err);

        return;

    }



    /* Grab a reference so hotplug does not delete the BlockDriverState from

     * underneath us.

     */

    drive_get_ref(drive_get_by_blockdev(bs));

}

void qmp_drive_mirror(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, Error **errp)

{

    BlockDriverInfo bdi;

    BlockDriverState *bs;

    BlockDriverState *source, *target_bs;

    BlockDriver *proto_drv;

    BlockDriver *drv = NULL;

    Error *local_err = NULL;

    int flags;

    uint64_t size;

    int ret;



    if (!has_speed) {

        speed = 0;

    }

    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_in_use(bs)) {

        error_set(errp, QERR_DEVICE_IN_USE, device);

        return;

    }



    flags = bs->open_flags | BDRV_O_RDWR;

    source = bs->backing_hd;

    if (!source && sync == MIRROR_SYNC_MODE_TOP) {

        sync = MIRROR_SYNC_MODE_FULL;

    }



    proto_drv = bdrv_find_protocol(target);

    if (!proto_drv) {

        error_set(errp, QERR_INVALID_BLOCK_FORMAT, format);

        return;

    }



    if (sync == MIRROR_SYNC_MODE_FULL && mode != NEW_IMAGE_MODE_EXISTING) {

        

        assert(format && drv);

        bdrv_get_geometry(bs, &size);

        size *= 512;

        ret = bdrv_img_create(target, format,

                              NULL, NULL, NULL, size, flags);

    } else {

        switch (mode) {

        case NEW_IMAGE_MODE_EXISTING:

            ret = 0;

            break;

        case NEW_IMAGE_MODE_ABSOLUTE_PATHS:

            

            ret = bdrv_img_create(target, format,

                                  source->filename,

                                  source->drv->format_name,

                                  NULL, -1, flags);

            break;

        default:

            abort();

        }

    }



    if (ret) {

        error_set(errp, QERR_OPEN_FILE_FAILED, target);

        return;

    }



    target_bs = bdrv_new("");

    ret = bdrv_open(target_bs, target, flags | BDRV_O_NO_BACKING, drv);



    if (ret < 0) {

        bdrv_delete(target_bs);

        error_set(errp, QERR_OPEN_FILE_FAILED, target);

        return;

    }



    

    if (bdrv_get_info(target_bs, &bdi) >= 0 && bdi.cluster_size != 0 &&

        bdi.cluster_size >= BDRV_SECTORS_PER_DIRTY_CHUNK * 512) {

        ret = bdrv_open_backing_file(target_bs);

        if (ret < 0) {

            bdrv_delete(target_bs);

            error_set(errp, QERR_OPEN_FILE_FAILED, target);

            return;

        }

    }



    mirror_start(bs, target_bs, speed, sync, block_job_cb, bs, &local_err);

    if (local_err != NULL) {

        bdrv_delete(target_bs);

        error_propagate(errp, local_err);

        return;

    }



    





    drive_get_ref(drive_get_by_blockdev(bs));

}

                      bool has_speed, int64_t speed, Error **errp)     mirror_start(bs, target_bs, speed, sync, block_job_cb, bs, &local_err);
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, Error **VAR_9)

{

    BlockDriverInfo bdi;

    BlockDriverState *bs;

    BlockDriverState *source, *target_bs;

    BlockDriver *proto_drv;

    BlockDriver *drv = NULL;

    Error *local_err = NULL;

    int VAR_10;

    uint64_t size;

    int VAR_11;



    if (!VAR_7) {

        VAR_8 = 0;

    }

    if (!VAR_5) {

        VAR_6 = NEW_IMAGE_MODE_ABSOLUTE_PATHS;

    }



    bs = bdrv_find(VAR_0);

    if (!bs) {

        error_set(VAR_9, QERR_DEVICE_NOT_FOUND, VAR_0);

        return;

    }



    if (!bdrv_is_inserted(bs)) {

        error_set(VAR_9, 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_9, QERR_INVALID_BLOCK_FORMAT, VAR_3);

            return;

        }

    }



    if (bdrv_in_use(bs)) {

        error_set(VAR_9, QERR_DEVICE_IN_USE, VAR_0);

        return;

    }



    VAR_10 = bs->open_flags | BDRV_O_RDWR;

    source = bs->backing_hd;

    if (!source && VAR_4 == MIRROR_SYNC_MODE_TOP) {

        VAR_4 = MIRROR_SYNC_MODE_FULL;

    }



    proto_drv = bdrv_find_protocol(VAR_1);

    if (!proto_drv) {

        error_set(VAR_9, QERR_INVALID_BLOCK_FORMAT, VAR_3);

        return;

    }



    if (VAR_4 == MIRROR_SYNC_MODE_FULL && VAR_6 != NEW_IMAGE_MODE_EXISTING) {

        

        assert(VAR_3 && drv);

        bdrv_get_geometry(bs, &size);

        size *= 512;

        VAR_11 = bdrv_img_create(VAR_1, VAR_3,

                              NULL, NULL, NULL, size, VAR_10);

    } else {

        switch (VAR_6) {

        case NEW_IMAGE_MODE_EXISTING:

            VAR_11 = 0;

            break;

        case NEW_IMAGE_MODE_ABSOLUTE_PATHS:

            

            VAR_11 = bdrv_img_create(VAR_1, VAR_3,

                                  source->filename,

                                  source->drv->format_name,

                                  NULL, -1, VAR_10);

            break;

        default:

            abort();

        }

    }



    if (VAR_11) {

        error_set(VAR_9, QERR_OPEN_FILE_FAILED, VAR_1);

        return;

    }



    target_bs = bdrv_new("");

    VAR_11 = bdrv_open(target_bs, VAR_1, VAR_10 | BDRV_O_NO_BACKING, drv);



    if (VAR_11 < 0) {

        bdrv_delete(target_bs);

        error_set(VAR_9, QERR_OPEN_FILE_FAILED, VAR_1);

        return;

    }



    

    if (bdrv_get_info(target_bs, &bdi) >= 0 && bdi.cluster_size != 0 &&

        bdi.cluster_size >= BDRV_SECTORS_PER_DIRTY_CHUNK * 512) {

        VAR_11 = bdrv_open_backing_file(target_bs);

        if (VAR_11 < 0) {

            bdrv_delete(target_bs);

            error_set(VAR_9, QERR_OPEN_FILE_FAILED, VAR_1);

            return;

        }

    }



    mirror_start(bs, target_bs, VAR_8, VAR_4, block_job_cb, bs, &local_err);

    if (local_err != NULL) {

        bdrv_delete(target_bs);

        error_propagate(VAR_9, local_err);

        return;

    }



    





    drive_get_ref(drive_get_by_blockdev(bs));

}

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, Error **VAR_9)
{ BlockDriverInfo bdi; BlockDriverState *bs; BlockDriverState *source, *target_bs; BlockDriver *proto_drv; BlockDriver *drv = NULL; Error *local_err = NULL; int VAR_10; uint64_t size; int VAR_11; if (!VAR_7) { VAR_8 = 0; } if (!VAR_5) { VAR_6 = NEW_IMAGE_MODE_ABSOLUTE_PATHS; } bs = bdrv_find(VAR_0); if (!bs) { error_set(VAR_9, QERR_DEVICE_NOT_FOUND, VAR_0); return; } if (!bdrv_is_inserted(bs)) { error_set(VAR_9, 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_9, QERR_INVALID_BLOCK_FORMAT, VAR_3); return; } } if (bdrv_in_use(bs)) { error_set(VAR_9, QERR_DEVICE_IN_USE, VAR_0); return; } VAR_10 = bs->open_flags | BDRV_O_RDWR; source = bs->backing_hd; if (!source && VAR_4 == MIRROR_SYNC_MODE_TOP) { VAR_4 = MIRROR_SYNC_MODE_FULL; } proto_drv = bdrv_find_protocol(VAR_1); if (!proto_drv) { error_set(VAR_9, QERR_INVALID_BLOCK_FORMAT, VAR_3); return; } if (VAR_4 == MIRROR_SYNC_MODE_FULL && VAR_6 != NEW_IMAGE_MODE_EXISTING) { assert(VAR_3 && drv); bdrv_get_geometry(bs, &size); size *= 512; VAR_11 = bdrv_img_create(VAR_1, VAR_3,
NULL, NULL, NULL, size, VAR_10); } else { switch (VAR_6) { case NEW_IMAGE_MODE_EXISTING:
VAR_11 = 0; break; case NEW_IMAGE_MODE_ABSOLUTE_PATHS:
VAR_11 = bdrv_img_create(VAR_1, VAR_3,
source->filename,
source->drv->format_name,
NULL, -1, VAR_10); break; default:
abort(); } } if (VAR_11) { error_set(VAR_9, QERR_OPEN_FILE_FAILED, VAR_1); return; } target_bs = bdrv_new(""); VAR_11 = bdrv_open(target_bs, VAR_1, VAR_10 | BDRV_O_NO_BACKING, drv); if (VAR_11 < 0) { bdrv_delete(target_bs); error_set(VAR_9, QERR_OPEN_FILE_FAILED, VAR_1); return; } if (bdrv_get_info(target_bs, &bdi) >= 0 && bdi.cluster_size != 0 &&
bdi.cluster_size >= BDRV_SECTORS_PER_DIRTY_CHUNK * 512) { VAR_11 = bdrv_open_backing_file(target_bs); if (VAR_11 < 0) { bdrv_delete(target_bs); error_set(VAR_9, QERR_OPEN_FILE_FAILED, VAR_1); return; } } mirror_start(bs, target_bs, VAR_8, VAR_4, block_job_cb, bs, &local_err); if (local_err != NULL) { bdrv_delete(target_bs); error_propagate(VAR_9, local_err); return; } drive_get_ref(drive_get_by_blockdev(bs)); }