mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-21 17:11:57 -06:00
vdi: Pull option parsing from vdi_co_create
In preparation of QAPI-fying VDI image creation, we have to create a BlockdevCreateOptionsVdi type which is received by a (future) vdi_co_create(). vdi_co_create_opts() now converts the QemuOpts object into such a BlockdevCreateOptionsVdi object. The protocol-layer file is still created in vdi_co_do_create() (and BlockdevCreateOptionsVdi.file is set to an empty string), but that will be addressed by a follow-up patch. Note that cluster-size is not part of the QAPI schema because it is not supported by default. Signed-off-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
d06195e6a6
commit
49858b5098
2 changed files with 95 additions and 14 deletions
91
block/vdi.c
91
block/vdi.c
|
@ -51,6 +51,9 @@
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
|
#include "qapi/qmp/qdict.h"
|
||||||
|
#include "qapi/qobject-input-visitor.h"
|
||||||
|
#include "qapi/qapi-visit-block-core.h"
|
||||||
#include "block/block_int.h"
|
#include "block/block_int.h"
|
||||||
#include "sysemu/block-backend.h"
|
#include "sysemu/block-backend.h"
|
||||||
#include "qemu/module.h"
|
#include "qemu/module.h"
|
||||||
|
@ -140,6 +143,8 @@
|
||||||
#define VDI_DISK_SIZE_MAX ((uint64_t)VDI_BLOCKS_IN_IMAGE_MAX * \
|
#define VDI_DISK_SIZE_MAX ((uint64_t)VDI_BLOCKS_IN_IMAGE_MAX * \
|
||||||
(uint64_t)DEFAULT_CLUSTER_SIZE)
|
(uint64_t)DEFAULT_CLUSTER_SIZE)
|
||||||
|
|
||||||
|
static QemuOptsList vdi_create_opts;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char text[0x40];
|
char text[0x40];
|
||||||
uint32_t signature;
|
uint32_t signature;
|
||||||
|
@ -716,13 +721,14 @@ nonallocating_write:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int coroutine_fn vdi_co_create_opts(const char *filename, QemuOpts *opts,
|
static int coroutine_fn vdi_co_do_create(const char *filename,
|
||||||
Error **errp)
|
QemuOpts *file_opts,
|
||||||
|
BlockdevCreateOptionsVdi *vdi_opts,
|
||||||
|
size_t block_size, Error **errp)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
uint64_t bytes = 0;
|
uint64_t bytes = 0;
|
||||||
uint32_t blocks;
|
uint32_t blocks;
|
||||||
size_t block_size = DEFAULT_CLUSTER_SIZE;
|
|
||||||
uint32_t image_type = VDI_TYPE_DYNAMIC;
|
uint32_t image_type = VDI_TYPE_DYNAMIC;
|
||||||
VdiHeader header;
|
VdiHeader header;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
@ -735,18 +741,25 @@ static int coroutine_fn vdi_co_create_opts(const char *filename, QemuOpts *opts,
|
||||||
logout("\n");
|
logout("\n");
|
||||||
|
|
||||||
/* Read out options. */
|
/* Read out options. */
|
||||||
bytes = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
|
bytes = vdi_opts->size;
|
||||||
BDRV_SECTOR_SIZE);
|
if (vdi_opts->q_static) {
|
||||||
#if defined(CONFIG_VDI_BLOCK_SIZE)
|
|
||||||
/* TODO: Additional checks (SECTOR_SIZE * 2^n, ...). */
|
|
||||||
block_size = qemu_opt_get_size_del(opts,
|
|
||||||
BLOCK_OPT_CLUSTER_SIZE,
|
|
||||||
DEFAULT_CLUSTER_SIZE);
|
|
||||||
#endif
|
|
||||||
#if defined(CONFIG_VDI_STATIC_IMAGE)
|
|
||||||
if (qemu_opt_get_bool_del(opts, BLOCK_OPT_STATIC, false)) {
|
|
||||||
image_type = VDI_TYPE_STATIC;
|
image_type = VDI_TYPE_STATIC;
|
||||||
}
|
}
|
||||||
|
#ifndef CONFIG_VDI_STATIC_IMAGE
|
||||||
|
if (image_type == VDI_TYPE_STATIC) {
|
||||||
|
ret = -ENOTSUP;
|
||||||
|
error_setg(errp, "Statically allocated images cannot be created in "
|
||||||
|
"this build");
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifndef CONFIG_VDI_BLOCK_SIZE
|
||||||
|
if (block_size != DEFAULT_CLUSTER_SIZE) {
|
||||||
|
ret = -ENOTSUP;
|
||||||
|
error_setg(errp,
|
||||||
|
"A non-default cluster size is not supported in this build");
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (bytes > VDI_DISK_SIZE_MAX) {
|
if (bytes > VDI_DISK_SIZE_MAX) {
|
||||||
|
@ -757,7 +770,7 @@ static int coroutine_fn vdi_co_create_opts(const char *filename, QemuOpts *opts,
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = bdrv_create_file(filename, opts, &local_err);
|
ret = bdrv_create_file(filename, file_opts, &local_err);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
error_propagate(errp, local_err);
|
error_propagate(errp, local_err);
|
||||||
goto exit;
|
goto exit;
|
||||||
|
@ -847,6 +860,56 @@ exit:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int coroutine_fn vdi_co_create_opts(const char *filename, QemuOpts *opts,
|
||||||
|
Error **errp)
|
||||||
|
{
|
||||||
|
QDict *qdict = NULL;
|
||||||
|
BlockdevCreateOptionsVdi *create_options = NULL;
|
||||||
|
uint64_t block_size = DEFAULT_CLUSTER_SIZE;
|
||||||
|
Visitor *v;
|
||||||
|
Error *local_err = NULL;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Since CONFIG_VDI_BLOCK_SIZE is disabled by default,
|
||||||
|
* cluster-size is not part of the QAPI schema; therefore we have
|
||||||
|
* to parse it before creating the QAPI object. */
|
||||||
|
#if defined(CONFIG_VDI_BLOCK_SIZE)
|
||||||
|
block_size = qemu_opt_get_size_del(opts,
|
||||||
|
BLOCK_OPT_CLUSTER_SIZE,
|
||||||
|
DEFAULT_CLUSTER_SIZE);
|
||||||
|
if (block_size < BDRV_SECTOR_SIZE || block_size > UINT32_MAX ||
|
||||||
|
!is_power_of_2(block_size))
|
||||||
|
{
|
||||||
|
error_setg(errp, "Invalid cluster size");
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
qdict = qemu_opts_to_qdict_filtered(opts, NULL, &vdi_create_opts, true);
|
||||||
|
|
||||||
|
qdict_put_str(qdict, "file", ""); /* FIXME */
|
||||||
|
|
||||||
|
/* Get the QAPI object */
|
||||||
|
v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
|
||||||
|
visit_type_BlockdevCreateOptionsVdi(v, NULL, &create_options, &local_err);
|
||||||
|
visit_free(v);
|
||||||
|
|
||||||
|
if (local_err) {
|
||||||
|
error_propagate(errp, local_err);
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
create_options->size = ROUND_UP(create_options->size, BDRV_SECTOR_SIZE);
|
||||||
|
|
||||||
|
ret = vdi_co_do_create(filename, opts, create_options, block_size, errp);
|
||||||
|
done:
|
||||||
|
QDECREF(qdict);
|
||||||
|
qapi_free_BlockdevCreateOptionsVdi(create_options);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static void vdi_close(BlockDriverState *bs)
|
static void vdi_close(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
BDRVVdiState *s = bs->opaque;
|
BDRVVdiState *s = bs->opaque;
|
||||||
|
|
|
@ -3768,6 +3768,24 @@
|
||||||
'data': { 'location': 'BlockdevOptionsSsh',
|
'data': { 'location': 'BlockdevOptionsSsh',
|
||||||
'size': 'size' } }
|
'size': 'size' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @BlockdevCreateOptionsVdi:
|
||||||
|
#
|
||||||
|
# Driver specific image creation options for VDI.
|
||||||
|
#
|
||||||
|
# @file Node to create the image format on
|
||||||
|
# @size Size of the virtual disk in bytes
|
||||||
|
# @static Whether to create a statically (true) or
|
||||||
|
# dynamically (false) allocated image
|
||||||
|
# (default: false, i.e. dynamic)
|
||||||
|
#
|
||||||
|
# Since: 2.12
|
||||||
|
##
|
||||||
|
{ 'struct': 'BlockdevCreateOptionsVdi',
|
||||||
|
'data': { 'file': 'BlockdevRef',
|
||||||
|
'size': 'size',
|
||||||
|
'*static': 'bool' } }
|
||||||
|
|
||||||
##
|
##
|
||||||
# @BlockdevCreateNotSupported:
|
# @BlockdevCreateNotSupported:
|
||||||
#
|
#
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue