int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
               BlockDriver *drv)
{
    int ret, open_flags;
    char tmp_filename[PATH_MAX];
    char backing_filename[PATH_MAX];
    bs->read_only = 0;
    bs->is_temporary = 0;
    bs->encrypted = 0;
    if (flags & BDRV_O_SNAPSHOT) {
        BlockDriverState *bs1;
        int64_t total_size;
        /* 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("");
        if (!bs1) {
            return -ENOMEM;
        }
        if (bdrv_open(bs1, filename, 0) < 0) {
            bdrv_delete(bs1);
            return -1;
        }
        total_size = bdrv_getlength(bs1) >> SECTOR_BITS;
        bdrv_delete(bs1);
        get_tmp_filename(tmp_filename, sizeof(tmp_filename));
        realpath(filename, backing_filename);
        if (bdrv_create(&bdrv_qcow2, tmp_filename,
                        total_size, backing_filename, 0) < 0) {
            return -1;
        }
        filename = tmp_filename;
        bs->is_temporary = 1;
    }
    pstrcpy(bs->filename, sizeof(bs->filename), filename);
    if (flags & BDRV_O_FILE) {
        drv = find_protocol(filename);
        if (!drv)
            return -ENOENT;
    } else {
        if (!drv) {
            drv = find_image_format(filename);
            if (!drv)
                return -1;
        }
    }
    bs->drv = drv;
    bs->opaque = qemu_mallocz(drv->instance_size);
    bs->total_sectors = 0; /* driver will set if it does not do getlength */
    if (bs->opaque == NULL && drv->instance_size > 0)
        return -1;
    /* Note: for compatibility, we open disk image files as RDWR, and
       RDONLY as fallback */
    if (!(flags & BDRV_O_FILE))
        open_flags = BDRV_O_RDWR | (flags & BDRV_O_DIRECT);
    else
        open_flags = flags & ~(BDRV_O_FILE | BDRV_O_SNAPSHOT);
    ret = drv->bdrv_open(bs, filename, open_flags);
    if (ret == -EACCES && !(flags & BDRV_O_FILE)) {
        ret = drv->bdrv_open(bs, filename, BDRV_O_RDONLY);
        bs->read_only = 1;
    }
    if (ret < 0) {
        qemu_free(bs->opaque);
        bs->opaque = NULL;
        bs->drv = NULL;
        return ret;
    }
    if (drv->bdrv_getlength) {
        bs->total_sectors = bdrv_getlength(bs) >> SECTOR_BITS;
    }
#ifndef _WIN32
    if (bs->is_temporary) {
        unlink(filename);
    }
#endif
    if (bs->backing_file[0] != '\0') {
        /* if there is a backing file, use it */
        bs->backing_hd = bdrv_new("");
        if (!bs->backing_hd) {
        fail:
            bdrv_close(bs);
            return -ENOMEM;
        }
        path_combine(backing_filename, sizeof(backing_filename),
                     filename, bs->backing_file);
        if (bdrv_open(bs->backing_hd, backing_filename, 0) < 0)
            goto fail;
    }
    /* call the change callback */
    bs->media_changed = 1;
    if (bs->change_cb)
        bs->change_cb(bs->change_opaque);
    return 0;
}
int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
               BlockDriver *drv)
{
    int ret, open_flags;
    char tmp_filename[PATH_MAX];
    char backing_filename[PATH_MAX];
    bs->read_only = 0;
    bs->is_temporary = 0;
    bs->encrypted = 0;
    if (flags & BDRV_O_SNAPSHOT) {
        BlockDriverState *bs1;
        int64_t total_size;
        

        
        bs1 = bdrv_new("");
        if (!bs1) {
            return -ENOMEM;
        }
        if (bdrv_open(bs1, filename, 0) < 0) {
            bdrv_delete(bs1);
            return -1;
        }
        total_size = bdrv_getlength(bs1) >> SECTOR_BITS;
        bdrv_delete(bs1);
        get_tmp_filename(tmp_filename, sizeof(tmp_filename));
        realpath(filename, backing_filename);
        if (bdrv_create(&bdrv_qcow2, tmp_filename,
                        total_size, backing_filename, 0) < 0) {
            return -1;
        }
        filename = tmp_filename;
        bs->is_temporary = 1;
    }
    pstrcpy(bs->filename, sizeof(bs->filename), filename);
    if (flags & BDRV_O_FILE) {
        drv = find_protocol(filename);
        if (!drv)
            return -ENOENT;
    } else {
        if (!drv) {
            drv = find_image_format(filename);
            if (!drv)
                return -1;
        }
    }
    bs->drv = drv;
    bs->opaque = qemu_mallocz(drv->instance_size);
    bs->total_sectors = 0; 
    if (bs->opaque == NULL && drv->instance_size > 0)
        return -1;
    

    if (!(flags & BDRV_O_FILE))
        open_flags = BDRV_O_RDWR | (flags & BDRV_O_DIRECT);
    else
        open_flags = flags & ~(BDRV_O_FILE | BDRV_O_SNAPSHOT);
    ret = drv->bdrv_open(bs, filename, open_flags);
    if (ret == -EACCES && !(flags & BDRV_O_FILE)) {
        ret = drv->bdrv_open(bs, filename, BDRV_O_RDONLY);
        bs->read_only = 1;
    }
    if (ret < 0) {
        qemu_free(bs->opaque);
        bs->opaque = NULL;
        bs->drv = NULL;
        return ret;
    }
    if (drv->bdrv_getlength) {
        bs->total_sectors = bdrv_getlength(bs) >> SECTOR_BITS;
    }
#ifndef _WIN32
    if (bs->is_temporary) {
        unlink(filename);
    }
#endif
    if (bs->backing_file[0] != '\0') {
        
        bs->backing_hd = bdrv_new("");
        if (!bs->backing_hd) {
        fail:
            bdrv_close(bs);
            return -ENOMEM;
        }
        path_combine(backing_filename, sizeof(backing_filename),
                     filename, bs->backing_file);
        if (bdrv_open(bs->backing_hd, backing_filename, 0) < 0)
            goto fail;
    }
    
    bs->media_changed = 1;
    if (bs->change_cb)
        bs->change_cb(bs->change_opaque);
    return 0;
}
int FUNC_0(BlockDriverState *VAR_0, const char *VAR_1, int VAR_2,
               BlockDriver *VAR_3)
{
    int VAR_4, VAR_5;
    char VAR_6[PATH_MAX];
    char VAR_7[PATH_MAX];
    VAR_0->read_only = 0;
    VAR_0->is_temporary = 0;
    VAR_0->encrypted = 0;
    if (VAR_2 & BDRV_O_SNAPSHOT) {
        BlockDriverState *bs1;
        int64_t total_size;
        

        
        bs1 = bdrv_new("");
        if (!bs1) {
            return -ENOMEM;
        }
        if (bdrv_open(bs1, VAR_1, 0) < 0) {
            bdrv_delete(bs1);
            return -1;
        }
        total_size = bdrv_getlength(bs1) >> SECTOR_BITS;
        bdrv_delete(bs1);
        get_tmp_filename(VAR_6, sizeof(VAR_6));
        realpath(VAR_1, VAR_7);
        if (bdrv_create(&bdrv_qcow2, VAR_6,
                        total_size, VAR_7, 0) < 0) {
            return -1;
        }
        VAR_1 = VAR_6;
        VAR_0->is_temporary = 1;
    }
    pstrcpy(VAR_0->VAR_1, sizeof(VAR_0->VAR_1), VAR_1);
    if (VAR_2 & BDRV_O_FILE) {
        VAR_3 = find_protocol(VAR_1);
        if (!VAR_3)
            return -ENOENT;
    } else {
        if (!VAR_3) {
            VAR_3 = find_image_format(VAR_1);
            if (!VAR_3)
                return -1;
        }
    }
    VAR_0->VAR_3 = VAR_3;
    VAR_0->opaque = qemu_mallocz(VAR_3->instance_size);
    VAR_0->total_sectors = 0; 
    if (VAR_0->opaque == NULL && VAR_3->instance_size > 0)
        return -1;
    

    if (!(VAR_2 & BDRV_O_FILE))
        VAR_5 = BDRV_O_RDWR | (VAR_2 & BDRV_O_DIRECT);
    else
        VAR_5 = VAR_2 & ~(BDRV_O_FILE | BDRV_O_SNAPSHOT);
    VAR_4 = VAR_3->bdrv_open(VAR_0, VAR_1, VAR_5);
    if (VAR_4 == -EACCES && !(VAR_2 & BDRV_O_FILE)) {
        VAR_4 = VAR_3->bdrv_open(VAR_0, VAR_1, BDRV_O_RDONLY);
        VAR_0->read_only = 1;
    }
    if (VAR_4 < 0) {
        qemu_free(VAR_0->opaque);
        VAR_0->opaque = NULL;
        VAR_0->VAR_3 = NULL;
        return VAR_4;
    }
    if (VAR_3->bdrv_getlength) {
        VAR_0->total_sectors = bdrv_getlength(VAR_0) >> SECTOR_BITS;
    }
#ifndef _WIN32
    if (VAR_0->is_temporary) {
        unlink(VAR_1);
    }
#endif
    if (VAR_0->backing_file[0] != '\0') {
        
        VAR_0->backing_hd = bdrv_new("");
        if (!VAR_0->backing_hd) {
        fail:
            bdrv_close(VAR_0);
            return -ENOMEM;
        }
        path_combine(VAR_7, sizeof(VAR_7),
                     VAR_1, VAR_0->backing_file);
        if (bdrv_open(VAR_0->backing_hd, VAR_7, 0) < 0)
            goto fail;
    }
    
    VAR_0->media_changed = 1;
    if (VAR_0->change_cb)
        VAR_0->change_cb(VAR_0->change_opaque);
    return 0;
}
int FUNC_0(BlockDriverState *VAR_0, const char *VAR_1, int VAR_2,
BlockDriver *VAR_3)
{ int VAR_4, VAR_5; char VAR_6[PATH_MAX]; char VAR_7[PATH_MAX]; VAR_0->read_only = 0; VAR_0->is_temporary = 0; VAR_0->encrypted = 0; if (VAR_2 & BDRV_O_SNAPSHOT) { BlockDriverState *bs1; int64_t total_size; bs1 = bdrv_new(""); if (!bs1) { return -ENOMEM; } if (bdrv_open(bs1, VAR_1, 0) < 0) { bdrv_delete(bs1); return -1; } total_size = bdrv_getlength(bs1) >> SECTOR_BITS; bdrv_delete(bs1); get_tmp_filename(VAR_6, sizeof(VAR_6)); realpath(VAR_1, VAR_7); if (bdrv_create(&bdrv_qcow2, VAR_6,
total_size, VAR_7, 0) < 0) { return -1; } VAR_1 = VAR_6; VAR_0->is_temporary = 1; } pstrcpy(VAR_0->VAR_1, sizeof(VAR_0->VAR_1), VAR_1); if (VAR_2 & BDRV_O_FILE) { VAR_3 = find_protocol(VAR_1); if (!VAR_3)
return -ENOENT; } else { if (!VAR_3) { VAR_3 = find_image_format(VAR_1); if (!VAR_3)
return -1; } } VAR_0->VAR_3 = VAR_3; VAR_0->opaque = qemu_mallocz(VAR_3->instance_size); VAR_0->total_sectors = 0; if (VAR_0->opaque == NULL && VAR_3->instance_size > 0)
return -1; if (!(VAR_2 & BDRV_O_FILE))
VAR_5 = BDRV_O_RDWR | (VAR_2 & BDRV_O_DIRECT); else
VAR_5 = VAR_2 & ~(BDRV_O_FILE | BDRV_O_SNAPSHOT); VAR_4 = VAR_3->bdrv_open(VAR_0, VAR_1, VAR_5); if (VAR_4 == -EACCES && !(VAR_2 & BDRV_O_FILE)) { VAR_4 = VAR_3->bdrv_open(VAR_0, VAR_1, BDRV_O_RDONLY); VAR_0->read_only = 1; } if (VAR_4 < 0) { qemu_free(VAR_0->opaque); VAR_0->opaque = NULL; VAR_0->VAR_3 = NULL; return VAR_4; } if (VAR_3->bdrv_getlength) { VAR_0->total_sectors = bdrv_getlength(VAR_0) >> SECTOR_BITS; } #ifndef _WIN32
if (VAR_0->is_temporary) { unlink(VAR_1); } #endif
if (VAR_0->backing_file[0] != '\0') { VAR_0->backing_hd = bdrv_new(""); if (!VAR_0->backing_hd) { fail:
bdrv_close(VAR_0); return -ENOMEM; } path_combine(VAR_7, sizeof(VAR_7),
VAR_1, VAR_0->backing_file); if (bdrv_open(VAR_0->backing_hd, VAR_7, 0) < 0)
goto fail; } VAR_0->media_changed = 1; if (VAR_0->change_cb)
VAR_0->change_cb(VAR_0->change_opaque); return 0; }