int bdrv_open(BlockDriverState *bs, const char *filename, int flags,

              BlockDriver *drv)

{

    int ret;

    char tmp_filename[PATH_MAX];



    if (flags & BDRV_O_SNAPSHOT) {

        BlockDriverState *bs1;

        int64_t total_size;

        int is_protocol = 0;

        BlockDriver *bdrv_qcow2;

        QEMUOptionParameter *options;

        char backing_filename[PATH_MAX];



        /* if snapshot, we create a temporary backing file and open it

           instead of opening 'filename' directly */



        /* if there is a backing file, use it */

        bs1 = bdrv_new("");

        ret = bdrv_open(bs1, filename, 0, drv);

        if (ret < 0) {

            bdrv_delete(bs1);

            return ret;

        }

        total_size = bdrv_getlength(bs1) & BDRV_SECTOR_MASK;



        if (bs1->drv && bs1->drv->protocol_name)

            is_protocol = 1;



        bdrv_delete(bs1);



        get_tmp_filename(tmp_filename, sizeof(tmp_filename));



        /* Real path is meaningless for protocols */

        if (is_protocol)

            snprintf(backing_filename, sizeof(backing_filename),

                     "%s", filename);

        else if (!realpath(filename, backing_filename))

            return -errno;



        bdrv_qcow2 = bdrv_find_format("qcow2");

        options = parse_option_parameters("", bdrv_qcow2->create_options, NULL);



        set_option_parameter_int(options, BLOCK_OPT_SIZE, total_size);

        set_option_parameter(options, BLOCK_OPT_BACKING_FILE, backing_filename);

        if (drv) {

            set_option_parameter(options, BLOCK_OPT_BACKING_FMT,

                drv->format_name);

        }



        ret = bdrv_create(bdrv_qcow2, tmp_filename, options);

        free_option_parameters(options);

        if (ret < 0) {

            return ret;

        }



        filename = tmp_filename;

        drv = bdrv_qcow2;

        bs->is_temporary = 1;

    }



    /* Find the right image format driver */

    if (!drv) {

        ret = find_image_format(filename, &drv);

    }



    if (!drv) {

        goto unlink_and_fail;

    }



    /* Open the image */

    ret = bdrv_open_common(bs, filename, flags, drv);

    if (ret < 0) {

        goto unlink_and_fail;

    }



    /* If there is a backing file, use it */

    if ((flags & BDRV_O_NO_BACKING) == 0 && bs->backing_file[0] != '\0') {

        char backing_filename[PATH_MAX];

        int back_flags;

        BlockDriver *back_drv = NULL;



        bs->backing_hd = bdrv_new("");

        bdrv_get_full_backing_filename(bs, backing_filename,

                                       sizeof(backing_filename));



        if (bs->backing_format[0] != '\0') {

            back_drv = bdrv_find_format(bs->backing_format);

        }



        /* backing files always opened read-only */

        back_flags =

            flags & ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);



        ret = bdrv_open(bs->backing_hd, backing_filename, back_flags, back_drv);

        if (ret < 0) {

            bdrv_close(bs);

            return ret;

        }

        if (bs->is_temporary) {

            bs->backing_hd->keep_read_only = !(flags & BDRV_O_RDWR);

        } else {

            /* base image inherits from "parent" */

            bs->backing_hd->keep_read_only = bs->keep_read_only;

        }

    }



    if (!bdrv_key_required(bs)) {

        bdrv_dev_change_media_cb(bs, true);

    }



    /* throttling disk I/O limits */

    if (bs->io_limits_enabled) {

        bdrv_io_limits_enable(bs);

    }



    return 0;



unlink_and_fail:

    if (bs->is_temporary) {

        unlink(filename);

    }

    return ret;

}

int bdrv_open(BlockDriverState *bs, const char *filename, int flags,

              BlockDriver *drv)

{

    int ret;

    char tmp_filename[PATH_MAX];



    if (flags & BDRV_O_SNAPSHOT) {

        BlockDriverState *bs1;

        int64_t total_size;

        int is_protocol = 0;

        BlockDriver *bdrv_qcow2;

        QEMUOptionParameter *options;

        char backing_filename[PATH_MAX];



        





        

        bs1 = bdrv_new("");

        ret = bdrv_open(bs1, filename, 0, drv);

        if (ret < 0) {

            bdrv_delete(bs1);

            return ret;

        }

        total_size = bdrv_getlength(bs1) & BDRV_SECTOR_MASK;



        if (bs1->drv && bs1->drv->protocol_name)

            is_protocol = 1;



        bdrv_delete(bs1);



        get_tmp_filename(tmp_filename, sizeof(tmp_filename));



        

        if (is_protocol)

            snprintf(backing_filename, sizeof(backing_filename),

                     "%s", filename);

        else if (!realpath(filename, backing_filename))

            return -errno;



        bdrv_qcow2 = bdrv_find_format("qcow2");

        options = parse_option_parameters("", bdrv_qcow2->create_options, NULL);



        set_option_parameter_int(options, BLOCK_OPT_SIZE, total_size);

        set_option_parameter(options, BLOCK_OPT_BACKING_FILE, backing_filename);

        if (drv) {

            set_option_parameter(options, BLOCK_OPT_BACKING_FMT,

                drv->format_name);

        }



        ret = bdrv_create(bdrv_qcow2, tmp_filename, options);

        free_option_parameters(options);

        if (ret < 0) {

            return ret;

        }



        filename = tmp_filename;

        drv = bdrv_qcow2;

        bs->is_temporary = 1;

    }



    

    if (!drv) {

        ret = find_image_format(filename, &drv);

    }



    if (!drv) {

        goto unlink_and_fail;

    }



    

    ret = bdrv_open_common(bs, filename, flags, drv);

    if (ret < 0) {

        goto unlink_and_fail;

    }



    

    if ((flags & BDRV_O_NO_BACKING) == 0 && bs->backing_file[0] != '\0') {

        char backing_filename[PATH_MAX];

        int back_flags;

        BlockDriver *back_drv = NULL;



        bs->backing_hd = bdrv_new("");

        bdrv_get_full_backing_filename(bs, backing_filename,

                                       sizeof(backing_filename));



        if (bs->backing_format[0] != '\0') {

            back_drv = bdrv_find_format(bs->backing_format);

        }



        

        back_flags =

            flags & ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);



        ret = bdrv_open(bs->backing_hd, backing_filename, back_flags, back_drv);

        if (ret < 0) {

            bdrv_close(bs);

            return ret;

        }

        if (bs->is_temporary) {

            bs->backing_hd->keep_read_only = !(flags & BDRV_O_RDWR);

        } else {

            

            bs->backing_hd->keep_read_only = bs->keep_read_only;

        }

    }



    if (!bdrv_key_required(bs)) {

        bdrv_dev_change_media_cb(bs, true);

    }



    

    if (bs->io_limits_enabled) {

        bdrv_io_limits_enable(bs);

    }



    return 0;



unlink_and_fail:

    if (bs->is_temporary) {

        unlink(filename);

    }

    return ret;

}

        get_tmp_filename(tmp_filename, sizeof(tmp_filename));
int FUNC_0(BlockDriverState *VAR_0, const char *VAR_1, int VAR_2,

              BlockDriver *VAR_3)

{

    int VAR_4;

    char VAR_5[PATH_MAX];



    if (VAR_2 & BDRV_O_SNAPSHOT) {

        BlockDriverState *bs1;

        int64_t total_size;

        int VAR_6 = 0;

        BlockDriver *bdrv_qcow2;

        QEMUOptionParameter *options;

        char VAR_8[PATH_MAX];



        





        

        bs1 = bdrv_new("");

        VAR_4 = FUNC_0(bs1, VAR_1, 0, VAR_3);

        if (VAR_4 < 0) {

            bdrv_delete(bs1);

            return VAR_4;

        }

        total_size = bdrv_getlength(bs1) & BDRV_SECTOR_MASK;



        if (bs1->VAR_3 && bs1->VAR_3->protocol_name)

            VAR_6 = 1;



        bdrv_delete(bs1);



        get_tmp_filename(VAR_5, sizeof(VAR_5));



        

        if (VAR_6)

            snprintf(VAR_8, sizeof(VAR_8),

                     "%s", VAR_1);

        else if (!realpath(VAR_1, VAR_8))

            return -errno;



        bdrv_qcow2 = bdrv_find_format("qcow2");

        options = parse_option_parameters("", bdrv_qcow2->create_options, NULL);



        set_option_parameter_int(options, BLOCK_OPT_SIZE, total_size);

        set_option_parameter(options, BLOCK_OPT_BACKING_FILE, VAR_8);

        if (VAR_3) {

            set_option_parameter(options, BLOCK_OPT_BACKING_FMT,

                VAR_3->format_name);

        }



        VAR_4 = bdrv_create(bdrv_qcow2, VAR_5, options);

        free_option_parameters(options);

        if (VAR_4 < 0) {

            return VAR_4;

        }



        VAR_1 = VAR_5;

        VAR_3 = bdrv_qcow2;

        VAR_0->is_temporary = 1;

    }



    

    if (!VAR_3) {

        VAR_4 = find_image_format(VAR_1, &VAR_3);

    }



    if (!VAR_3) {

        goto unlink_and_fail;

    }



    

    VAR_4 = bdrv_open_common(VAR_0, VAR_1, VAR_2, VAR_3);

    if (VAR_4 < 0) {

        goto unlink_and_fail;

    }



    

    if ((VAR_2 & BDRV_O_NO_BACKING) == 0 && VAR_0->backing_file[0] != '\0') {

        char VAR_8[PATH_MAX];

        int VAR_8;

        BlockDriver *back_drv = NULL;



        VAR_0->backing_hd = bdrv_new("");

        bdrv_get_full_backing_filename(VAR_0, VAR_8,

                                       sizeof(VAR_8));



        if (VAR_0->backing_format[0] != '\0') {

            back_drv = bdrv_find_format(VAR_0->backing_format);

        }



        

        VAR_8 =

            VAR_2 & ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);



        VAR_4 = FUNC_0(VAR_0->backing_hd, VAR_8, VAR_8, back_drv);

        if (VAR_4 < 0) {

            bdrv_close(VAR_0);

            return VAR_4;

        }

        if (VAR_0->is_temporary) {

            VAR_0->backing_hd->keep_read_only = !(VAR_2 & BDRV_O_RDWR);

        } else {

            

            VAR_0->backing_hd->keep_read_only = VAR_0->keep_read_only;

        }

    }



    if (!bdrv_key_required(VAR_0)) {

        bdrv_dev_change_media_cb(VAR_0, true);

    }



    

    if (VAR_0->io_limits_enabled) {

        bdrv_io_limits_enable(VAR_0);

    }



    return 0;



unlink_and_fail:

    if (VAR_0->is_temporary) {

        unlink(VAR_1);

    }

    return VAR_4;

}

int FUNC_0(BlockDriverState *VAR_0, const char *VAR_1, int VAR_2,
BlockDriver *VAR_3)
{ int VAR_4; char VAR_5[PATH_MAX]; if (VAR_2 & BDRV_O_SNAPSHOT) { BlockDriverState *bs1; int64_t total_size; int VAR_6 = 0; BlockDriver *bdrv_qcow2; QEMUOptionParameter *options; char VAR_8[PATH_MAX]; bs1 = bdrv_new(""); VAR_4 = FUNC_0(bs1, VAR_1, 0, VAR_3); if (VAR_4 < 0) { bdrv_delete(bs1); return VAR_4; } total_size = bdrv_getlength(bs1) & BDRV_SECTOR_MASK; if (bs1->VAR_3 && bs1->VAR_3->protocol_name)
VAR_6 = 1; bdrv_delete(bs1); get_tmp_filename(VAR_5, sizeof(VAR_5)); if (VAR_6)
snprintf(VAR_8, sizeof(VAR_8),
"%s", VAR_1); else if (!realpath(VAR_1, VAR_8))
return -errno; bdrv_qcow2 = bdrv_find_format("qcow2"); options = parse_option_parameters("", bdrv_qcow2->create_options, NULL); set_option_parameter_int(options, BLOCK_OPT_SIZE, total_size); set_option_parameter(options, BLOCK_OPT_BACKING_FILE, VAR_8); if (VAR_3) { set_option_parameter(options, BLOCK_OPT_BACKING_FMT,
VAR_3->format_name); } VAR_4 = bdrv_create(bdrv_qcow2, VAR_5, options); free_option_parameters(options); if (VAR_4 < 0) { return VAR_4; } VAR_1 = VAR_5; VAR_3 = bdrv_qcow2; VAR_0->is_temporary = 1; } if (!VAR_3) { VAR_4 = find_image_format(VAR_1, &VAR_3); } if (!VAR_3) { goto unlink_and_fail; } VAR_4 = bdrv_open_common(VAR_0, VAR_1, VAR_2, VAR_3); if (VAR_4 < 0) { goto unlink_and_fail; } if ((VAR_2 & BDRV_O_NO_BACKING) == 0 && VAR_0->backing_file[0] != '\0') { char VAR_8[PATH_MAX]; int VAR_8; BlockDriver *back_drv = NULL; VAR_0->backing_hd = bdrv_new(""); bdrv_get_full_backing_filename(VAR_0, VAR_8,
sizeof(VAR_8)); if (VAR_0->backing_format[0] != '\0') { back_drv = bdrv_find_format(VAR_0->backing_format); } VAR_8 =
VAR_2 & ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING); VAR_4 = FUNC_0(VAR_0->backing_hd, VAR_8, VAR_8, back_drv); if (VAR_4 < 0) { bdrv_close(VAR_0); return VAR_4; } if (VAR_0->is_temporary) { VAR_0->backing_hd->keep_read_only = !(VAR_2 & BDRV_O_RDWR); } else { VAR_0->backing_hd->keep_read_only = VAR_0->keep_read_only; } } if (!bdrv_key_required(VAR_0)) { bdrv_dev_change_media_cb(VAR_0, true); } if (VAR_0->io_limits_enabled) { bdrv_io_limits_enable(VAR_0); } return 0; unlink_and_fail:
if (VAR_0->is_temporary) { unlink(VAR_1); } return VAR_4; }