From patchwork Thu Jan 11 19:52:25 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 859291 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zHcJF5ZQ2z9sBW for ; Fri, 12 Jan 2018 07:03:25 +1100 (AEDT) Received: from localhost ([::1]:38149 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZj4N-0005oe-RG for incoming@patchwork.ozlabs.org; Thu, 11 Jan 2018 15:03:23 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58412) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZivE-0005z9-9r for qemu-devel@nongnu.org; Thu, 11 Jan 2018 14:53:57 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eZivD-00015a-7f for qemu-devel@nongnu.org; Thu, 11 Jan 2018 14:53:56 -0500 Received: from mx1.redhat.com ([209.132.183.28]:43388) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eZivA-00010r-JB; Thu, 11 Jan 2018 14:53:52 -0500 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 97B3768568; Thu, 11 Jan 2018 19:53:46 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.36.118.59]) by smtp.corp.redhat.com (Postfix) with ESMTP id F35837C8A6; Thu, 11 Jan 2018 19:53:41 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Date: Thu, 11 Jan 2018 20:52:25 +0100 Message-Id: <20180111195225.4226-11-kwolf@redhat.com> In-Reply-To: <20180111195225.4226-1-kwolf@redhat.com> References: <20180111195225.4226-1-kwolf@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Thu, 11 Jan 2018 19:53:51 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [RFC PATCH 10/10] block: x-blockdev-create QMP command X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, pkrempa@redhat.com, qemu-devel@nongnu.org, mreitz@redhat.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" 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: Kevin Wolf --- qapi/block-core.json | 12 ++++++++++++ include/block/block_int.h | 2 ++ block.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++ block/qcow2.c | 3 ++- 4 files changed, 64 insertions(+), 1 deletion(-) diff --git a/qapi/block-core.json b/qapi/block-core.json index 9341f6708d..93357a4d5d 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -3415,6 +3415,18 @@ } } ## +# @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: # # Opens a block device's tray. If there is a block driver state tree inserted as diff --git a/include/block/block_int.h b/include/block/block_int.h index 29cafa4236..a9f144d7bd 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -130,6 +130,8 @@ 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)(BlockdevCreateOptions *opts, + Error **errp); int (*bdrv_create)(const char *filename, QemuOpts *opts, Error **errp); int (*bdrv_make_empty)(BlockDriverState *bs); diff --git a/block.c b/block.c index c9b0e1d6d3..7521884de8 100644 --- a/block.c +++ b/block.c @@ -485,6 +485,54 @@ int bdrv_create_file(const char *filename, QemuOpts *opts, Error **errp) return ret; } +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, true)) { + 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 = NOT_DONE, + .errp = errp, + }; + + co = qemu_coroutine_create(bdrv_co_create_co_entry, &cco); + qemu_coroutine_enter(co); + while (cco.ret == NOT_DONE) { + aio_poll(qemu_get_aio_context(), true); + } +} + /** * Try to get @bs's logical and physical block size. * On success, store them in @bsz struct and return 0. diff --git a/block/qcow2.c b/block/qcow2.c index 4031a18a77..5c5386e0b6 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -4436,7 +4436,8 @@ BlockDriver bdrv_qcow2 = { .bdrv_reopen_abort = qcow2_reopen_abort, .bdrv_join_options = qcow2_join_options, .bdrv_child_perm = bdrv_format_default_perms, - .bdrv_create = qcow2_create, + .bdrv_create = qcow2_create, + .bdrv_co_create = qcow2_create2, .bdrv_has_zero_init = bdrv_has_zero_init_1, .bdrv_co_get_block_status = qcow2_co_get_block_status,