Example #1
0
static int parallels_open(BlockDriverState *bs, int flags)
{
    BDRVParallelsState *s = bs->opaque;
    int i;
    struct parallels_header ph;

    bs->read_only = 1; // no write support yet

    if (bdrv_pread(bs->file, 0, &ph, sizeof(ph)) != sizeof(ph))
        goto fail;

    if (memcmp(ph.magic, HEADER_MAGIC, 16) ||
	(le32_to_cpu(ph.version) != HEADER_VERSION)) {
        goto fail;
    }

    bs->total_sectors = le32_to_cpu(ph.nb_sectors);

    s->tracks = le32_to_cpu(ph.tracks);

    s->catalog_size = le32_to_cpu(ph.catalog_entries);
    s->catalog_bitmap = g_malloc(s->catalog_size * 4);
    if (bdrv_pread(bs->file, 64, s->catalog_bitmap, s->catalog_size * 4) !=
	s->catalog_size * 4)
	goto fail;
    for (i = 0; i < s->catalog_size; i++)
	le32_to_cpus(&s->catalog_bitmap[i]);

    return 0;
fail:
    if (s->catalog_bitmap)
	g_free(s->catalog_bitmap);
    return -1;
}
Example #2
0
static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
                          Error **errp)
{
    BDRVParallelsState *s = bs->opaque;
    int i;
    struct parallels_header ph;
    int ret;

    bs->read_only = 1; // no write support yet

    ret = bdrv_pread(bs->file, 0, &ph, sizeof(ph));
    if (ret < 0) {
        goto fail;
    }

    if (memcmp(ph.magic, HEADER_MAGIC, 16) ||
        (le32_to_cpu(ph.version) != HEADER_VERSION)) {
        error_setg(errp, "Image not in Parallels format");
        ret = -EINVAL;
        goto fail;
    }

    bs->total_sectors = le32_to_cpu(ph.nb_sectors);

    s->tracks = le32_to_cpu(ph.tracks);
    if (s->tracks == 0) {
        error_setg(errp, "Invalid image: Zero sectors per track");
        ret = -EINVAL;
        goto fail;
    }

    s->catalog_size = le32_to_cpu(ph.catalog_entries);
    if (s->catalog_size > INT_MAX / 4) {
        error_setg(errp, "Catalog too large");
        ret = -EFBIG;
        goto fail;
    }
    s->catalog_bitmap = g_try_malloc(s->catalog_size * 4);
    if (s->catalog_size && s->catalog_bitmap == NULL) {
        ret = -ENOMEM;
        goto fail;
    }

    ret = bdrv_pread(bs->file, 64, s->catalog_bitmap, s->catalog_size * 4);
    if (ret < 0) {
        goto fail;
    }

    for (i = 0; i < s->catalog_size; i++)
	le32_to_cpus(&s->catalog_bitmap[i]);

    qemu_co_mutex_init(&s->lock);
    return 0;

fail:
    g_free(s->catalog_bitmap);
    return ret;
}
Example #3
0
static inline int dmg_read_chunk(BlockDriverState *bs, int sector_num)
{
    BDRVDMGState *s = bs->opaque;

    if(!is_sector_in_chunk(s,s->current_chunk,sector_num)) {
	int ret;
	uint32_t chunk = search_chunk(s,sector_num);

	if(chunk>=s->n_chunks)
	    return -1;

	s->current_chunk = s->n_chunks;
	switch(s->types[chunk]) {
	case 0x80000005: { /* zlib compressed */
	    int i;

	    /* we need to buffer, because only the chunk as whole can be
	     * inflated. */
	    i=0;
	    do {
                ret = bdrv_pread(bs->file, s->offsets[chunk] + i,
                                 s->compressed_chunk+i, s->lengths[chunk]-i);
		if(ret<0 && errno==EINTR)
		    ret=0;
		i+=ret;
	    } while(ret>=0 && ret+i<s->lengths[chunk]);

	    if (ret != s->lengths[chunk])
		return -1;

	    s->zstream.next_in = s->compressed_chunk;
	    s->zstream.avail_in = s->lengths[chunk];
	    s->zstream.next_out = s->uncompressed_chunk;
	    s->zstream.avail_out = 512*s->sectorcounts[chunk];
	    ret = inflateReset(&s->zstream);
	    if(ret != Z_OK)
		return -1;
	    ret = inflate(&s->zstream, Z_FINISH);
	    if(ret != Z_STREAM_END || s->zstream.total_out != 512*s->sectorcounts[chunk])
		return -1;
	    break; }
	case 1: /* copy */
	    ret = bdrv_pread(bs->file, s->offsets[chunk],
                             s->uncompressed_chunk, s->lengths[chunk]);
	    if (ret != s->lengths[chunk])
		return -1;
	    break;
	case 2: /* zero */
	    memset(s->uncompressed_chunk, 0, 512*s->sectorcounts[chunk]);
	    break;
	}
	s->current_chunk = chunk;
    }
    return 0;
}
Example #4
0
int qcow2_read_snapshots(BlockDriverState *bs)
{
    BDRVQcowState *s = bs->opaque;
    QCowSnapshotHeader h;
    QCowSnapshot *sn;
    int i, id_str_size, name_size;
    int64_t offset;
    uint32_t extra_data_size;

    if (!s->nb_snapshots) {
        s->snapshots = NULL;
        s->snapshots_size = 0;
        return 0;
    }

    offset = s->snapshots_offset;
    s->snapshots = qemu_mallocz(s->nb_snapshots * sizeof(QCowSnapshot));
    for(i = 0; i < s->nb_snapshots; i++) {
        offset = align_offset(offset, 8);
        if (bdrv_pread(s->hd, offset, &h, sizeof(h)) != sizeof(h))
            goto fail;
        offset += sizeof(h);
        sn = s->snapshots + i;
        sn->l1_table_offset = be64_to_cpu(h.l1_table_offset);
        sn->l1_size = be32_to_cpu(h.l1_size);
        sn->vm_state_size = be32_to_cpu(h.vm_state_size);
        sn->date_sec = be32_to_cpu(h.date_sec);
        sn->date_nsec = be32_to_cpu(h.date_nsec);
        sn->vm_clock_nsec = be64_to_cpu(h.vm_clock_nsec);
        extra_data_size = be32_to_cpu(h.extra_data_size);

        id_str_size = be16_to_cpu(h.id_str_size);
        name_size = be16_to_cpu(h.name_size);

        offset += extra_data_size;

        sn->id_str = qemu_malloc(id_str_size + 1);
        if (bdrv_pread(s->hd, offset, sn->id_str, id_str_size) != id_str_size)
            goto fail;
        offset += id_str_size;
        sn->id_str[id_str_size] = '\0';

        sn->name = qemu_malloc(name_size + 1);
        if (bdrv_pread(s->hd, offset, sn->name, name_size) != name_size)
            goto fail;
        offset += name_size;
        sn->name[name_size] = '\0';
    }
    s->snapshots_size = offset - s->snapshots_offset;
    return 0;
 fail:
    qcow2_free_snapshots(bs);
    return -1;
}
Example #5
0
static void test_sync_op_pread(BdrvChild *c)
{
    uint8_t buf[512];
    int ret;

    /* Success */
    ret = bdrv_pread(c, 0, buf, sizeof(buf));
    g_assert_cmpint(ret, ==, 512);

    /* Early error: Negative offset */
    ret = bdrv_pread(c, -2, buf, sizeof(buf));
    g_assert_cmpint(ret, ==, -EIO);
}
Example #6
0
static int cloop_open(BlockDriverState *bs, int flags)
{
    BDRVCloopState *s = bs->opaque;
    uint32_t offsets_size, max_compressed_block_size = 1, i;

    bs->read_only = 1;

    /* read header */
    if (bdrv_pread(bs->file, 128, &s->block_size, 4) < 4) {
        goto cloop_close;
    }
    s->block_size = be32_to_cpu(s->block_size);

    if (bdrv_pread(bs->file, 128 + 4, &s->n_blocks, 4) < 4) {
        goto cloop_close;
    }
    s->n_blocks = be32_to_cpu(s->n_blocks);

    /* read offsets */
    offsets_size = s->n_blocks * sizeof(uint64_t);
    s->offsets = g_malloc(offsets_size);
    if (bdrv_pread(bs->file, 128 + 4 + 4, s->offsets, offsets_size) <
            offsets_size) {
        goto cloop_close;
    }
    for(i=0;i<s->n_blocks;i++) {
        s->offsets[i] = be64_to_cpu(s->offsets[i]);
        if (i > 0) {
            uint32_t size = s->offsets[i] - s->offsets[i - 1];
            if (size > max_compressed_block_size) {
                max_compressed_block_size = size;
            }
        }
    }

    /* initialize zlib engine */
    s->compressed_block = g_malloc(max_compressed_block_size + 1);
    s->uncompressed_block = g_malloc(s->block_size);
    if (inflateInit(&s->zstream) != Z_OK) {
        goto cloop_close;
    }
    s->current_block = s->n_blocks;

    s->sectors_per_block = s->block_size/512;
    bs->total_sectors = s->n_blocks * s->sectors_per_block;
    qemu_co_mutex_init(&s->lock);
    return 0;

cloop_close:
    return -1;
}
Example #7
0
static int vmdk_open_desc_file(BlockDriverState *bs, int flags,
                               int64_t desc_offset)
{
    int ret;
    char buf[2048];
    char ct[128];
    BDRVVmdkState *s = bs->opaque;

    ret = bdrv_pread(bs->file, desc_offset, buf, sizeof(buf));
    if (ret < 0) {
        return ret;
    }
    buf[2047] = '\0';
    if (vmdk_parse_description(buf, "createType", ct, sizeof(ct))) {
        return -EINVAL;
    }
    if (strcmp(ct, "monolithicFlat") &&
        strcmp(ct, "twoGbMaxExtentSparse") &&
        strcmp(ct, "twoGbMaxExtentFlat")) {
        fprintf(stderr,
                "VMDK: Not supported image type \"%s\""".\n", ct);
        return -ENOTSUP;
    }
    s->desc_offset = 0;
    return vmdk_parse_extents(buf, bs, bs->file->filename);
}
Example #8
0
static int vmdk_open_vmdk3(BlockDriverState *bs,
                           BlockDriverState *file,
                           int flags)
{
    int ret;
    uint32_t magic;
    VMDK3Header header;
    VmdkExtent *extent;

    ret = bdrv_pread(file, sizeof(magic), &header, sizeof(header));
    if (ret < 0) {
        return ret;
    }
    extent = vmdk_add_extent(bs,
                             bs->file, false,
                             le32_to_cpu(header.disk_sectors),
                             le32_to_cpu(header.l1dir_offset) << 9,
                             0, 1 << 6, 1 << 9,
                             le32_to_cpu(header.granularity));
    ret = vmdk_init_tables(bs, extent);
    if (ret) {
        /* free extent allocated by vmdk_add_extent */
        vmdk_free_last_extent(bs);
    }
    return ret;
}
Example #9
0
static int vmdk_parent_open(BlockDriverState *bs)
{
    char *p_name;
    char desc[DESC_SIZE + 1];
    BDRVVmdkState *s = bs->opaque;
    int ret;

    desc[DESC_SIZE] = '\0';
    ret = bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE);
    if (ret < 0) {
        return ret;
    }

    p_name = strstr(desc, "parentFileNameHint");
    if (p_name != NULL) {
        char *end_name;

        p_name += sizeof("parentFileNameHint") + 1;
        end_name = strchr(p_name, '\"');
        if (end_name == NULL) {
            return -EINVAL;
        }
        if ((end_name - p_name) > sizeof(bs->backing_file) - 1) {
            return -EINVAL;
        }

        pstrcpy(bs->backing_file, end_name - p_name + 1, p_name);
    }

    return 0;
}
Example #10
0
static int vmdk_write_cid(BlockDriverState *bs, uint32_t cid)
{
    char desc[DESC_SIZE], tmp_desc[DESC_SIZE];
    char *p_name, *tmp_str;
    BDRVVmdkState *s = bs->opaque;
    int ret;

    ret = bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE);
    if (ret < 0) {
        return ret;
    }

    desc[DESC_SIZE - 1] = '\0';
    tmp_str = strstr(desc, "parentCID");
    if (tmp_str == NULL) {
        return -EINVAL;
    }

    pstrcpy(tmp_desc, sizeof(tmp_desc), tmp_str);
    p_name = strstr(desc, "CID");
    if (p_name != NULL) {
        p_name += sizeof("CID");
        snprintf(p_name, sizeof(desc) - (p_name - desc), "%x\n", cid);
        pstrcat(desc, sizeof(desc), tmp_desc);
    }

    ret = bdrv_pwrite_sync(bs->file, s->desc_offset, desc, DESC_SIZE);
    if (ret < 0) {
        return ret;
    }

    return 0;
}
Example #11
0
static uint32_t vmdk_read_cid(BlockDriverState *bs, int parent)
{
    char desc[DESC_SIZE];
    uint32_t cid = 0xffffffff;
    const char *p_name, *cid_str;
    size_t cid_str_size;
    BDRVVmdkState *s = bs->opaque;
    int ret;

    ret = bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE);
    if (ret < 0) {
        return 0;
    }

    if (parent) {
        cid_str = "parentCID";
        cid_str_size = sizeof("parentCID");
    } else {
        cid_str = "CID";
        cid_str_size = sizeof("CID");
    }

    desc[DESC_SIZE - 1] = '\0';
    p_name = strstr(desc, cid_str);
    if (p_name != NULL) {
        p_name += cid_str_size;
        sscanf(p_name, "%x", &cid);
    }

    return cid;
}
Example #12
0
static off_t read_off(BlockDriverState *bs, int64_t offset)
{
	uint64_t buffer;
	if (bdrv_pread(bs->file, offset, &buffer, 8) < 8)
		return 0;
	return be64_to_cpu(buffer);
}
Example #13
0
static inline int cloop_read_block(BlockDriverState *bs, int block_num)
{
    BDRVCloopState *s = bs->opaque;

    if (s->current_block != block_num) {
        int ret;
        uint32_t bytes = s->offsets[block_num + 1] - s->offsets[block_num];

        ret = bdrv_pread(bs->file->bs, s->offsets[block_num],
                         s->compressed_block, bytes);
        if (ret != bytes) {
            return -1;
        }

        s->zstream.next_in = s->compressed_block;
        s->zstream.avail_in = bytes;
        s->zstream.next_out = s->uncompressed_block;
        s->zstream.avail_out = s->block_size;
        ret = inflateReset(&s->zstream);
        if (ret != Z_OK) {
            return -1;
        }
        ret = inflate(&s->zstream, Z_FINISH);
        if (ret != Z_STREAM_END || s->zstream.total_out != s->block_size) {
            return -1;
        }

        s->current_block = block_num;
    }
    return 0;
}
Example #14
0
static int do_pread(char *buf, int64_t offset, int count, int *total)
{
    *total = bdrv_pread(bs, offset, (uint8_t *)buf, count);
    if (*total < 0)
        return *total;
    return 1;
}
Example #15
0
/* Reads num_sectors from the log (all log sectors are 4096 bytes),
 * into buffer 'buffer'.  Upon return, *sectors_read will contain
 * the number of sectors successfully read.
 *
 * It is assumed that 'buffer' is already allocated, and of sufficient
 * size (i.e. >= 4096*num_sectors).
 *
 * If 'peek' is true, then the tail (read) pointer for the circular buffer is
 * not modified.
 *
 * 0 is returned on success, -errno otherwise.  */
static int vhdx_log_read_sectors(BlockDriverState *bs, VHDXLogEntries *log,
                                 uint32_t *sectors_read, void *buffer,
                                 uint32_t num_sectors, bool peek)
{
    int ret = 0;
    uint64_t offset;
    uint32_t read;

    read = log->read;

    *sectors_read = 0;
    while (num_sectors) {
        if (read == log->write) {
            /* empty */
            break;
        }
        offset = log->offset + read;

        ret = bdrv_pread(bs->file, offset, buffer, VHDX_LOG_SECTOR_SIZE);
        if (ret < 0) {
            goto exit;
        }
        read = vhdx_log_inc_idx(read, log->length);

        *sectors_read = *sectors_read + 1;
        num_sectors--;
    }

exit:
    if (!peek) {
        log->read = read;
    }
    return ret;
}
Example #16
0
static int qcow2_cache_do_get(BlockDriverState *bs, Qcow2Cache *c,
    uint64_t offset, void **table, bool read_from_disk)
{
    BDRVQcowState *s = bs->opaque;
    int i;
    int ret;

    trace_qcow2_cache_get(qemu_coroutine_self(), c == s->l2_table_cache,
                          offset, read_from_disk);

    /* Check if the table is already cached */
    for (i = 0; i < c->size; i++) {
        if (c->entries[i].offset == offset) {
            goto found;
        }
    }

    /* If not, write a table back and replace it */
    i = qcow2_cache_find_entry_to_replace(c);
    trace_qcow2_cache_get_replace_entry(qemu_coroutine_self(),
                                        c == s->l2_table_cache, i);
    if (i < 0) {
        return i;
    }

    ret = qcow2_cache_entry_flush(bs, c, i);
    if (ret < 0) {
        return ret;
    }

    trace_qcow2_cache_get_read(qemu_coroutine_self(),
                               c == s->l2_table_cache, i);
    c->entries[i].offset = 0;
    if (read_from_disk) {
        if (c == s->l2_table_cache) {
            BLKDBG_EVENT(bs->file, BLKDBG_L2_LOAD);
        }

        ret = bdrv_pread(bs->file, offset, c->entries[i].table, s->cluster_size);
        if (ret < 0) {
            return ret;
        }
    }

    /* Give the table some hits for the start so that it won't be replaced
     * immediately. The number 32 is completely arbitrary. */
    c->entries[i].cache_hits = 32;
    c->entries[i].offset = offset;

    /* And return the right table */
found:
    c->entries[i].cache_hits++;
    c->entries[i].ref++;
    *table = c->entries[i].table;

    trace_qcow2_cache_get_done(qemu_coroutine_self(),
                               c == s->l2_table_cache, i);

    return 0;
}
Example #17
0
static off_t read_uint32(BlockDriverState *bs, int64_t offset)
{
	uint32_t buffer;
	if (bdrv_pread(bs->file, offset, &buffer, 4) < 4)
		return 0;
	return be32_to_cpu(buffer);
}
Example #18
0
int qcow2_snapshot_load_tmp(BlockDriverState *bs, const char *snapshot_name)
{
    int i, snapshot_index, l1_size2;
    BDRVQcowState *s = bs->opaque;
    QCowSnapshot *sn;

    snapshot_index = find_snapshot_by_id_or_name(bs, snapshot_name);
    if (snapshot_index < 0) {
        return -ENOENT;
    }

    sn = &s->snapshots[snapshot_index];
    s->l1_size = sn->l1_size;
    l1_size2 = s->l1_size * sizeof(uint64_t);
    if (s->l1_table != NULL) {
        g_free(s->l1_table);
    }

    s->l1_table_offset = sn->l1_table_offset;
    s->l1_table = g_malloc0(align_offset(l1_size2, 512));

    if (bdrv_pread(bs->file, sn->l1_table_offset,
                   s->l1_table, l1_size2) != l1_size2) {
        return -1;
    }

    for(i = 0; i < s->l1_size; i++) {
        be64_to_cpus(&s->l1_table[i]);
    }
    return 0;
}
Example #19
0
File: tar.c Project: jkivilin/qemu
/* This is where we get a request from a caller to read something */
static BlockDriverAIOCB *tar_aio_readv(BlockDriverState *bs,
        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
        BlockDriverCompletionFunc *cb, void *opaque)
{
    BDRVTarState *s = bs->opaque;
    SparseCache *sparse;
    int64_t sec_file = sector_num + s->file_sec;
    int64_t start = sector_num * SECTOR_SIZE;
    int64_t end = start + (nb_sectors * SECTOR_SIZE);
    int i;
    TarAIOCB *acb;

    for (i = 0; i < s->sparse_num; i++) {
        sparse = &s->sparse[i];
        if (sparse->start > end) {
            /* We expect the cache to be start increasing */
            break;
        } else if ((sparse->start < start) && (sparse->end <= start)) {
            /* sparse before our offset */
            sec_file -= (sparse->end - sparse->start) / SECTOR_SIZE;
        } else if ((sparse->start <= start) && (sparse->end >= end)) {
            /* all our sectors are sparse */
            char *buf = g_malloc0(nb_sectors * SECTOR_SIZE);

            acb = qemu_aio_get(&tar_aiocb_info, bs, cb, opaque);
            qemu_iovec_from_buf(qiov, 0, buf, nb_sectors * SECTOR_SIZE);
            g_free(buf);
            acb->bh = qemu_bh_new(tar_sparse_cb, acb);
            qemu_bh_schedule(acb->bh);

            return &acb->common;
        } else if (((sparse->start >= start) && (sparse->start < end)) ||
                   ((sparse->end >= start) && (sparse->end < end))) {
            /* we're semi-sparse (worst case) */
            /* let's go synchronous and read all sectors individually */
            char *buf = g_malloc(nb_sectors * SECTOR_SIZE);
            uint64_t offs;

            for (offs = 0; offs < (nb_sectors * SECTOR_SIZE);
                 offs += SECTOR_SIZE) {
                bdrv_pread(bs, (sector_num * SECTOR_SIZE) + offs,
                           buf + offs, SECTOR_SIZE);
            }

            qemu_iovec_from_buf(qiov, 0, buf, nb_sectors * SECTOR_SIZE);
            acb = qemu_aio_get(&tar_aiocb_info, bs, cb, opaque);
            acb->bh = qemu_bh_new(tar_sparse_cb, acb);
            qemu_bh_schedule(acb->bh);

            return &acb->common;
        }
    }

    return bdrv_aio_readv(s->hd, sec_file, qiov, nb_sectors,
                          cb, opaque);
}
Example #20
0
int qcow2_snapshot_load_tmp(BlockDriverState *bs,
                            const char *snapshot_id,
                            const char *name,
                            Error **errp)
{
    int i, snapshot_index;
    BDRVQcow2State *s = bs->opaque;
    QCowSnapshot *sn;
    uint64_t *new_l1_table;
    int new_l1_bytes;
    int ret;

    assert(bs->read_only);

    /* Search the snapshot */
    snapshot_index = find_snapshot_by_id_and_name(bs, snapshot_id, name);
    if (snapshot_index < 0) {
        error_setg(errp,
                   "Can't find snapshot");
        return -ENOENT;
    }
    sn = &s->snapshots[snapshot_index];

    /* Allocate and read in the snapshot's L1 table */
    if (sn->l1_size > QCOW_MAX_L1_SIZE / sizeof(uint64_t)) {
        error_setg(errp, "Snapshot L1 table too large");
        return -EFBIG;
    }
    new_l1_bytes = sn->l1_size * sizeof(uint64_t);
    new_l1_table = qemu_try_blockalign(bs->file->bs,
                                       align_offset(new_l1_bytes, 512));
    if (new_l1_table == NULL) {
        return -ENOMEM;
    }

    ret = bdrv_pread(bs->file->bs, sn->l1_table_offset,
                     new_l1_table, new_l1_bytes);
    if (ret < 0) {
        error_setg(errp, "Failed to read l1 table for snapshot");
        qemu_vfree(new_l1_table);
        return ret;
    }

    /* Switch the L1 table */
    qemu_vfree(s->l1_table);

    s->l1_size = sn->l1_size;
    s->l1_table_offset = sn->l1_table_offset;
    s->l1_table = new_l1_table;

    for(i = 0;i < s->l1_size; i++) {
        be64_to_cpus(&s->l1_table[i]);
    }

    return 0;
}
Example #21
0
static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
                          Error **errp)
{
    BDRVParallelsState *s = bs->opaque;
    int i;
    struct parallels_header ph;
    int ret;

    bs->read_only = 1; // no write support yet

    ret = bdrv_pread(bs->file, 0, &ph, sizeof(ph));
    if (ret < 0) {
        goto fail;
    }

    if (memcmp(ph.magic, HEADER_MAGIC, 16) ||
        (le32_to_cpu(ph.version) != HEADER_VERSION)) {
        ret = -EMEDIUMTYPE;
        goto fail;
    }

    bs->total_sectors = le32_to_cpu(ph.nb_sectors);

    s->tracks = le32_to_cpu(ph.tracks);

    s->catalog_size = le32_to_cpu(ph.catalog_entries);
    s->catalog_bitmap = g_malloc(s->catalog_size * 4);

    ret = bdrv_pread(bs->file, 64, s->catalog_bitmap, s->catalog_size * 4);
    if (ret < 0) {
        goto fail;
    }

    for (i = 0; i < s->catalog_size; i++)
	le32_to_cpus(&s->catalog_bitmap[i]);

    qemu_co_mutex_init(&s->lock);
    return 0;

fail:
    g_free(s->catalog_bitmap);
    return ret;
}
Example #22
0
static int vmdk_init_tables(BlockDriverState *bs, VmdkExtent *extent)
{
    int ret;
    int l1_size, i;

    /* read the L1 table */
    l1_size = extent->l1_size * sizeof(uint32_t);
    extent->l1_table = g_malloc(l1_size);
    ret = bdrv_pread(extent->file,
                    extent->l1_table_offset,
                    extent->l1_table,
                    l1_size);
    if (ret < 0) {
        goto fail_l1;
    }
    for (i = 0; i < extent->l1_size; i++) {
        le32_to_cpus(&extent->l1_table[i]);
    }

    if (extent->l1_backup_table_offset) {
        extent->l1_backup_table = g_malloc(l1_size);
        ret = bdrv_pread(extent->file,
                        extent->l1_backup_table_offset,
                        extent->l1_backup_table,
                        l1_size);
        if (ret < 0) {
            goto fail_l1b;
        }
        for (i = 0; i < extent->l1_size; i++) {
            le32_to_cpus(&extent->l1_backup_table[i]);
        }
    }

    extent->l2_cache =
        g_malloc(extent->l2_size * L2_CACHE_SIZE * sizeof(uint32_t));
    return 0;
 fail_l1b:
    g_free(extent->l1_backup_table);
 fail_l1:
    g_free(extent->l1_table);
    return ret;
}
Example #23
0
/* load_bitmap_data
 * @bitmap_table entries must satisfy specification constraints.
 * @bitmap must be cleared */
static int load_bitmap_data(BlockDriverState *bs,
                            const uint64_t *bitmap_table,
                            uint32_t bitmap_table_size,
                            BdrvDirtyBitmap *bitmap)
{
    int ret = 0;
    BDRVQcow2State *s = bs->opaque;
    uint64_t offset, limit;
    uint64_t bm_size = bdrv_dirty_bitmap_size(bitmap);
    uint8_t *buf = NULL;
    uint64_t i, tab_size =
            size_to_clusters(s,
                bdrv_dirty_bitmap_serialization_size(bitmap, 0, bm_size));

    if (tab_size != bitmap_table_size || tab_size > BME_MAX_TABLE_SIZE) {
        return -EINVAL;
    }

    buf = g_malloc(s->cluster_size);
    limit = bytes_covered_by_bitmap_cluster(s, bitmap);
    for (i = 0, offset = 0; i < tab_size; ++i, offset += limit) {
        uint64_t count = MIN(bm_size - offset, limit);
        uint64_t entry = bitmap_table[i];
        uint64_t data_offset = entry & BME_TABLE_ENTRY_OFFSET_MASK;

        assert(check_table_entry(entry, s->cluster_size) == 0);

        if (data_offset == 0) {
            if (entry & BME_TABLE_ENTRY_FLAG_ALL_ONES) {
                bdrv_dirty_bitmap_deserialize_ones(bitmap, offset, count,
                                                   false);
            } else {
                /* No need to deserialize zeros because the dirty bitmap is
                 * already cleared */
            }
        } else {
            ret = bdrv_pread(bs->file, data_offset, buf, s->cluster_size);
            if (ret < 0) {
                goto finish;
            }
            bdrv_dirty_bitmap_deserialize_part(bitmap, buf, offset, count,
                                               false);
        }
    }
    ret = 0;

    bdrv_dirty_bitmap_deserialize_finish(bitmap);

finish:
    g_free(buf);

    return ret;
}
Example #24
0
File: dmg.c Project: heiher/qemu
static int dmg_read_plist_xml(BlockDriverState *bs, DmgHeaderState *ds,
                              uint64_t info_begin, uint64_t info_length)
{
    BDRVDMGState *s = bs->opaque;
    int ret;
    uint8_t *buffer = NULL;
    char *data_begin, *data_end;

    /* Have at least some length to avoid NULL for g_malloc. Attempt to set a
     * safe upper cap on the data length. A test sample had a XML length of
     * about 1 MiB. */
    if (info_length == 0 || info_length > 16 * 1024 * 1024) {
        ret = -EINVAL;
        goto fail;
    }

    buffer = g_malloc(info_length + 1);
    buffer[info_length] = '\0';
    ret = bdrv_pread(bs->file, info_begin, buffer, info_length);
    if (ret != info_length) {
        ret = -EINVAL;
        goto fail;
    }

    /* look for <data>...</data>. The data is 284 (0x11c) bytes after base64
     * decode. The actual data element has 431 (0x1af) bytes which includes tabs
     * and line feeds. */
    data_end = (char *)buffer;
    while ((data_begin = strstr(data_end, "<data>")) != NULL) {
        guchar *mish;
        gsize out_len = 0;

        data_begin += 6;
        data_end = strstr(data_begin, "</data>");
        /* malformed XML? */
        if (data_end == NULL) {
            ret = -EINVAL;
            goto fail;
        }
        *data_end++ = '\0';
        mish = g_base64_decode(data_begin, &out_len);
        ret = dmg_read_mish_block(s, ds, mish, (uint32_t)out_len);
        g_free(mish);
        if (ret < 0) {
            goto fail;
        }
    }
    ret = 0;

fail:
    g_free(buffer);
    return ret;
}
Example #25
0
static int read_uint32(BlockDriverState *bs, int64_t offset, uint32_t *result)
{
    uint32_t buffer;
    int ret;

    ret = bdrv_pread(bs->file, offset, &buffer, 4);
    if (ret < 0) {
        return ret;
    }

    *result = be32_to_cpu(buffer);
    return 0;
}
Example #26
0
/**
 * Read a string of known length from the image file
 *
 * @file:       Image file
 * @offset:     File offset to start of string, in bytes
 * @n:          String length in bytes
 * @buf:        Destination buffer
 * @buflen:     Destination buffer length in bytes
 * @ret:        0 on success, -errno on failure
 *
 * The string is NUL-terminated.
 */
static int qed_read_string(BlockDriverState *file, uint64_t offset, size_t n,
                           char *buf, size_t buflen)
{
    int ret;
    if (n >= buflen) {
        return -EINVAL;
    }
    ret = bdrv_pread(file, offset, buf, n);
    if (ret < 0) {
        return ret;
    }
    buf[n] = '\0';
    return 0;
}
Example #27
0
static void rtas_nvram_fetch(PowerPCCPU *cpu, sPAPREnvironment *spapr,
                             uint32_t token, uint32_t nargs,
                             target_ulong args,
                             uint32_t nret, target_ulong rets)
{
    sPAPRNVRAM *nvram = spapr->nvram;
    hwaddr offset, buffer, len;
    int alen;
    void *membuf;

    if ((nargs != 3) || (nret != 2)) {
        rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
        return;
    }

    if (!nvram) {
        rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
        rtas_st(rets, 1, 0);
        return;
    }

    offset = rtas_ld(args, 0);
    buffer = rtas_ld(args, 1);
    len = rtas_ld(args, 2);

    if (((offset + len) < offset)
        || ((offset + len) > nvram->size)) {
        rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
        rtas_st(rets, 1, 0);
        return;
    }

    membuf = cpu_physical_memory_map(buffer, &len, 1);
    if (nvram->drive) {
        alen = bdrv_pread(nvram->drive, offset, membuf, len);
    } else {
        assert(nvram->buf);

        memcpy(membuf, nvram->buf + offset, len);
        alen = len;
    }
    cpu_physical_memory_unmap(membuf, len, 1, len);

    rtas_st(rets, 0, (alen < len) ? RTAS_OUT_HW_ERROR : RTAS_OUT_SUCCESS);
    rtas_st(rets, 1, (alen < 0) ? 0 : alen);
}
Example #28
0
/* copy the snapshot 'snapshot_name' into the current disk image */
int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
{
    BDRVQcowState *s = bs->opaque;
    QCowSnapshot *sn;
    int i, snapshot_index;
    int cur_l1_bytes, sn_l1_bytes;

    snapshot_index = find_snapshot_by_id_or_name(bs, snapshot_id);
    if (snapshot_index < 0)
        return -ENOENT;
    sn = &s->snapshots[snapshot_index];

    if (qcow2_update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, -1) < 0)
        goto fail;

    if (qcow2_grow_l1_table(bs, sn->l1_size, true) < 0)
        goto fail;

    cur_l1_bytes = s->l1_size * sizeof(uint64_t);
    sn_l1_bytes = sn->l1_size * sizeof(uint64_t);

    if (cur_l1_bytes > sn_l1_bytes) {
        memset(s->l1_table + sn->l1_size, 0, cur_l1_bytes - sn_l1_bytes);
    }

    /* copy the snapshot l1 table to the current l1 table */
    if (bdrv_pread(bs->file, sn->l1_table_offset,
                   s->l1_table, sn_l1_bytes) < 0)
        goto fail;
    if (bdrv_pwrite_sync(bs->file, s->l1_table_offset,
                         s->l1_table, cur_l1_bytes) < 0)
        goto fail;
    for(i = 0; i < s->l1_size; i++) {
        be64_to_cpus(&s->l1_table[i]);
    }

    if (qcow2_update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, 1) < 0)
        goto fail;

#ifdef DEBUG_ALLOC
    qcow2_check_refcounts(bs);
#endif
    return 0;
fail:
    return -EIO;
}
Example #29
0
static int parallels_read(BlockDriverState *bs, int64_t sector_num,
                    uint8_t *buf, int nb_sectors)
{
    while (nb_sectors > 0) {
        int64_t position = seek_to_sector(bs, sector_num);
        if (position >= 0) {
            if (bdrv_pread(bs->file, position, buf, 512) != 512)
                return -1;
        } else {
            memset(buf, 0, 512);
        }
        nb_sectors--;
        sector_num++;
        buf += 512;
    }
    return 0;
}
Example #30
0
static ssize_t block_crypto_read_func(QCryptoBlock *block,
                                      size_t offset,
                                      uint8_t *buf,
                                      size_t buflen,
                                      Error **errp,
                                      void *opaque)
{
    BlockDriverState *bs = opaque;
    ssize_t ret;

    ret = bdrv_pread(bs->file, offset, buf, buflen);
    if (ret < 0) {
        error_setg_errno(errp, -ret, "Could not read encryption header");
        return ret;
    }
    return ret;
}