nfs: Support .bdrv_co_create
This adds the .bdrv_co_create driver callback to nfs, which enables image creation over QMP. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com>
This commit is contained in:
parent
c22a034545
commit
a1a42af422
76
block/nfs.c
76
block/nfs.c
@ -551,33 +551,45 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int64_t nfs_client_open_qdict(NFSClient *client, QDict *options,
|
||||
int flags, int open_flags, Error **errp)
|
||||
static BlockdevOptionsNfs *nfs_options_qdict_to_qapi(QDict *options,
|
||||
Error **errp)
|
||||
{
|
||||
BlockdevOptionsNfs *opts = NULL;
|
||||
QObject *crumpled = NULL;
|
||||
Visitor *v;
|
||||
Error *local_err = NULL;
|
||||
int ret;
|
||||
|
||||
crumpled = qdict_crumple(options, errp);
|
||||
if (crumpled == NULL) {
|
||||
return -EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
v = qobject_input_visitor_new_keyval(crumpled);
|
||||
visit_type_BlockdevOptionsNfs(v, NULL, &opts, &local_err);
|
||||
visit_free(v);
|
||||
qobject_decref(crumpled);
|
||||
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return opts;
|
||||
}
|
||||
|
||||
static int64_t nfs_client_open_qdict(NFSClient *client, QDict *options,
|
||||
int flags, int open_flags, Error **errp)
|
||||
{
|
||||
BlockdevOptionsNfs *opts;
|
||||
int ret;
|
||||
|
||||
opts = nfs_options_qdict_to_qapi(options, errp);
|
||||
if (opts == NULL) {
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = nfs_client_open(client, opts, flags, open_flags, errp);
|
||||
fail:
|
||||
qobject_decref(crumpled);
|
||||
qapi_free_BlockdevOptionsNfs(opts);
|
||||
return ret;
|
||||
}
|
||||
@ -614,18 +626,43 @@ static QemuOptsList nfs_create_opts = {
|
||||
}
|
||||
};
|
||||
|
||||
static int coroutine_fn nfs_file_co_create_opts(const char *url, QemuOpts *opts,
|
||||
Error **errp)
|
||||
static int nfs_file_co_create(BlockdevCreateOptions *options, Error **errp)
|
||||
{
|
||||
int64_t ret, total_size;
|
||||
BlockdevCreateOptionsNfs *opts = &options->u.nfs;
|
||||
NFSClient *client = g_new0(NFSClient, 1);
|
||||
QDict *options = NULL;
|
||||
int ret;
|
||||
|
||||
assert(options->driver == BLOCKDEV_DRIVER_NFS);
|
||||
|
||||
client->aio_context = qemu_get_aio_context();
|
||||
|
||||
ret = nfs_client_open(client, opts->location, O_CREAT, 0, errp);
|
||||
if (ret < 0) {
|
||||
goto out;
|
||||
}
|
||||
ret = nfs_ftruncate(client->context, client->fh, opts->size);
|
||||
nfs_client_close(client);
|
||||
|
||||
out:
|
||||
g_free(client);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int coroutine_fn nfs_file_co_create_opts(const char *url, QemuOpts *opts,
|
||||
Error **errp)
|
||||
{
|
||||
BlockdevCreateOptions *create_options;
|
||||
BlockdevCreateOptionsNfs *nfs_opts;
|
||||
QDict *options;
|
||||
int ret;
|
||||
|
||||
create_options = g_new0(BlockdevCreateOptions, 1);
|
||||
create_options->driver = BLOCKDEV_DRIVER_NFS;
|
||||
nfs_opts = &create_options->u.nfs;
|
||||
|
||||
/* Read out options */
|
||||
total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
|
||||
BDRV_SECTOR_SIZE);
|
||||
nfs_opts->size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
|
||||
BDRV_SECTOR_SIZE);
|
||||
|
||||
options = qdict_new();
|
||||
ret = nfs_parse_uri(url, options, errp);
|
||||
@ -633,15 +670,21 @@ static int coroutine_fn nfs_file_co_create_opts(const char *url, QemuOpts *opts,
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = nfs_client_open_qdict(client, options, O_CREAT, 0, errp);
|
||||
nfs_opts->location = nfs_options_qdict_to_qapi(options, errp);
|
||||
if (nfs_opts->location == NULL) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = nfs_file_co_create(create_options, errp);
|
||||
if (ret < 0) {
|
||||
goto out;
|
||||
}
|
||||
ret = nfs_ftruncate(client->context, client->fh, total_size);
|
||||
nfs_client_close(client);
|
||||
|
||||
ret = 0;
|
||||
out:
|
||||
QDECREF(options);
|
||||
g_free(client);
|
||||
qapi_free_BlockdevCreateOptions(create_options);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -828,6 +871,7 @@ static BlockDriver bdrv_nfs = {
|
||||
|
||||
.bdrv_file_open = nfs_file_open,
|
||||
.bdrv_close = nfs_file_close,
|
||||
.bdrv_co_create = nfs_file_co_create,
|
||||
.bdrv_co_create_opts = nfs_file_co_create_opts,
|
||||
.bdrv_reopen_prepare = nfs_reopen_prepare,
|
||||
|
||||
|
@ -3392,6 +3392,20 @@
|
||||
'size': 'size',
|
||||
'*preallocation': 'PreallocMode' } }
|
||||
|
||||
##
|
||||
# @BlockdevCreateOptionsNfs:
|
||||
#
|
||||
# Driver specific image creation options for NFS.
|
||||
#
|
||||
# @location Where to store the new image file
|
||||
# @size Size of the virtual disk in bytes
|
||||
#
|
||||
# Since: 2.12
|
||||
##
|
||||
{ 'struct': 'BlockdevCreateOptionsNfs',
|
||||
'data': { 'location': 'BlockdevOptionsNfs',
|
||||
'size': 'size' } }
|
||||
|
||||
##
|
||||
# @BlockdevQcow2Version:
|
||||
#
|
||||
@ -3491,7 +3505,7 @@
|
||||
'iscsi': 'BlockdevCreateNotSupported',
|
||||
'luks': 'BlockdevCreateNotSupported',
|
||||
'nbd': 'BlockdevCreateNotSupported',
|
||||
'nfs': 'BlockdevCreateNotSupported',
|
||||
'nfs': 'BlockdevCreateOptionsNfs',
|
||||
'null-aio': 'BlockdevCreateNotSupported',
|
||||
'null-co': 'BlockdevCreateNotSupported',
|
||||
'nvme': 'BlockdevCreateNotSupported',
|
||||
|
Loading…
Reference in New Issue
Block a user