Commit b0292b85 authored by Kevin Wolf's avatar Kevin Wolf
Browse files

block: x-blockdev-create QMP command



This adds a synchronous x-blockdev-create QMP command that can create
qcow2 images on a given node name.

We don't want to block while creating an image, so this is not the final
interface in all aspects, but BlockdevCreateOptionsQcow2 and
.bdrv_co_create() are what they actually might look like in the end. In
any case, this should be good enough to test whether we interpret
BlockdevCreateOptions as we should.

Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
Reviewed-by: default avatarMax Reitz <mreitz@redhat.com>
Reviewed-by: default avatarEric Blake <eblake@redhat.com>
parent e8eb8637
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -9,7 +9,7 @@ block-obj-y += block-backend.o snapshot.o qapi.o
block-obj-$(CONFIG_WIN32) += file-win32.o win32-aio.o
block-obj-$(CONFIG_POSIX) += file-posix.o
block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o
block-obj-y += null.o mirror.o commit.o io.o
block-obj-y += null.o mirror.o commit.o io.o create.o
block-obj-y += throttle-groups.o
block-obj-$(CONFIG_LINUX) += nvme.o

block/create.c

0 → 100644
+76 −0
Original line number Diff line number Diff line
/*
 * Block layer code related to image creation
 *
 * Copyright (c) 2018 Kevin Wolf <kwolf@redhat.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "qemu/osdep.h"
#include "block/block_int.h"
#include "qapi/qapi-commands-block-core.h"
#include "qapi/error.h"

typedef struct BlockdevCreateCo {
    BlockDriver *drv;
    BlockdevCreateOptions *opts;
    int ret;
    Error **errp;
} BlockdevCreateCo;

static void coroutine_fn bdrv_co_create_co_entry(void *opaque)
{
    BlockdevCreateCo *cco = opaque;
    cco->ret = cco->drv->bdrv_co_create(cco->opts, cco->errp);
}

void qmp_x_blockdev_create(BlockdevCreateOptions *options, Error **errp)
{
    const char *fmt = BlockdevDriver_str(options->driver);
    BlockDriver *drv = bdrv_find_format(fmt);
    Coroutine *co;
    BlockdevCreateCo cco;

    /* If the driver is in the schema, we know that it exists. But it may not
     * be whitelisted. */
    assert(drv);
    if (bdrv_uses_whitelist() && !bdrv_is_whitelisted(drv, false)) {
        error_setg(errp, "Driver is not whitelisted");
        return;
    }

    /* Call callback if it exists */
    if (!drv->bdrv_co_create) {
        error_setg(errp, "Driver does not support blockdev-create");
        return;
    }

    cco = (BlockdevCreateCo) {
        .drv = drv,
        .opts = options,
        .ret = -EINPROGRESS,
        .errp = errp,
    };

    co = qemu_coroutine_create(bdrv_co_create_co_entry, &cco);
    qemu_coroutine_enter(co);
    while (cco.ret == -EINPROGRESS) {
        aio_poll(qemu_get_aio_context(), true);
    }
}
+1 −0
Original line number Diff line number Diff line
@@ -4490,6 +4490,7 @@ BlockDriver bdrv_qcow2 = {
    .bdrv_join_options    = qcow2_join_options,
    .bdrv_child_perm      = bdrv_format_default_perms,
    .bdrv_co_create_opts  = qcow2_co_create_opts,
    .bdrv_co_create       = qcow2_co_create,
    .bdrv_has_zero_init = bdrv_has_zero_init_1,
    .bdrv_co_block_status = qcow2_co_block_status,

+4 −1
Original line number Diff line number Diff line
@@ -129,7 +129,10 @@ struct BlockDriver {
    int (*bdrv_file_open)(BlockDriverState *bs, QDict *options, int flags,
                          Error **errp);
    void (*bdrv_close)(BlockDriverState *bs);
    int coroutine_fn (*bdrv_co_create_opts)(const char *filename, QemuOpts *opts,
    int coroutine_fn (*bdrv_co_create)(BlockdevCreateOptions *opts,
                                       Error **errp);
    int coroutine_fn (*bdrv_co_create_opts)(const char *filename,
                                            QemuOpts *opts,
                                            Error **errp);
    int (*bdrv_make_empty)(BlockDriverState *bs);

+12 −0
Original line number Diff line number Diff line
@@ -3463,6 +3463,18 @@
      'vxhs':           'BlockdevCreateNotSupported'
  } }

##
# @x-blockdev-create:
#
# Create an image format on a given node.
# TODO Replace with something asynchronous (block job?)
#
# Since: 2.12
##
{ 'command': 'x-blockdev-create',
  'data': 'BlockdevCreateOptions',
  'boxed': true }

##
# @blockdev-open-tray:
#