コード例 #1
0
ファイル: vdi.c プロジェクト: MaddTheSane/qemu
static int vdi_open(BlockDriverState *bs, QDict *options, int flags,
                    Error **errp)
{
    BDRVVdiState *s = bs->opaque;
    VdiHeader header;
    size_t bmap_size;
    int ret;
    Error *local_err = NULL;
    QemuUUID uuid_link, uuid_parent;

    bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
                               false, errp);
    if (!bs->file) {
        return -EINVAL;
    }

    logout("\n");

    ret = bdrv_read(bs->file, 0, (uint8_t *)&header, 1);
    if (ret < 0) {
        goto fail;
    }

    vdi_header_to_cpu(&header);
    if (VDI_DEBUG) {
        vdi_header_print(&header);
    }

    if (header.disk_size > VDI_DISK_SIZE_MAX) {
        error_setg(errp, "Unsupported VDI image size (size is 0x%" PRIx64
                          ", max supported is 0x%" PRIx64 ")",
                          header.disk_size, VDI_DISK_SIZE_MAX);
        ret = -ENOTSUP;
        goto fail;
    }

    uuid_link = header.uuid_link;
    uuid_parent = header.uuid_parent;

    if (header.disk_size % SECTOR_SIZE != 0) {
        /* 'VBoxManage convertfromraw' can create images with odd disk sizes.
           We accept them but round the disk size to the next multiple of
           SECTOR_SIZE. */
        logout("odd disk size %" PRIu64 " B, round up\n", header.disk_size);
        header.disk_size = ROUND_UP(header.disk_size, SECTOR_SIZE);
    }

    if (header.signature != VDI_SIGNATURE) {
        error_setg(errp, "Image not in VDI format (bad signature %08" PRIx32
                   ")", header.signature);
        ret = -EINVAL;
        goto fail;
    } else if (header.version != VDI_VERSION_1_1) {
        error_setg(errp, "unsupported VDI image (version %" PRIu32 ".%" PRIu32
                   ")", header.version >> 16, header.version & 0xffff);
        ret = -ENOTSUP;
        goto fail;
    } else if (header.offset_bmap % SECTOR_SIZE != 0) {
コード例 #2
0
ファイル: crypto.c プロジェクト: artyom-tarasenko/qemu
static int block_crypto_open_generic(QCryptoBlockFormat format,
                                     QemuOptsList *opts_spec,
                                     BlockDriverState *bs,
                                     QDict *options,
                                     int flags,
                                     Error **errp)
{
    BlockCrypto *crypto = bs->opaque;
    QemuOpts *opts = NULL;
    Error *local_err = NULL;
    int ret = -EINVAL;
    QCryptoBlockOpenOptions *open_opts = NULL;
    unsigned int cflags = 0;

    bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
                               false, errp);
    if (!bs->file) {
        return -EINVAL;
    }

    opts = qemu_opts_create(opts_spec, NULL, 0, &error_abort);
    qemu_opts_absorb_qdict(opts, options, &local_err);
    if (local_err) {
        error_propagate(errp, local_err);
        goto cleanup;
    }

    open_opts = block_crypto_open_opts_init(format, opts, errp);
    if (!open_opts) {
        goto cleanup;
    }

    if (flags & BDRV_O_NO_IO) {
        cflags |= QCRYPTO_BLOCK_OPEN_NO_IO;
    }
    crypto->block = qcrypto_block_open(open_opts,
                                       block_crypto_read_func,
                                       bs,
                                       cflags,
                                       errp);

    if (!crypto->block) {
        ret = -EIO;
        goto cleanup;
    }

    bs->encrypted = true;
    bs->valid_key = true;

    ret = 0;
 cleanup:
    qapi_free_QCryptoBlockOpenOptions(open_opts);
    return ret;
}
コード例 #3
0
ファイル: copy-on-read.c プロジェクト: Mellanox/qemu
static int cor_open(BlockDriverState *bs, QDict *options, int flags,
                    Error **errp)
{
    bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, false,
                               errp);
    if (!bs->file) {
        return -EINVAL;
    }

    bs->supported_write_flags = BDRV_REQ_WRITE_UNCHANGED |
                                (BDRV_REQ_FUA &
                                    bs->file->bs->supported_write_flags);

    bs->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED |
                               ((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP) &
                                    bs->file->bs->supported_zero_flags);

    return 0;
}
コード例 #4
0
ファイル: dmg.c プロジェクト: CTU-IIG/qemu
static int dmg_open(BlockDriverState *bs, QDict *options, int flags,
                    Error **errp)
{
    BDRVDMGState *s = bs->opaque;
    DmgHeaderState ds;
    uint64_t rsrc_fork_offset, rsrc_fork_length;
    uint64_t plist_xml_offset, plist_xml_length;
    int64_t offset;
    int ret;

    ret = bdrv_apply_auto_read_only(bs, NULL, errp);
    if (ret < 0) {
        return ret;
    }

    bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
                               false, errp);
    if (!bs->file) {
        return -EINVAL;
    }

    block_module_load_one("dmg-bz2");

    s->n_chunks = 0;
    s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL;
    /* used by dmg_read_mish_block to keep track of the current I/O position */
    ds.data_fork_offset = 0;
    ds.max_compressed_size = 1;
    ds.max_sectors_per_chunk = 1;

    /* locate the UDIF trailer */
    offset = dmg_find_koly_offset(bs->file, errp);
    if (offset < 0) {
        ret = offset;
        goto fail;
    }

    /* offset of data fork (DataForkOffset) */
    ret = read_uint64(bs, offset + 0x18, &ds.data_fork_offset);
    if (ret < 0) {
        goto fail;
    } else if (ds.data_fork_offset > offset) {
        ret = -EINVAL;
        goto fail;
    }

    /* offset of resource fork (RsrcForkOffset) */
    ret = read_uint64(bs, offset + 0x28, &rsrc_fork_offset);
    if (ret < 0) {
        goto fail;
    }
    ret = read_uint64(bs, offset + 0x30, &rsrc_fork_length);
    if (ret < 0) {
        goto fail;
    }
    if (rsrc_fork_offset >= offset ||
        rsrc_fork_length > offset - rsrc_fork_offset) {
        ret = -EINVAL;
        goto fail;
    }
    /* offset of property list (XMLOffset) */
    ret = read_uint64(bs, offset + 0xd8, &plist_xml_offset);
    if (ret < 0) {
        goto fail;
    }
    ret = read_uint64(bs, offset + 0xe0, &plist_xml_length);
    if (ret < 0) {
        goto fail;
    }
    if (plist_xml_offset >= offset ||
        plist_xml_length > offset - plist_xml_offset) {
        ret = -EINVAL;
        goto fail;
    }
    ret = read_uint64(bs, offset + 0x1ec, (uint64_t *)&bs->total_sectors);
    if (ret < 0) {
        goto fail;
    }
    if (bs->total_sectors < 0) {
        ret = -EINVAL;
        goto fail;
    }
    if (rsrc_fork_length != 0) {
        ret = dmg_read_resource_fork(bs, &ds,
                                     rsrc_fork_offset, rsrc_fork_length);
        if (ret < 0) {
            goto fail;
        }
    } else if (plist_xml_length != 0) {
        ret = dmg_read_plist_xml(bs, &ds, plist_xml_offset, plist_xml_length);
        if (ret < 0) {
            goto fail;
        }
    } else {
        ret = -EINVAL;
        goto fail;
    }

    /* initialize zlib engine */
    s->compressed_chunk = qemu_try_blockalign(bs->file->bs,
                                              ds.max_compressed_size + 1);
    s->uncompressed_chunk = qemu_try_blockalign(bs->file->bs,
                                                512 * ds.max_sectors_per_chunk);
    if (s->compressed_chunk == NULL || s->uncompressed_chunk == NULL) {
        ret = -ENOMEM;
        goto fail;
    }

    if (inflateInit(&s->zstream) != Z_OK) {
        ret = -EINVAL;
        goto fail;
    }

    s->current_chunk = s->n_chunks;

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

fail:
    g_free(s->types);
    g_free(s->offsets);
    g_free(s->lengths);
    g_free(s->sectors);
    g_free(s->sectorcounts);
    qemu_vfree(s->compressed_chunk);
    qemu_vfree(s->uncompressed_chunk);
    return ret;
}