void qmp_transaction(BlockdevActionList *dev_list, Error **errp)

{

    int ret = 0;

    BlockdevActionList *dev_entry = dev_list;

    BlkTransactionStates *states, *next;



    QSIMPLEQ_HEAD(snap_bdrv_states, BlkTransactionStates) snap_bdrv_states;

    QSIMPLEQ_INIT(&snap_bdrv_states);



    /* drain all i/o before any snapshots */

    bdrv_drain_all();



    /* We don't do anything in this loop that commits us to the snapshot */

    while (NULL != dev_entry) {

        BlockdevAction *dev_info = NULL;

        BlockDriver *proto_drv;

        BlockDriver *drv;

        int flags;

        enum NewImageMode mode;

        const char *new_image_file;

        const char *device;

        const char *format = "qcow2";



        dev_info = dev_entry->value;

        dev_entry = dev_entry->next;



        states = g_malloc0(sizeof(BlkTransactionStates));

        QSIMPLEQ_INSERT_TAIL(&snap_bdrv_states, states, entry);



        switch (dev_info->kind) {

        case BLOCKDEV_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC:

            device = dev_info->blockdev_snapshot_sync->device;

            if (!dev_info->blockdev_snapshot_sync->has_mode) {

                dev_info->blockdev_snapshot_sync->mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS;

            }

            new_image_file = dev_info->blockdev_snapshot_sync->snapshot_file;

            if (dev_info->blockdev_snapshot_sync->has_format) {

                format = dev_info->blockdev_snapshot_sync->format;

            }

            mode = dev_info->blockdev_snapshot_sync->mode;

            break;

        default:

            abort();

        }



        drv = bdrv_find_format(format);

        if (!drv) {

            error_set(errp, QERR_INVALID_BLOCK_FORMAT, format);

            goto delete_and_fail;

        }



        states->old_bs = bdrv_find(device);

        if (!states->old_bs) {

            error_set(errp, QERR_DEVICE_NOT_FOUND, device);

            goto delete_and_fail;

        }



        if (!bdrv_is_inserted(states->old_bs)) {

            error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);

            goto delete_and_fail;

        }



        if (bdrv_in_use(states->old_bs)) {

            error_set(errp, QERR_DEVICE_IN_USE, device);

            goto delete_and_fail;

        }



        if (!bdrv_is_read_only(states->old_bs)) {

            if (bdrv_flush(states->old_bs)) {

                error_set(errp, QERR_IO_ERROR);

                goto delete_and_fail;

            }

        }



        flags = states->old_bs->open_flags;



        proto_drv = bdrv_find_protocol(new_image_file);

        if (!proto_drv) {

            error_set(errp, QERR_INVALID_BLOCK_FORMAT, format);

            goto delete_and_fail;

        }



        /* create new image w/backing file */

        if (mode != NEW_IMAGE_MODE_EXISTING) {

            ret = bdrv_img_create(new_image_file, format,

                                  states->old_bs->filename,

                                  states->old_bs->drv->format_name,

                                  NULL, -1, flags);

            if (ret) {

                error_set(errp, QERR_OPEN_FILE_FAILED, new_image_file);

                goto delete_and_fail;

            }

        }



        /* We will manually add the backing_hd field to the bs later */

        states->new_bs = bdrv_new("");

        ret = bdrv_open(states->new_bs, new_image_file,

                        flags | BDRV_O_NO_BACKING, drv);

        if (ret != 0) {

            error_set(errp, QERR_OPEN_FILE_FAILED, new_image_file);

            goto delete_and_fail;

        }

    }





    /* Now we are going to do the actual pivot.  Everything up to this point

     * is reversible, but we are committed at this point */

    QSIMPLEQ_FOREACH(states, &snap_bdrv_states, entry) {

        /* This removes our old bs from the bdrv_states, and adds the new bs */

        bdrv_append(states->new_bs, states->old_bs);






    }



    /* success */

    goto exit;



delete_and_fail:

    /*

    * failure, and it is all-or-none; abandon each new bs, and keep using

    * the original bs for all images

    */

    QSIMPLEQ_FOREACH(states, &snap_bdrv_states, entry) {

        if (states->new_bs) {

             bdrv_delete(states->new_bs);

        }

    }

exit:

    QSIMPLEQ_FOREACH_SAFE(states, &snap_bdrv_states, entry, next) {

        g_free(states);

    }

    return;

}
void qmp_transaction(BlockdevActionList *dev_list, Error **errp)

{

    int ret = 0;

    BlockdevActionList *dev_entry = dev_list;

    BlkTransactionStates *states, *next;



    QSIMPLEQ_HEAD(snap_bdrv_states, BlkTransactionStates) snap_bdrv_states;

    QSIMPLEQ_INIT(&snap_bdrv_states);



    

    bdrv_drain_all();



    

    while (NULL != dev_entry) {

        BlockdevAction *dev_info = NULL;

        BlockDriver *proto_drv;

        BlockDriver *drv;

        int flags;

        enum NewImageMode mode;

        const char *new_image_file;

        const char *device;

        const char *format = "qcow2";



        dev_info = dev_entry->value;

        dev_entry = dev_entry->next;



        states = g_malloc0(sizeof(BlkTransactionStates));

        QSIMPLEQ_INSERT_TAIL(&snap_bdrv_states, states, entry);



        switch (dev_info->kind) {

        case BLOCKDEV_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC:

            device = dev_info->blockdev_snapshot_sync->device;

            if (!dev_info->blockdev_snapshot_sync->has_mode) {

                dev_info->blockdev_snapshot_sync->mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS;

            }

            new_image_file = dev_info->blockdev_snapshot_sync->snapshot_file;

            if (dev_info->blockdev_snapshot_sync->has_format) {

                format = dev_info->blockdev_snapshot_sync->format;

            }

            mode = dev_info->blockdev_snapshot_sync->mode;

            break;

        default:

            abort();

        }



        drv = bdrv_find_format(format);

        if (!drv) {

            error_set(errp, QERR_INVALID_BLOCK_FORMAT, format);

            goto delete_and_fail;

        }



        states->old_bs = bdrv_find(device);

        if (!states->old_bs) {

            error_set(errp, QERR_DEVICE_NOT_FOUND, device);

            goto delete_and_fail;

        }



        if (!bdrv_is_inserted(states->old_bs)) {

            error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);

            goto delete_and_fail;

        }



        if (bdrv_in_use(states->old_bs)) {

            error_set(errp, QERR_DEVICE_IN_USE, device);

            goto delete_and_fail;

        }



        if (!bdrv_is_read_only(states->old_bs)) {

            if (bdrv_flush(states->old_bs)) {

                error_set(errp, QERR_IO_ERROR);

                goto delete_and_fail;

            }

        }



        flags = states->old_bs->open_flags;



        proto_drv = bdrv_find_protocol(new_image_file);

        if (!proto_drv) {

            error_set(errp, QERR_INVALID_BLOCK_FORMAT, format);

            goto delete_and_fail;

        }



        

        if (mode != NEW_IMAGE_MODE_EXISTING) {

            ret = bdrv_img_create(new_image_file, format,

                                  states->old_bs->filename,

                                  states->old_bs->drv->format_name,

                                  NULL, -1, flags);

            if (ret) {

                error_set(errp, QERR_OPEN_FILE_FAILED, new_image_file);

                goto delete_and_fail;

            }

        }



        

        states->new_bs = bdrv_new("");

        ret = bdrv_open(states->new_bs, new_image_file,

                        flags | BDRV_O_NO_BACKING, drv);

        if (ret != 0) {

            error_set(errp, QERR_OPEN_FILE_FAILED, new_image_file);

            goto delete_and_fail;

        }

    }





    



    QSIMPLEQ_FOREACH(states, &snap_bdrv_states, entry) {

        

        bdrv_append(states->new_bs, states->old_bs);






    }



    

    goto exit;



delete_and_fail:

    







    QSIMPLEQ_FOREACH(states, &snap_bdrv_states, entry) {

        if (states->new_bs) {

             bdrv_delete(states->new_bs);

        }

    }

exit:

    QSIMPLEQ_FOREACH_SAFE(states, &snap_bdrv_states, entry, next) {

        g_free(states);

    }

    return;

}
void FUNC_0(BlockdevActionList *VAR_0, Error **VAR_1)

{

    int VAR_2 = 0;

    BlockdevActionList *dev_entry = VAR_0;

    BlkTransactionStates *states, *next;



    QSIMPLEQ_HEAD(snap_bdrv_states, BlkTransactionStates) snap_bdrv_states;

    QSIMPLEQ_INIT(&snap_bdrv_states);



    

    bdrv_drain_all();



    

    while (NULL != dev_entry) {

        BlockdevAction *dev_info = NULL;

        BlockDriver *proto_drv;

        BlockDriver *drv;

        int VAR_3;

        enum NewImageMode VAR_4;

        const char *VAR_5;

        const char *VAR_6;

        const char *VAR_7 = "qcow2";



        dev_info = dev_entry->value;

        dev_entry = dev_entry->next;



        states = g_malloc0(sizeof(BlkTransactionStates));

        QSIMPLEQ_INSERT_TAIL(&snap_bdrv_states, states, entry);



        switch (dev_info->kind) {

        case BLOCKDEV_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC:

            VAR_6 = dev_info->blockdev_snapshot_sync->VAR_6;

            if (!dev_info->blockdev_snapshot_sync->has_mode) {

                dev_info->blockdev_snapshot_sync->VAR_4 = NEW_IMAGE_MODE_ABSOLUTE_PATHS;

            }

            VAR_5 = dev_info->blockdev_snapshot_sync->snapshot_file;

            if (dev_info->blockdev_snapshot_sync->has_format) {

                VAR_7 = dev_info->blockdev_snapshot_sync->VAR_7;

            }

            VAR_4 = dev_info->blockdev_snapshot_sync->VAR_4;

            break;

        default:

            abort();

        }



        drv = bdrv_find_format(VAR_7);

        if (!drv) {

            error_set(VAR_1, QERR_INVALID_BLOCK_FORMAT, VAR_7);

            goto delete_and_fail;

        }



        states->old_bs = bdrv_find(VAR_6);

        if (!states->old_bs) {

            error_set(VAR_1, QERR_DEVICE_NOT_FOUND, VAR_6);

            goto delete_and_fail;

        }



        if (!bdrv_is_inserted(states->old_bs)) {

            error_set(VAR_1, QERR_DEVICE_HAS_NO_MEDIUM, VAR_6);

            goto delete_and_fail;

        }



        if (bdrv_in_use(states->old_bs)) {

            error_set(VAR_1, QERR_DEVICE_IN_USE, VAR_6);

            goto delete_and_fail;

        }



        if (!bdrv_is_read_only(states->old_bs)) {

            if (bdrv_flush(states->old_bs)) {

                error_set(VAR_1, QERR_IO_ERROR);

                goto delete_and_fail;

            }

        }



        VAR_3 = states->old_bs->open_flags;



        proto_drv = bdrv_find_protocol(VAR_5);

        if (!proto_drv) {

            error_set(VAR_1, QERR_INVALID_BLOCK_FORMAT, VAR_7);

            goto delete_and_fail;

        }



        

        if (VAR_4 != NEW_IMAGE_MODE_EXISTING) {

            VAR_2 = bdrv_img_create(VAR_5, VAR_7,

                                  states->old_bs->filename,

                                  states->old_bs->drv->format_name,

                                  NULL, -1, VAR_3);

            if (VAR_2) {

                error_set(VAR_1, QERR_OPEN_FILE_FAILED, VAR_5);

                goto delete_and_fail;

            }

        }



        

        states->new_bs = bdrv_new("");

        VAR_2 = bdrv_open(states->new_bs, VAR_5,

                        VAR_3 | BDRV_O_NO_BACKING, drv);

        if (VAR_2 != 0) {

            error_set(VAR_1, QERR_OPEN_FILE_FAILED, VAR_5);

            goto delete_and_fail;

        }

    }





    



    QSIMPLEQ_FOREACH(states, &snap_bdrv_states, entry) {

        

        bdrv_append(states->new_bs, states->old_bs);






    }



    

    goto exit;



delete_and_fail:

    







    QSIMPLEQ_FOREACH(states, &snap_bdrv_states, entry) {

        if (states->new_bs) {

             bdrv_delete(states->new_bs);

        }

    }

exit:

    QSIMPLEQ_FOREACH_SAFE(states, &snap_bdrv_states, entry, next) {

        g_free(states);

    }

    return;

}
void FUNC_0(BlockdevActionList *VAR_0, Error **VAR_1)
{ int VAR_2 = 0; BlockdevActionList *dev_entry = VAR_0; BlkTransactionStates *states, *next; QSIMPLEQ_HEAD(snap_bdrv_states, BlkTransactionStates) snap_bdrv_states; QSIMPLEQ_INIT(&snap_bdrv_states); bdrv_drain_all(); while (NULL != dev_entry) { BlockdevAction *dev_info = NULL; BlockDriver *proto_drv; BlockDriver *drv; int VAR_3; enum NewImageMode VAR_4; const char *VAR_5; const char *VAR_6; const char *VAR_7 = "qcow2"; dev_info = dev_entry->value; dev_entry = dev_entry->next; states = g_malloc0(sizeof(BlkTransactionStates)); QSIMPLEQ_INSERT_TAIL(&snap_bdrv_states, states, entry); switch (dev_info->kind) { case BLOCKDEV_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC:
VAR_6 = dev_info->blockdev_snapshot_sync->VAR_6; if (!dev_info->blockdev_snapshot_sync->has_mode) { dev_info->blockdev_snapshot_sync->VAR_4 = NEW_IMAGE_MODE_ABSOLUTE_PATHS; } VAR_5 = dev_info->blockdev_snapshot_sync->snapshot_file; if (dev_info->blockdev_snapshot_sync->has_format) { VAR_7 = dev_info->blockdev_snapshot_sync->VAR_7; } VAR_4 = dev_info->blockdev_snapshot_sync->VAR_4; break; default:
abort(); } drv = bdrv_find_format(VAR_7); if (!drv) { error_set(VAR_1, QERR_INVALID_BLOCK_FORMAT, VAR_7); goto delete_and_fail; } states->old_bs = bdrv_find(VAR_6); if (!states->old_bs) { error_set(VAR_1, QERR_DEVICE_NOT_FOUND, VAR_6); goto delete_and_fail; } if (!bdrv_is_inserted(states->old_bs)) { error_set(VAR_1, QERR_DEVICE_HAS_NO_MEDIUM, VAR_6); goto delete_and_fail; } if (bdrv_in_use(states->old_bs)) { error_set(VAR_1, QERR_DEVICE_IN_USE, VAR_6); goto delete_and_fail; } if (!bdrv_is_read_only(states->old_bs)) { if (bdrv_flush(states->old_bs)) { error_set(VAR_1, QERR_IO_ERROR); goto delete_and_fail; } } VAR_3 = states->old_bs->open_flags; proto_drv = bdrv_find_protocol(VAR_5); if (!proto_drv) { error_set(VAR_1, QERR_INVALID_BLOCK_FORMAT, VAR_7); goto delete_and_fail; } if (VAR_4 != NEW_IMAGE_MODE_EXISTING) { VAR_2 = bdrv_img_create(VAR_5, VAR_7,
states->old_bs->filename,
states->old_bs->drv->format_name,
NULL, -1, VAR_3); if (VAR_2) { error_set(VAR_1, QERR_OPEN_FILE_FAILED, VAR_5); goto delete_and_fail; } } states->new_bs = bdrv_new(""); VAR_2 = bdrv_open(states->new_bs, VAR_5,
VAR_3 | BDRV_O_NO_BACKING, drv); if (VAR_2 != 0) { error_set(VAR_1, QERR_OPEN_FILE_FAILED, VAR_5); goto delete_and_fail; } } QSIMPLEQ_FOREACH(states, &snap_bdrv_states, entry) { bdrv_append(states->new_bs, states->old_bs); } goto exit; delete_and_fail:
QSIMPLEQ_FOREACH(states, &snap_bdrv_states, entry) { if (states->new_bs) { bdrv_delete(states->new_bs); } } exit:
QSIMPLEQ_FOREACH_SAFE(states, &snap_bdrv_states, entry, next) { g_free(states); } return; }