From nobody Thu Apr 25 17:51:58 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1515700821676338.3517747947601; Thu, 11 Jan 2018 12:00:21 -0800 (PST) Received: from localhost ([::1]:38107 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZj1Q-0003Id-HK for importer@patchew.org; Thu, 11 Jan 2018 15:00:20 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57195) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZiuG-0004sh-7O for qemu-devel@nongnu.org; Thu, 11 Jan 2018 14:53:00 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eZiuF-00005L-Bm for qemu-devel@nongnu.org; Thu, 11 Jan 2018 14:52:56 -0500 Received: from mx1.redhat.com ([209.132.183.28]:35153) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eZiuC-0008Tp-0Q; Thu, 11 Jan 2018 14:52: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 EE7017CBAB; Thu, 11 Jan 2018 19:52:50 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.36.118.59]) by smtp.corp.redhat.com (Postfix) with ESMTP id 5F744171A4; Thu, 11 Jan 2018 19:52:39 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Date: Thu, 11 Jan 2018 20:52:16 +0100 Message-Id: <20180111195225.4226-2-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.26]); Thu, 11 Jan 2018 19:52: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 01/10] block/qapi: Introduce BlockdevCreateOptions 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+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" This creates a BlockdevCreateOptions union type that will contain all of the options for image creation. We'll start out with an empty struct type BlockdevCreateDummy for all drivers. Signed-off-by: Kevin Wolf --- qapi/block-core.json | 64 ++++++++++++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 64 insertions(+) diff --git a/qapi/block-core.json b/qapi/block-core.json index e94a6881b2..1749376c61 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -3320,6 +3320,70 @@ { 'command': 'blockdev-del', 'data': { 'node-name': 'str' } } =20 ## +# @BlockdevCreateDummy: +# +# FIXME To be removed. Only there to make the QAPI generator happy while w= e're +# adding driver by driver. Leaving out union branches is not allowed. +# +# Since: 2.12 +## +{ 'struct': 'BlockdevCreateDummy', 'data': {}} + +## +# @BlockdevCreateOptions: +# +# Options for creating an image format on a given node. +# +# @driver block driver to create the image format +# @node node to create the image format on +# +# Since: 2.12 +## +{ 'union': 'BlockdevCreateOptions', + 'base': { + 'driver': 'BlockdevDriver', + 'node': 'BlockdevRef' }, + 'discriminator': 'driver', + 'data': { + 'blkdebug': 'BlockdevCreateDummy', + 'blkverify': 'BlockdevCreateDummy', + 'bochs': 'BlockdevCreateDummy', + 'cloop': 'BlockdevCreateDummy', + 'dmg': 'BlockdevCreateDummy', + 'file': 'BlockdevCreateDummy', + 'ftp': 'BlockdevCreateDummy', + 'ftps': 'BlockdevCreateDummy', + 'gluster': 'BlockdevCreateDummy', + 'host_cdrom': 'BlockdevCreateDummy', + 'host_device': 'BlockdevCreateDummy', + 'http': 'BlockdevCreateDummy', + 'https': 'BlockdevCreateDummy', + 'iscsi': 'BlockdevCreateDummy', + 'luks': 'BlockdevCreateDummy', + 'nbd': 'BlockdevCreateDummy', + 'nfs': 'BlockdevCreateDummy', + 'null-aio': 'BlockdevCreateDummy', + 'null-co': 'BlockdevCreateDummy', + 'parallels': 'BlockdevCreateDummy', + 'qcow2': 'BlockdevCreateDummy', + 'qcow': 'BlockdevCreateDummy', + 'qed': 'BlockdevCreateDummy', + 'quorum': 'BlockdevCreateDummy', + 'raw': 'BlockdevCreateDummy', + 'rbd': 'BlockdevCreateDummy', + 'replication': 'BlockdevCreateDummy', + 'sheepdog': 'BlockdevCreateDummy', + 'ssh': 'BlockdevCreateDummy', + 'throttle': 'BlockdevCreateDummy', + 'vdi': 'BlockdevCreateDummy', + 'vhdx': 'BlockdevCreateDummy', + 'vmdk': 'BlockdevCreateDummy', + 'vpc': 'BlockdevCreateDummy', + 'vvfat': 'BlockdevCreateDummy', + 'vxhs': 'BlockdevCreateDummy' + } } + +## # @blockdev-open-tray: # # Opens a block device's tray. If there is a block driver state tree inser= ted as --=20 2.13.6 From nobody Thu Apr 25 17:51:58 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1515700536520180.14288665237427; Thu, 11 Jan 2018 11:55:36 -0800 (PST) Received: from localhost ([::1]:37881 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZiwp-00075A-Iq for importer@patchew.org; Thu, 11 Jan 2018 14:55:35 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57241) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZiuN-00050e-1V for qemu-devel@nongnu.org; Thu, 11 Jan 2018 14:53:03 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eZiuM-0000Av-9W for qemu-devel@nongnu.org; Thu, 11 Jan 2018 14:53:03 -0500 Received: from mx1.redhat.com ([209.132.183.28]:56038) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eZiuK-00008n-3S; Thu, 11 Jan 2018 14:53:00 -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 1A16576520; Thu, 11 Jan 2018 19:52:59 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.36.118.59]) by smtp.corp.redhat.com (Postfix) with ESMTP id 539EB1715B; Thu, 11 Jan 2018 19:52:51 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Date: Thu, 11 Jan 2018 20:52:17 +0100 Message-Id: <20180111195225.4226-3-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.26]); Thu, 11 Jan 2018 19:52:59 +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 02/10] block/qapi: Add qcow2 create options to schema 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+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Signed-off-by: Kevin Wolf --- qapi/block-core.json | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/qapi/block-core.json b/qapi/block-core.json index 1749376c61..9341f6708d 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -3320,6 +3320,37 @@ { 'command': 'blockdev-del', 'data': { 'node-name': 'str' } } =20 ## +# @BlockdevQcow2CompatLevel: +# @0_10: The original QCOW2 format as introduced in qemu 0.10 (version = 2) +# @1_1: The extended QCOW2 format as introduced in qemu 1.1 (version 3) +# +# Since: 2.10 +## +{ 'enum': 'BlockdevQcow2CompatLevel', + 'data': [ '0_10', '1_1' ] } + + +## +# @BlockdevCreateOptionsQcow2: +# +# Driver specific image creation options for qcow2. +# +# TODO Describe fields +# +# Since: 2.12 +## +{ 'struct': 'BlockdevCreateOptionsQcow2', + 'data': { 'size': 'size', + '*compat': 'BlockdevQcow2CompatLevel', + '*backing-file': 'str', + '*backing-fmt': 'BlockdevDriver', + '*encrypt': 'QCryptoBlockCreateOptions', + '*cluster-size': 'size', + '*preallocation': 'PreallocMode', + '*lazy-refcounts': 'bool', + '*refcount-bits': 'int' } } + +## # @BlockdevCreateDummy: # # FIXME To be removed. Only there to make the QAPI generator happy while w= e're @@ -3365,7 +3396,7 @@ 'null-aio': 'BlockdevCreateDummy', 'null-co': 'BlockdevCreateDummy', 'parallels': 'BlockdevCreateDummy', - 'qcow2': 'BlockdevCreateDummy', + 'qcow2': 'BlockdevCreateOptionsQcow2', 'qcow': 'BlockdevCreateDummy', 'qed': 'BlockdevCreateDummy', 'quorum': 'BlockdevCreateDummy', --=20 2.13.6 From nobody Thu Apr 25 17:51:58 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1515701004717217.7618484779531; Thu, 11 Jan 2018 12:03:24 -0800 (PST) Received: from localhost ([::1]:38150 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZj4L-00060q-Tc for importer@patchew.org; Thu, 11 Jan 2018 15:03:21 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57347) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZiuX-0005Da-QJ for qemu-devel@nongnu.org; Thu, 11 Jan 2018 14:53:14 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eZiuW-0000JX-Ld for qemu-devel@nongnu.org; Thu, 11 Jan 2018 14:53:13 -0500 Received: from mx1.redhat.com ([209.132.183.28]:33934) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eZiuQ-0000EE-V3; Thu, 11 Jan 2018 14:53:07 -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 EB2A144BDC; Thu, 11 Jan 2018 19:53:05 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.36.118.59]) by smtp.corp.redhat.com (Postfix) with ESMTP id 5FB2A7B12D; Thu, 11 Jan 2018 19:52:59 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Date: Thu, 11 Jan 2018 20:52:18 +0100 Message-Id: <20180111195225.4226-4-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.30]); Thu, 11 Jan 2018 19:53:06 +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 03/10] qcow2: Let qcow2_create() handle protocol layer 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+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Currently, qcow2_create() only parses the QemuOpts and then calls qcow2_create2() for the actual image creation, which includes both the creation of the actual file on the file system and writing a valid empty qcow2 image into that file. The plan is that qcow2_create2() becomes the function that implements the functionality for a future 'blockdev-create' QMP command, which only creates the qcow2 layer on an already opened file node. This is a first step towards that goal: Let's move out anything that deals with the protocol layer from qcow2_create2() into qcow2_create(). This means that qcow2_create2() doesn't need a file name any more. Signed-off-by: Kevin Wolf Reviewed-by: Eric Blake --- block/qcow2.c | 64 +++++++++++++++++++++++++++++++++++--------------------= ---- 1 file changed, 38 insertions(+), 26 deletions(-) diff --git a/block/qcow2.c b/block/qcow2.c index 4348b2c0c5..b02bc39a01 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -2690,7 +2690,7 @@ static uint64_t qcow2_opt_get_refcount_bits_del(QemuO= pts *opts, int version, return refcount_bits; } =20 -static int qcow2_create2(const char *filename, int64_t total_size, +static int qcow2_create2(BlockDriverState *bs, int64_t total_size, const char *backing_file, const char *backing_for= mat, int flags, size_t cluster_size, PreallocMode prea= lloc, QemuOpts *opts, int version, int refcount_order, @@ -2716,28 +2716,11 @@ static int qcow2_create2(const char *filename, int6= 4_t total_size, Error *local_err =3D NULL; int ret; =20 - if (prealloc =3D=3D PREALLOC_MODE_FULL || prealloc =3D=3D PREALLOC_MOD= E_FALLOC) { - int64_t prealloc_size =3D - qcow2_calc_prealloc_size(total_size, cluster_size, refcount_or= der); - qemu_opt_set_number(opts, BLOCK_OPT_SIZE, prealloc_size, &error_ab= ort); - qemu_opt_set(opts, BLOCK_OPT_PREALLOC, PreallocMode_str(prealloc), - &error_abort); - } - - ret =3D bdrv_create_file(filename, opts, &local_err); + blk =3D blk_new(BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL); + ret =3D blk_insert_bs(blk, bs, errp); if (ret < 0) { - error_propagate(errp, local_err); - return ret; - } - - blk =3D blk_new_open(filename, NULL, NULL, - BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, - &local_err); - if (blk =3D=3D NULL) { - error_propagate(errp, local_err); - return -EIO; + goto out; } - blk_set_allow_write_beyond_eof(blk, true); =20 /* Write the header */ @@ -2792,7 +2775,8 @@ static int qcow2_create2(const char *filename, int64_= t total_size, */ options =3D qdict_new(); qdict_put_str(options, "driver", "qcow2"); - blk =3D blk_new_open(filename, NULL, options, + qdict_put_str(options, "file", bs->node_name); + blk =3D blk_new_open(NULL, NULL, options, BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_NO_FLUSH, &local_err); if (blk =3D=3D NULL) { @@ -2864,7 +2848,8 @@ static int qcow2_create2(const char *filename, int64_= t total_size, */ options =3D qdict_new(); qdict_put_str(options, "driver", "qcow2"); - blk =3D blk_new_open(filename, NULL, options, + qdict_put_str(options, "file", bs->node_name); + blk =3D blk_new_open(NULL, NULL, options, BDRV_O_RDWR | BDRV_O_NO_BACKING | BDRV_O_NO_IO, &local_err); if (blk =3D=3D NULL) { @@ -2894,6 +2879,7 @@ static int qcow2_create(const char *filename, QemuOpt= s *opts, Error **errp) uint64_t refcount_bits; int refcount_order; char *encryptfmt =3D NULL; + BlockDriverState *bs =3D NULL; Error *local_err =3D NULL; int ret; =20 @@ -2962,12 +2948,38 @@ static int qcow2_create(const char *filename, QemuO= pts *opts, Error **errp) =20 refcount_order =3D ctz32(refcount_bits); =20 - ret =3D qcow2_create2(filename, size, backing_file, backing_fmt, flags, + /* Create and open the file (protocol layer */ + if (prealloc =3D=3D PREALLOC_MODE_FULL || prealloc =3D=3D PREALLOC_MOD= E_FALLOC) { + int64_t prealloc_size =3D + qcow2_calc_prealloc_size(size, cluster_size, refcount_order); + qemu_opt_set_number(opts, BLOCK_OPT_SIZE, prealloc_size, &error_ab= ort); + qemu_opt_set(opts, BLOCK_OPT_PREALLOC, PreallocMode_str(prealloc), + &error_abort); + } + + ret =3D bdrv_create_file(filename, opts, errp); + if (ret < 0) { + goto finish; + } + + bs =3D bdrv_open(filename, NULL, NULL, + BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp); + if (bs =3D=3D NULL) { + ret =3D -EIO; + goto finish; + } + + /* Create the qcow2 image (format layer) */ + ret =3D qcow2_create2(bs, size, backing_file, backing_fmt, flags, cluster_size, prealloc, opts, version, refcount_or= der, - encryptfmt, &local_err); - error_propagate(errp, local_err); + encryptfmt, errp); + if (ret < 0) { + goto finish; + } =20 finish: + bdrv_unref(bs); + g_free(backing_file); g_free(backing_fmt); g_free(encryptfmt); --=20 2.13.6 From nobody Thu Apr 25 17:51:58 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1515700847637840.0135009571203; Thu, 11 Jan 2018 12:00:47 -0800 (PST) Received: from localhost ([::1]:38113 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZj1p-0003hL-N7 for importer@patchew.org; Thu, 11 Jan 2018 15:00:45 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57747) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZium-0005T0-FN for qemu-devel@nongnu.org; Thu, 11 Jan 2018 14:53:32 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eZiui-0000XA-Ug for qemu-devel@nongnu.org; Thu, 11 Jan 2018 14:53:28 -0500 Received: from mx1.redhat.com ([209.132.183.28]:34416) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eZiuc-0000OA-HX; Thu, 11 Jan 2018 14:53:18 -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 7D5ED356E3; Thu, 11 Jan 2018 19:53:17 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.36.118.59]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1D53B7C14D; Thu, 11 Jan 2018 19:53:05 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Date: Thu, 11 Jan 2018 20:52:19 +0100 Message-Id: <20180111195225.4226-5-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.30]); Thu, 11 Jan 2018 19:53:17 +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 04/10] qcow2: Pass BlockdevCreateOptions to qcow2_create2() 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+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" All of the simple options are now passed to qcow2_create2() in a BlockdevCreateOptions object. Still missing: node-name and the encryption options. Signed-off-by: Kevin Wolf Reviewed-by: Eric Blake --- block/qcow2.c | 186 ++++++++++++++++++++++++++++++++++++++++++++++--------= ---- 1 file changed, 148 insertions(+), 38 deletions(-) diff --git a/block/qcow2.c b/block/qcow2.c index b02bc39a01..09e567324d 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -2630,19 +2630,26 @@ static int64_t qcow2_calc_prealloc_size(int64_t tot= al_size, return meta_size + aligned_total_size; } =20 -static size_t qcow2_opt_get_cluster_size_del(QemuOpts *opts, Error **errp) +static bool validate_cluster_size(size_t cluster_size, Error **errp) { - size_t cluster_size; - int cluster_bits; - - cluster_size =3D qemu_opt_get_size_del(opts, BLOCK_OPT_CLUSTER_SIZE, - DEFAULT_CLUSTER_SIZE); - cluster_bits =3D ctz32(cluster_size); + int cluster_bits =3D ctz32(cluster_size); if (cluster_bits < MIN_CLUSTER_BITS || cluster_bits > MAX_CLUSTER_BITS= || (1 << cluster_bits) !=3D cluster_size) { error_setg(errp, "Cluster size must be a power of two between %d a= nd " "%dk", 1 << MIN_CLUSTER_BITS, 1 << (MAX_CLUSTER_BITS - = 10)); + return false; + } + return true; +} + +static size_t qcow2_opt_get_cluster_size_del(QemuOpts *opts, Error **errp) +{ + size_t cluster_size; + + cluster_size =3D qemu_opt_get_size_del(opts, BLOCK_OPT_CLUSTER_SIZE, + DEFAULT_CLUSTER_SIZE); + if (!validate_cluster_size(cluster_size, errp)) { return 0; } return cluster_size; @@ -2690,12 +2697,11 @@ static uint64_t qcow2_opt_get_refcount_bits_del(Qem= uOpts *opts, int version, return refcount_bits; } =20 -static int qcow2_create2(BlockDriverState *bs, int64_t total_size, - const char *backing_file, const char *backing_for= mat, - int flags, size_t cluster_size, PreallocMode prea= lloc, - QemuOpts *opts, int version, int refcount_order, - const char *encryptfmt, Error **errp) +static int qcow2_create2(BlockDriverState *bs, + BlockdevCreateOptions *create_options, + QemuOpts *opts, const char *encryptfmt, Error **e= rrp) { + BlockdevCreateOptionsQcow2 *qcow2_opts; QDict *options; =20 /* @@ -2712,10 +2718,88 @@ static int qcow2_create2(BlockDriverState *bs, int6= 4_t total_size, */ BlockBackend *blk; QCowHeader *header; + size_t cluster_size; + int version; + int refcount_order; uint64_t* refcount_table; Error *local_err =3D NULL; int ret; =20 + /* Validate options and set default values */ + assert(create_options->driver =3D=3D BLOCKDEV_DRIVER_QCOW2); + qcow2_opts =3D &create_options->u.qcow2; + + if (!QEMU_IS_ALIGNED(qcow2_opts->size, BDRV_SECTOR_SIZE)) { + error_setg(errp, "Image size must be a multiple of 512 bytes"); + ret =3D -EINVAL; + goto out; + } + + if (qcow2_opts->has_compat) { + switch (qcow2_opts->compat) { + case BLOCKDEV_QCOW2_COMPAT_LEVEL_0_10: + version =3D 2; + break; + case BLOCKDEV_QCOW2_COMPAT_LEVEL_1_1: + version =3D 3; + break; + default: + g_assert_not_reached(); + } + } else { + version =3D 3; + } + + if (qcow2_opts->has_cluster_size) { + cluster_size =3D qcow2_opts->cluster_size; + } else { + cluster_size =3D DEFAULT_CLUSTER_SIZE; + } + + if (!validate_cluster_size(cluster_size, errp)) { + return -EINVAL; + } + + if (!qcow2_opts->has_preallocation) { + qcow2_opts->preallocation =3D PREALLOC_MODE_OFF; + } + if (qcow2_opts->backing_file && + qcow2_opts->preallocation !=3D PREALLOC_MODE_OFF) + { + error_setg(errp, "Backing file and preallocation cannot be used at= " + "the same time"); + return -EINVAL; + } + + if (!qcow2_opts->has_lazy_refcounts) { + qcow2_opts->lazy_refcounts =3D false; + } + if (version < 3 && qcow2_opts->lazy_refcounts) { + error_setg(errp, "Lazy refcounts only supported with compatibility= " + "level 1.1 and above (use compat=3D1.1 or greater)"); + return -EINVAL; + } + + if (!qcow2_opts->has_refcount_bits) { + qcow2_opts->refcount_bits =3D 16; + } + if (qcow2_opts->refcount_bits > 64 || + !is_power_of_2(qcow2_opts->refcount_bits)) + { + error_setg(errp, "Refcount width must be a power of two and may no= t " + "exceed 64 bits"); + return -EINVAL; + } + if (version < 3 && qcow2_opts->refcount_bits !=3D 16) { + error_setg(errp, "Different refcount widths than 16 bits require " + "compatibility level 1.1 or above (use compat=3D1.1 or " + "greater)"); + return -EINVAL; + } + refcount_order =3D ctz32(qcow2_opts->refcount_bits); + + + /* Create BlockBackend to write to the image */ blk =3D blk_new(BLK_PERM_WRITE | BLK_PERM_RESIZE, BLK_PERM_ALL); ret =3D blk_insert_bs(blk, bs, errp); if (ret < 0) { @@ -2742,7 +2826,7 @@ static int qcow2_create2(BlockDriverState *bs, int64_= t total_size, /* We'll update this to correct value later */ header->crypt_method =3D cpu_to_be32(QCOW_CRYPT_NONE); =20 - if (flags & BLOCK_FLAG_LAZY_REFCOUNTS) { + if (qcow2_opts->lazy_refcounts) { header->compatible_features |=3D cpu_to_be64(QCOW2_COMPAT_LAZY_REFCOUNTS); } @@ -2804,18 +2888,26 @@ static int qcow2_create2(BlockDriverState *bs, int6= 4_t total_size, } =20 /* Okay, now that we have a valid image, let's give it the right size = */ - ret =3D blk_truncate(blk, total_size, PREALLOC_MODE_OFF, errp); + ret =3D blk_truncate(blk, qcow2_opts->size, PREALLOC_MODE_OFF, errp); if (ret < 0) { error_prepend(errp, "Could not resize image: "); goto out; } =20 /* Want a backing file? There you go.*/ - if (backing_file) { - ret =3D bdrv_change_backing_file(blk_bs(blk), backing_file, backin= g_format); + if (qcow2_opts->has_backing_file) { + const char *backing_format =3D NULL; + + if (qcow2_opts->has_backing_fmt) { + backing_format =3D BlockdevDriver_str(qcow2_opts->backing_fmt); + } + + ret =3D bdrv_change_backing_file(blk_bs(blk), qcow2_opts->backing_= file, + backing_format); if (ret < 0) { error_setg_errno(errp, -ret, "Could not assign backing file '%= s' " - "with format '%s'", backing_file, backing_for= mat); + "with format '%s'", qcow2_opts->backing_file, + backing_format); goto out; } } @@ -2829,8 +2921,8 @@ static int qcow2_create2(BlockDriverState *bs, int64_= t total_size, } =20 /* And if we're supposed to preallocate metadata, do that now */ - if (prealloc !=3D PREALLOC_MODE_OFF) { - ret =3D preallocate(blk_bs(blk), 0, total_size); + if (qcow2_opts->preallocation !=3D PREALLOC_MODE_OFF) { + ret =3D preallocate(blk_bs(blk), 0, qcow2_opts->size); if (ret < 0) { error_setg_errno(errp, -ret, "Could not preallocate metadata"); goto out; @@ -2868,8 +2960,10 @@ out: =20 static int qcow2_create(const char *filename, QemuOpts *opts, Error **errp) { + BlockdevCreateOptions create_options; char *backing_file =3D NULL; char *backing_fmt =3D NULL; + BlockdevDriver backing_drv; char *buf =3D NULL; uint64_t size =3D 0; int flags =3D 0; @@ -2877,7 +2971,6 @@ static int qcow2_create(const char *filename, QemuOpt= s *opts, Error **errp) PreallocMode prealloc; int version; uint64_t refcount_bits; - int refcount_order; char *encryptfmt =3D NULL; BlockDriverState *bs =3D NULL; Error *local_err =3D NULL; @@ -2888,6 +2981,13 @@ static int qcow2_create(const char *filename, QemuOp= ts *opts, Error **errp) BDRV_SECTOR_SIZE); backing_file =3D qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE); backing_fmt =3D qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FMT); + backing_drv =3D qapi_enum_parse(&BlockdevDriver_lookup, backing_fmt, + 0, &local_err); + if (local_err) { + error_propagate(errp, local_err); + ret =3D -EINVAL; + goto finish; + } encryptfmt =3D qemu_opt_get_del(opts, BLOCK_OPT_ENCRYPT_FORMAT); if (encryptfmt) { if (qemu_opt_get(opts, BLOCK_OPT_ENCRYPT)) { @@ -2925,20 +3025,6 @@ static int qcow2_create(const char *filename, QemuOp= ts *opts, Error **errp) flags |=3D BLOCK_FLAG_LAZY_REFCOUNTS; } =20 - if (backing_file && prealloc !=3D PREALLOC_MODE_OFF) { - error_setg(errp, "Backing file and preallocation cannot be used at= " - "the same time"); - ret =3D -EINVAL; - goto finish; - } - - if (version < 3 && (flags & BLOCK_FLAG_LAZY_REFCOUNTS)) { - error_setg(errp, "Lazy refcounts only supported with compatibility= " - "level 1.1 and above (use compat=3D1.1 or greater)"); - ret =3D -EINVAL; - goto finish; - } - refcount_bits =3D qcow2_opt_get_refcount_bits_del(opts, version, &loca= l_err); if (local_err) { error_propagate(errp, local_err); @@ -2946,10 +3032,10 @@ static int qcow2_create(const char *filename, QemuO= pts *opts, Error **errp) goto finish; } =20 - refcount_order =3D ctz32(refcount_bits); =20 /* Create and open the file (protocol layer */ if (prealloc =3D=3D PREALLOC_MODE_FULL || prealloc =3D=3D PREALLOC_MOD= E_FALLOC) { + int refcount_order =3D ctz32(refcount_bits); int64_t prealloc_size =3D qcow2_calc_prealloc_size(size, cluster_size, refcount_order); qemu_opt_set_number(opts, BLOCK_OPT_SIZE, prealloc_size, &error_ab= ort); @@ -2970,9 +3056,33 @@ static int qcow2_create(const char *filename, QemuOp= ts *opts, Error **errp) } =20 /* Create the qcow2 image (format layer) */ - ret =3D qcow2_create2(bs, size, backing_file, backing_fmt, flags, - cluster_size, prealloc, opts, version, refcount_or= der, - encryptfmt, errp); + create_options =3D (BlockdevCreateOptions) { + .driver =3D BLOCKDEV_DRIVER_QCOW2, + .node =3D & (BlockdevRef) { + .type =3D QTYPE_QSTRING, + .u.reference =3D bs->node_name, + }, + .u.qcow2 =3D { + .size =3D size, + .has_compat =3D true, + .compat =3D version =3D=3D 2 + ? BLOCKDEV_QCOW2_COMPAT_LEVEL_0_10 + : BLOCKDEV_QCOW2_COMPAT_LEVEL_1_1, + .has_backing_file =3D (backing_file !=3D NULL), + .backing_file =3D backing_file, + .has_backing_fmt =3D (backing_fmt !=3D NULL), + .backing_fmt =3D backing_drv, + .has_cluster_size =3D true, + .cluster_size =3D cluster_size, + .has_preallocation =3D true, + .preallocation =3D prealloc, + .has_lazy_refcounts =3D true, + .lazy_refcounts =3D (flags & BLOCK_FLAG_LAZY_REFCOUNTS), + .has_refcount_bits =3D true, + .refcount_bits =3D refcount_bits, + }, + }; + ret =3D qcow2_create2(bs, &create_options, opts, encryptfmt, errp); if (ret < 0) { goto finish; } --=20 2.13.6 From nobody Thu Apr 25 17:51:58 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1515700677683203.2808317117475; Thu, 11 Jan 2018 11:57:57 -0800 (PST) Received: from localhost ([::1]:38085 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZiz6-00012m-Sg for importer@patchew.org; Thu, 11 Jan 2018 14:57:56 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57685) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZiuk-0005RF-Lh for qemu-devel@nongnu.org; Thu, 11 Jan 2018 14:53:28 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eZiuj-0000XY-Bu for qemu-devel@nongnu.org; Thu, 11 Jan 2018 14:53:26 -0500 Received: from mx1.redhat.com ([209.132.183.28]:55078) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eZiug-0000TG-2R; Thu, 11 Jan 2018 14:53:22 -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 0858EC098D0A; Thu, 11 Jan 2018 19:53:21 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.36.118.59]) by smtp.corp.redhat.com (Postfix) with ESMTP id AB89617163; Thu, 11 Jan 2018 19:53:16 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Date: Thu, 11 Jan 2018 20:52:20 +0100 Message-Id: <20180111195225.4226-6-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.31]); Thu, 11 Jan 2018 19:53:21 +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 05/10] qcow2: Use BlockdevRef in qcow2_create2() 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+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Instead of passing a separate BlockDriverState* into qcow2_create2(), make use of the BlockdevRef that is included in BlockdevCreateOptions. Signed-off-by: Kevin Wolf Reviewed-by: Eric Blake --- include/block/block.h | 1 + block.c | 39 +++++++++++++++++++++++++++++++++++++++ block/qcow2.c | 33 +++++++++++++++++++++------------ 3 files changed, 61 insertions(+), 12 deletions(-) diff --git a/include/block/block.h b/include/block/block.h index 9b12774ddf..4b11f814a8 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -258,6 +258,7 @@ BdrvChild *bdrv_open_child(const char *filename, BlockDriverState* parent, const BdrvChildRole *child_role, bool allow_none, Error **errp); +BlockDriverState *bdrv_open_blockdev_ref(BlockdevRef *ref, Error **errp); void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_h= d, Error **errp); int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options, diff --git a/block.c b/block.c index a8da4f2b25..c9b0e1d6d3 100644 --- a/block.c +++ b/block.c @@ -32,6 +32,8 @@ #include "qapi/qmp/qerror.h" #include "qapi/qmp/qbool.h" #include "qapi/qmp/qjson.h" +#include "qapi/qobject-output-visitor.h" +#include "qapi-visit.h" #include "sysemu/block-backend.h" #include "sysemu/sysemu.h" #include "qemu/notify.h" @@ -2405,6 +2407,43 @@ BdrvChild *bdrv_open_child(const char *filename, return c; } =20 +/* TODO Future callers may need to specify parent/child_role in order for + * option inheritance to work. Existing callers use it for the root node. = */ +BlockDriverState *bdrv_open_blockdev_ref(BlockdevRef *ref, Error **errp) +{ + BlockDriverState *bs =3D NULL; + Error *local_err =3D NULL; + QObject *obj =3D NULL; + QDict *qdict =3D NULL; + const char *reference =3D NULL; + Visitor *v =3D NULL; + + if (ref->type =3D=3D QTYPE_QSTRING) { + reference =3D ref->u.reference; + } else { + BlockdevOptions *options =3D &ref->u.definition; + assert(ref->type =3D=3D QTYPE_QDICT); + + v =3D qobject_output_visitor_new(&obj); + visit_type_BlockdevOptions(v, NULL, &options, &local_err); + if (local_err) { + error_propagate(errp, local_err); + goto fail; + } + visit_complete(v, &obj); + + qdict =3D qobject_to_qdict(obj); + qdict_flatten(qdict); + } + + bs =3D bdrv_open_inherit(NULL, reference, qdict, 0, NULL, NULL, errp); + +fail: + qobject_decref(obj); + visit_free(v); + return bs; +} + static BlockDriverState *bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, QDict *snapshot_options, diff --git a/block/qcow2.c b/block/qcow2.c index 09e567324d..1a0f8f2e6d 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -2697,8 +2697,7 @@ static uint64_t qcow2_opt_get_refcount_bits_del(QemuO= pts *opts, int version, return refcount_bits; } =20 -static int qcow2_create2(BlockDriverState *bs, - BlockdevCreateOptions *create_options, +static int qcow2_create2(BlockdevCreateOptions *create_options, QemuOpts *opts, const char *encryptfmt, Error **e= rrp) { BlockdevCreateOptionsQcow2 *qcow2_opts; @@ -2716,7 +2715,8 @@ static int qcow2_create2(BlockDriverState *bs, * 2 GB for 64k clusters, and we don't want to have a 2 GB initial file * size for any qcow2 image. */ - BlockBackend *blk; + BlockBackend *blk =3D NULL; + BlockDriverState *bs =3D NULL; QCowHeader *header; size_t cluster_size; int version; @@ -2725,6 +2725,11 @@ static int qcow2_create2(BlockDriverState *bs, Error *local_err =3D NULL; int ret; =20 + bs =3D bdrv_open_blockdev_ref(create_options->node, errp); + if (bs =3D=3D NULL) { + return -EIO; + } + /* Validate options and set default values */ assert(create_options->driver =3D=3D BLOCKDEV_DRIVER_QCOW2); qcow2_opts =3D &create_options->u.qcow2; @@ -2757,7 +2762,8 @@ static int qcow2_create2(BlockDriverState *bs, } =20 if (!validate_cluster_size(cluster_size, errp)) { - return -EINVAL; + ret =3D -EINVAL; + goto out; } =20 if (!qcow2_opts->has_preallocation) { @@ -2768,7 +2774,8 @@ static int qcow2_create2(BlockDriverState *bs, { error_setg(errp, "Backing file and preallocation cannot be used at= " "the same time"); - return -EINVAL; + ret =3D -EINVAL; + goto out; } =20 if (!qcow2_opts->has_lazy_refcounts) { @@ -2777,7 +2784,8 @@ static int qcow2_create2(BlockDriverState *bs, if (version < 3 && qcow2_opts->lazy_refcounts) { error_setg(errp, "Lazy refcounts only supported with compatibility= " "level 1.1 and above (use compat=3D1.1 or greater)"); - return -EINVAL; + ret =3D -EINVAL; + goto out; } =20 if (!qcow2_opts->has_refcount_bits) { @@ -2788,13 +2796,15 @@ static int qcow2_create2(BlockDriverState *bs, { error_setg(errp, "Refcount width must be a power of two and may no= t " "exceed 64 bits"); - return -EINVAL; + ret =3D -EINVAL; + goto out; } if (version < 3 && qcow2_opts->refcount_bits !=3D 16) { error_setg(errp, "Different refcount widths than 16 bits require " "compatibility level 1.1 or above (use compat=3D1.1 or " "greater)"); - return -EINVAL; + ret =3D -EINVAL; + goto out; } refcount_order =3D ctz32(qcow2_opts->refcount_bits); =20 @@ -2952,9 +2962,8 @@ static int qcow2_create2(BlockDriverState *bs, =20 ret =3D 0; out: - if (blk) { - blk_unref(blk); - } + blk_unref(blk); + bdrv_unref(bs); return ret; } =20 @@ -3082,7 +3091,7 @@ static int qcow2_create(const char *filename, QemuOpt= s *opts, Error **errp) .refcount_bits =3D refcount_bits, }, }; - ret =3D qcow2_create2(bs, &create_options, opts, encryptfmt, errp); + ret =3D qcow2_create2(&create_options, opts, encryptfmt, errp); if (ret < 0) { goto finish; } --=20 2.13.6 From nobody Thu Apr 25 17:51:58 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1515700712938939.2626901727757; Thu, 11 Jan 2018 11:58:32 -0800 (PST) Received: from localhost ([::1]:38087 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZizg-0001ea-2b for importer@patchew.org; Thu, 11 Jan 2018 14:58:32 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57941) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZiut-0005Ye-63 for qemu-devel@nongnu.org; Thu, 11 Jan 2018 14:53:36 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eZius-0000ht-32 for qemu-devel@nongnu.org; Thu, 11 Jan 2018 14:53:35 -0500 Received: from mx1.redhat.com ([209.132.183.28]:56952) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eZiuo-0000cW-O2; Thu, 11 Jan 2018 14:53:30 -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 B51EF65176; Thu, 11 Jan 2018 19:53:29 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.36.118.59]) by smtp.corp.redhat.com (Postfix) with ESMTP id 3F9201715B; Thu, 11 Jan 2018 19:53:21 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Date: Thu, 11 Jan 2018 20:52:21 +0100 Message-Id: <20180111195225.4226-7-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.26]); Thu, 11 Jan 2018 19:53:29 +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 06/10] qcow2: Use QCryptoBlockCreateOptions in qcow2_create2() 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+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Instead of passing the encryption format name and the QemuOpts down, use the QCryptoBlockCreateOptions contained in BlockdevCreateOptions. Signed-off-by: Kevin Wolf Reviewed-by: Eric Blake --- block/qcow2.c | 62 +++++++++++++++++++++++++++++++++++++++++++------------= ---- 1 file changed, 45 insertions(+), 17 deletions(-) diff --git a/block/qcow2.c b/block/qcow2.c index 1a0f8f2e6d..686b765c06 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -2379,13 +2379,10 @@ static int qcow2_crypt_method_from_format(const cha= r *encryptfmt) } } =20 -static int qcow2_set_up_encryption(BlockDriverState *bs, const char *encry= ptfmt, - QemuOpts *opts, Error **errp) +static QCryptoBlockCreateOptions * +qcow2_parse_encryption(const char *encryptfmt, QemuOpts *opts, Error **err= p) { - BDRVQcow2State *s =3D bs->opaque; QCryptoBlockCreateOptions *cryptoopts =3D NULL; - QCryptoBlock *crypto =3D NULL; - int ret =3D -EINVAL; QDict *options, *encryptopts; int fmt; =20 @@ -2408,10 +2405,31 @@ static int qcow2_set_up_encryption(BlockDriverState= *bs, const char *encryptfmt, error_setg(errp, "Unknown encryption format '%s'", encryptfmt); break; } - if (!cryptoopts) { - ret =3D -EINVAL; - goto out; + + QDECREF(encryptopts); + return cryptoopts; +} + +static int qcow2_set_up_encryption(BlockDriverState *bs, + QCryptoBlockCreateOptions *cryptoopts, + Error **errp) +{ + BDRVQcow2State *s =3D bs->opaque; + QCryptoBlock *crypto =3D NULL; + int fmt, ret; + + switch (cryptoopts->format) { + case Q_CRYPTO_BLOCK_FORMAT_LUKS: + fmt =3D QCOW_CRYPT_LUKS; + break; + case Q_CRYPTO_BLOCK_FORMAT_QCOW: + fmt =3D QCOW_CRYPT_AES; + break; + default: + error_setg(errp, "Crypto format not supported in qcow2"); + return -EINVAL; } + s->crypt_method_header =3D fmt; =20 crypto =3D qcrypto_block_create(cryptoopts, "encrypt.", @@ -2419,8 +2437,7 @@ static int qcow2_set_up_encryption(BlockDriverState *= bs, const char *encryptfmt, qcow2_crypto_hdr_write_func, bs, errp); if (!crypto) { - ret =3D -EINVAL; - goto out; + return -EINVAL; } =20 ret =3D qcow2_update_header(bs); @@ -2429,10 +2446,9 @@ static int qcow2_set_up_encryption(BlockDriverState = *bs, const char *encryptfmt, goto out; } =20 + ret =3D 0; out: - QDECREF(encryptopts); qcrypto_block_free(crypto); - qapi_free_QCryptoBlockCreateOptions(cryptoopts); return ret; } =20 @@ -2697,8 +2713,7 @@ static uint64_t qcow2_opt_get_refcount_bits_del(QemuO= pts *opts, int version, return refcount_bits; } =20 -static int qcow2_create2(BlockdevCreateOptions *create_options, - QemuOpts *opts, const char *encryptfmt, Error **e= rrp) +static int qcow2_create2(BlockdevCreateOptions *create_options, Error **er= rp) { BlockdevCreateOptionsQcow2 *qcow2_opts; QDict *options; @@ -2923,8 +2938,8 @@ static int qcow2_create2(BlockdevCreateOptions *creat= e_options, } =20 /* Want encryption? There you go. */ - if (encryptfmt) { - ret =3D qcow2_set_up_encryption(blk_bs(blk), encryptfmt, opts, err= p); + if (qcow2_opts->has_encrypt) { + ret =3D qcow2_set_up_encryption(blk_bs(blk), qcow2_opts->encrypt, = errp); if (ret < 0) { goto out; } @@ -2981,6 +2996,7 @@ static int qcow2_create(const char *filename, QemuOpt= s *opts, Error **errp) int version; uint64_t refcount_bits; char *encryptfmt =3D NULL; + QCryptoBlockCreateOptions *cryptoopts =3D NULL; BlockDriverState *bs =3D NULL; Error *local_err =3D NULL; int ret; @@ -2997,6 +3013,7 @@ static int qcow2_create(const char *filename, QemuOpt= s *opts, Error **errp) ret =3D -EINVAL; goto finish; } + encryptfmt =3D qemu_opt_get_del(opts, BLOCK_OPT_ENCRYPT_FORMAT); if (encryptfmt) { if (qemu_opt_get(opts, BLOCK_OPT_ENCRYPT)) { @@ -3008,6 +3025,14 @@ static int qcow2_create(const char *filename, QemuOp= ts *opts, Error **errp) } else if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ENCRYPT, false)) { encryptfmt =3D g_strdup("aes"); } + if (encryptfmt) { + cryptoopts =3D qcow2_parse_encryption(encryptfmt, opts, errp); + if (cryptoopts =3D=3D NULL) { + ret =3D -EINVAL; + goto finish; + } + } + cluster_size =3D qcow2_opt_get_cluster_size_del(opts, &local_err); if (local_err) { error_propagate(errp, local_err); @@ -3081,6 +3106,8 @@ static int qcow2_create(const char *filename, QemuOpt= s *opts, Error **errp) .backing_file =3D backing_file, .has_backing_fmt =3D (backing_fmt !=3D NULL), .backing_fmt =3D backing_drv, + .has_encrypt =3D (encryptfmt !=3D NULL), + .encrypt =3D cryptoopts, .has_cluster_size =3D true, .cluster_size =3D cluster_size, .has_preallocation =3D true, @@ -3091,7 +3118,7 @@ static int qcow2_create(const char *filename, QemuOpt= s *opts, Error **errp) .refcount_bits =3D refcount_bits, }, }; - ret =3D qcow2_create2(&create_options, opts, encryptfmt, errp); + ret =3D qcow2_create2(&create_options, errp); if (ret < 0) { goto finish; } @@ -3099,6 +3126,7 @@ static int qcow2_create(const char *filename, QemuOpt= s *opts, Error **errp) finish: bdrv_unref(bs); =20 + qapi_free_QCryptoBlockCreateOptions(cryptoopts); g_free(backing_file); g_free(backing_fmt); g_free(encryptfmt); --=20 2.13.6 From nobody Thu Apr 25 17:51:58 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1515700938441193.04177071153265; Thu, 11 Jan 2018 12:02:18 -0800 (PST) Received: from localhost ([::1]:38139 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZj3J-00051B-Gq for importer@patchew.org; Thu, 11 Jan 2018 15:02:17 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58073) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZiuz-0005fW-Rs for qemu-devel@nongnu.org; Thu, 11 Jan 2018 14:53:42 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eZiuw-0000nN-0O for qemu-devel@nongnu.org; Thu, 11 Jan 2018 14:53:41 -0500 Received: from mx1.redhat.com ([209.132.183.28]:50434) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eZiut-0000ij-N0; Thu, 11 Jan 2018 14:53:35 -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 A60D42D0FDB; Thu, 11 Jan 2018 19:53:34 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.36.118.59]) by smtp.corp.redhat.com (Postfix) with ESMTP id E4D6C7FD21; Thu, 11 Jan 2018 19:53:29 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Date: Thu, 11 Jan 2018 20:52:22 +0100 Message-Id: <20180111195225.4226-8-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.29]); Thu, 11 Jan 2018 19:53:34 +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 07/10] qcow2: Handle full/falloc preallocation in qcow2_create2() 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+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Once qcow2_create2() can be called directly on an already existing node, we must provide the 'full' and 'falloc' preallocation modes outside of creating the image on the protocol layer. Fortunately, we have preallocated truncate now which can provide this functionality. Signed-off-by: Kevin Wolf Reviewed-by: Eric Blake --- block/qcow2.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/block/qcow2.c b/block/qcow2.c index 686b765c06..868e0e8a62 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -2832,6 +2832,25 @@ static int qcow2_create2(BlockdevCreateOptions *crea= te_options, Error **errp) } blk_set_allow_write_beyond_eof(blk, true); =20 + /* Clear the protocol layer and preallocate it if necessary */ + ret =3D blk_truncate(blk, 0, PREALLOC_MODE_OFF, errp); + if (ret < 0) { + goto out; + } + + if (qcow2_opts->preallocation =3D=3D PREALLOC_MODE_FULL || + qcow2_opts->preallocation =3D=3D PREALLOC_MODE_FALLOC) + { + int64_t prealloc_size =3D + qcow2_calc_prealloc_size(qcow2_opts->size, cluster_size, + refcount_order); + + ret =3D blk_truncate(blk, prealloc_size, qcow2_opts->preallocation= , errp); + if (ret < 0) { + goto out; + } + } + /* Write the header */ QEMU_BUILD_BUG_ON((1 << MIN_CLUSTER_BITS) < sizeof(*header)); header =3D g_malloc0(cluster_size); @@ -3068,15 +3087,6 @@ static int qcow2_create(const char *filename, QemuOp= ts *opts, Error **errp) =20 =20 /* Create and open the file (protocol layer */ - if (prealloc =3D=3D PREALLOC_MODE_FULL || prealloc =3D=3D PREALLOC_MOD= E_FALLOC) { - int refcount_order =3D ctz32(refcount_bits); - int64_t prealloc_size =3D - qcow2_calc_prealloc_size(size, cluster_size, refcount_order); - qemu_opt_set_number(opts, BLOCK_OPT_SIZE, prealloc_size, &error_ab= ort); - qemu_opt_set(opts, BLOCK_OPT_PREALLOC, PreallocMode_str(prealloc), - &error_abort); - } - ret =3D bdrv_create_file(filename, opts, errp); if (ret < 0) { goto finish; --=20 2.13.6 From nobody Thu Apr 25 17:51:58 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1515701053486334.1638736005842; Thu, 11 Jan 2018 12:04:13 -0800 (PST) Received: from localhost ([::1]:38175 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZj5A-0006wL-Lh for importer@patchew.org; Thu, 11 Jan 2018 15:04:12 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58177) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZiv2-0005jA-CE for qemu-devel@nongnu.org; Thu, 11 Jan 2018 14:53:45 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eZiv1-0000tb-EE for qemu-devel@nongnu.org; Thu, 11 Jan 2018 14:53:44 -0500 Received: from mx1.redhat.com ([209.132.183.28]:46383) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eZiuv-0000m9-R9; Thu, 11 Jan 2018 14:53:37 -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 D28E044BF2; Thu, 11 Jan 2018 19:53:36 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.36.118.59]) by smtp.corp.redhat.com (Postfix) with ESMTP id ED58E7A305; Thu, 11 Jan 2018 19:53:34 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Date: Thu, 11 Jan 2018 20:52:23 +0100 Message-Id: <20180111195225.4226-9-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.30]); Thu, 11 Jan 2018 19:53:36 +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 08/10] util: Add qemu_opts_to_qdict_filtered() 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+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" This allows, given a QemuOpts for a QemuOptsList that was merged from multiple QemuOptsList, to only consider those options that exist in one specific list. Block drivers need this to separate format-layer create options from protocol-level options. Signed-off-by: Kevin Wolf --- include/qemu/option.h | 2 ++ util/qemu-option.c | 28 +++++++++++++++++++++++++--- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/include/qemu/option.h b/include/qemu/option.h index a88c5f02b1..197f80e79d 100644 --- a/include/qemu/option.h +++ b/include/qemu/option.h @@ -125,6 +125,8 @@ void qemu_opts_set_defaults(QemuOptsList *list, const c= har *params, int permit_abbrev); QemuOpts *qemu_opts_from_qdict(QemuOptsList *list, const QDict *qdict, Error **errp); +QDict *qemu_opts_to_qdict_filtered(QemuOpts *opts, QDict *qdict, + QemuOptsList *list, bool del); QDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qdict); void qemu_opts_absorb_qdict(QemuOpts *opts, QDict *qdict, Error **errp); =20 diff --git a/util/qemu-option.c b/util/qemu-option.c index 553d3dc552..76dc5bedf8 100644 --- a/util/qemu-option.c +++ b/util/qemu-option.c @@ -1009,9 +1009,10 @@ void qemu_opts_absorb_qdict(QemuOpts *opts, QDict *q= dict, Error **errp) * TODO We'll want to use types appropriate for opt->desc->type, but * this is enough for now. */ -QDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qdict) +QDict *qemu_opts_to_qdict_filtered(QemuOpts *opts, QDict *qdict, + QemuOptsList *list, bool del) { - QemuOpt *opt; + QemuOpt *opt, *next; =20 if (!qdict) { qdict =3D qdict_new(); @@ -1019,12 +1020,33 @@ QDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qd= ict) if (opts->id) { qdict_put_str(qdict, "id", opts->id); } - QTAILQ_FOREACH(opt, &opts->head, next) { + QTAILQ_FOREACH_SAFE(opt, &opts->head, next, next) { + if (list) { + QemuOptDesc *desc; + bool found =3D false; + for (desc =3D list->desc; desc->name; desc++) { + if (!strcmp(desc->name, opt->name)) { + found =3D true; + break; + } + } + if (!found) { + continue; + } + } qdict_put_str(qdict, opt->name, opt->str); + if (del) { + qemu_opt_del_all(opts, opt->name); + } } return qdict; } =20 +QDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qdict) +{ + return qemu_opts_to_qdict_filtered(opts, qdict, NULL, false); +} + /* Validate parsed opts against descriptions where no * descriptions were provided in the QemuOptsList. */ --=20 2.13.6 From nobody Thu Apr 25 17:51:58 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1515700888887714.2574693714162; Thu, 11 Jan 2018 12:01:28 -0800 (PST) Received: from localhost ([::1]:38131 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZj2W-0004HZ-13 for importer@patchew.org; Thu, 11 Jan 2018 15:01:28 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58300) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZiv9-0005sD-1w for qemu-devel@nongnu.org; Thu, 11 Jan 2018 14:53:52 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eZiv5-0000wM-4k for qemu-devel@nongnu.org; Thu, 11 Jan 2018 14:53:51 -0500 Received: from mx1.redhat.com ([209.132.183.28]:50576) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eZiv0-0000qh-PB; Thu, 11 Jan 2018 14:53:42 -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 C9F3AC059721; Thu, 11 Jan 2018 19:53:41 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.36.118.59]) by smtp.corp.redhat.com (Postfix) with ESMTP id 05E5B5C258; Thu, 11 Jan 2018 19:53:36 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Date: Thu, 11 Jan 2018 20:52:24 +0100 Message-Id: <20180111195225.4226-10-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.32]); Thu, 11 Jan 2018 19:53:41 +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 09/10] qcow2: Use visitor for options in qcow2_create() 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+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Signed-off-by: Kevin Wolf --- block/qcow2.c | 227 ++++++++++++++++++-----------------------= ---- tests/qemu-iotests/049.out | 10 +- 2 files changed, 93 insertions(+), 144 deletions(-) diff --git a/block/qcow2.c b/block/qcow2.c index 868e0e8a62..4031a18a77 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -36,7 +36,7 @@ #include "qemu/option_int.h" #include "qemu/cutils.h" #include "qemu/bswap.h" -#include "qapi/opts-visitor.h" +#include "qapi/qobject-input-visitor.h" #include "qapi-visit.h" #include "block/crypto.h" =20 @@ -2379,37 +2379,6 @@ static int qcow2_crypt_method_from_format(const char= *encryptfmt) } } =20 -static QCryptoBlockCreateOptions * -qcow2_parse_encryption(const char *encryptfmt, QemuOpts *opts, Error **err= p) -{ - QCryptoBlockCreateOptions *cryptoopts =3D NULL; - QDict *options, *encryptopts; - int fmt; - - options =3D qemu_opts_to_qdict(opts, NULL); - qdict_extract_subqdict(options, &encryptopts, "encrypt."); - QDECREF(options); - - fmt =3D qcow2_crypt_method_from_format(encryptfmt); - - switch (fmt) { - case QCOW_CRYPT_LUKS: - cryptoopts =3D block_crypto_create_opts_init( - Q_CRYPTO_BLOCK_FORMAT_LUKS, encryptopts, errp); - break; - case QCOW_CRYPT_AES: - cryptoopts =3D block_crypto_create_opts_init( - Q_CRYPTO_BLOCK_FORMAT_QCOW, encryptopts, errp); - break; - default: - error_setg(errp, "Unknown encryption format '%s'", encryptfmt); - break; - } - - QDECREF(encryptopts); - return cryptoopts; -} - static int qcow2_set_up_encryption(BlockDriverState *bs, QCryptoBlockCreateOptions *cryptoopts, Error **errp) @@ -3003,144 +2972,124 @@ out: =20 static int qcow2_create(const char *filename, QemuOpts *opts, Error **errp) { - BlockdevCreateOptions create_options; - char *backing_file =3D NULL; - char *backing_fmt =3D NULL; - BlockdevDriver backing_drv; - char *buf =3D NULL; - uint64_t size =3D 0; - int flags =3D 0; - size_t cluster_size =3D DEFAULT_CLUSTER_SIZE; - PreallocMode prealloc; - int version; - uint64_t refcount_bits; - char *encryptfmt =3D NULL; - QCryptoBlockCreateOptions *cryptoopts =3D NULL; + BlockdevCreateOptions *create_options; + QDict *qdict =3D NULL; + QObject *qobj; + Visitor *v; BlockDriverState *bs =3D NULL; + const char *val; + int i, ret; Error *local_err =3D NULL; - int ret; =20 - /* Read out options */ - size =3D ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0), - BDRV_SECTOR_SIZE); - backing_file =3D qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE); - backing_fmt =3D qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FMT); - backing_drv =3D qapi_enum_parse(&BlockdevDriver_lookup, backing_fmt, - 0, &local_err); - if (local_err) { - error_propagate(errp, local_err); - ret =3D -EINVAL; - goto finish; - } + /* Only the keyval visitor supports the dotted syntax needed for + * encryption, so go through a QDict before getting a QAPI type. Ignore + * options meant for the protocol layer so that the visitor doesn't + * complain. */ + qdict =3D qemu_opts_to_qdict_filtered(opts, NULL, bdrv_qcow2.create_op= ts, + true); + + /* Handle encryption options */ + val =3D qdict_get_try_str(qdict, BLOCK_OPT_ENCRYPT); + if (val && !strcmp(val, "on")) { + qdict_put_str(qdict, BLOCK_OPT_ENCRYPT, "qcow"); + } else if (val && !strcmp(val, "off")) { + qdict_del(qdict, BLOCK_OPT_ENCRYPT); + } + + val =3D qdict_get_try_str(qdict, BLOCK_OPT_ENCRYPT_FORMAT); + if (val && !strcmp(val, "aes")) { + qdict_put_str(qdict, BLOCK_OPT_ENCRYPT_FORMAT, "qcow"); + } + + /* TODO QAPI doesn't allow dots in enum values. Either change QAPI or + * decide on the proper new representation for blockdev-create */ + val =3D qdict_get_try_str(qdict, BLOCK_OPT_COMPAT_LEVEL); + if (val && !strcmp(val, "0.10")) { + qdict_put_str(qdict, BLOCK_OPT_COMPAT_LEVEL, "0_10"); + } else if (val && !strcmp(val, "1.1")) { + qdict_put_str(qdict, BLOCK_OPT_COMPAT_LEVEL, "1_1"); + } + + /* Change legacy command line options into QMP ones */ + static const struct { + const char *from; + const char *to; + } opt_renames[] =3D { + { BLOCK_OPT_BACKING_FILE, "backing-file" }, + { BLOCK_OPT_BACKING_FMT, "backing-fmt" }, + { BLOCK_OPT_CLUSTER_SIZE, "cluster-size" }, + { BLOCK_OPT_LAZY_REFCOUNTS, "lazy-refcounts" }, + { BLOCK_OPT_REFCOUNT_BITS, "refcount-bits" }, + { BLOCK_OPT_ENCRYPT, BLOCK_OPT_ENCRYPT_FORMAT }, + }; =20 - encryptfmt =3D qemu_opt_get_del(opts, BLOCK_OPT_ENCRYPT_FORMAT); - if (encryptfmt) { - if (qemu_opt_get(opts, BLOCK_OPT_ENCRYPT)) { - error_setg(errp, "Options " BLOCK_OPT_ENCRYPT " and " - BLOCK_OPT_ENCRYPT_FORMAT " are mutually exclusive"); - ret =3D -EINVAL; - goto finish; - } - } else if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ENCRYPT, false)) { - encryptfmt =3D g_strdup("aes"); - } - if (encryptfmt) { - cryptoopts =3D qcow2_parse_encryption(encryptfmt, opts, errp); - if (cryptoopts =3D=3D NULL) { - ret =3D -EINVAL; - goto finish; + for (i =3D 0; i < ARRAY_SIZE(opt_renames); i++) { + if (qdict_haskey(qdict, opt_renames[i].from)) { + if (qdict_haskey(qdict, opt_renames[i].to)) { + error_setg(errp, "'%s' and its alias '%s' can't be used at= the " + "same time", opt_renames[i].to, opt_renames[i].= from); + ret =3D -EINVAL; + goto finish; + } + + qobj =3D qdict_get(qdict, opt_renames[i].from); + qobject_incref(qobj); + qdict_put_obj(qdict, opt_renames[i].to, qobj); + qdict_del(qdict, opt_renames[i].from); } } =20 - cluster_size =3D qcow2_opt_get_cluster_size_del(opts, &local_err); - if (local_err) { - error_propagate(errp, local_err); - ret =3D -EINVAL; + /* Create and open the file (protocol layer) */ + ret =3D bdrv_create_file(filename, opts, errp); + if (ret < 0) { goto finish; } - buf =3D qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC); - prealloc =3D qapi_enum_parse(&PreallocMode_lookup, buf, - PREALLOC_MODE_OFF, &local_err); - if (local_err) { - error_propagate(errp, local_err); - ret =3D -EINVAL; + + bs =3D bdrv_open(filename, NULL, NULL, + BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp); + if (bs =3D=3D NULL) { + ret =3D -EIO; goto finish; } =20 - version =3D qcow2_opt_get_version_del(opts, &local_err); - if (local_err) { - error_propagate(errp, local_err); + /* Set 'driver' and 'node' options */ + qdict_put_str(qdict, "driver", "qcow2"); + qdict_put_str(qdict, "node", bs->node_name); + + /* Now get the QAPI type BlockdevCreateOptions */ + qobj =3D qdict_crumple(qdict, errp); + QDECREF(qdict); + qdict =3D qobject_to_qdict(qobj); + if (qdict =3D=3D NULL) { ret =3D -EINVAL; goto finish; } =20 - if (qemu_opt_get_bool_del(opts, BLOCK_OPT_LAZY_REFCOUNTS, false)) { - flags |=3D BLOCK_FLAG_LAZY_REFCOUNTS; - } + v =3D qobject_input_visitor_new_keyval(QOBJECT(qdict)); + visit_type_BlockdevCreateOptions(v, NULL, &create_options, &local_err); + visit_free(v); =20 - refcount_bits =3D qcow2_opt_get_refcount_bits_del(opts, version, &loca= l_err); if (local_err) { error_propagate(errp, local_err); ret =3D -EINVAL; goto finish; } =20 - - /* Create and open the file (protocol layer */ - ret =3D bdrv_create_file(filename, opts, errp); - if (ret < 0) { - goto finish; - } - - bs =3D bdrv_open(filename, NULL, NULL, - BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL, errp); - if (bs =3D=3D NULL) { - ret =3D -EIO; - goto finish; - } + /* Silently round up size */ + create_options->u.qcow2.size =3D ROUND_UP(create_options->u.qcow2.size, + BDRV_SECTOR_SIZE); =20 /* Create the qcow2 image (format layer) */ - create_options =3D (BlockdevCreateOptions) { - .driver =3D BLOCKDEV_DRIVER_QCOW2, - .node =3D & (BlockdevRef) { - .type =3D QTYPE_QSTRING, - .u.reference =3D bs->node_name, - }, - .u.qcow2 =3D { - .size =3D size, - .has_compat =3D true, - .compat =3D version =3D=3D 2 - ? BLOCKDEV_QCOW2_COMPAT_LEVEL_0_10 - : BLOCKDEV_QCOW2_COMPAT_LEVEL_1_1, - .has_backing_file =3D (backing_file !=3D NULL), - .backing_file =3D backing_file, - .has_backing_fmt =3D (backing_fmt !=3D NULL), - .backing_fmt =3D backing_drv, - .has_encrypt =3D (encryptfmt !=3D NULL), - .encrypt =3D cryptoopts, - .has_cluster_size =3D true, - .cluster_size =3D cluster_size, - .has_preallocation =3D true, - .preallocation =3D prealloc, - .has_lazy_refcounts =3D true, - .lazy_refcounts =3D (flags & BLOCK_FLAG_LAZY_REFCOUNTS), - .has_refcount_bits =3D true, - .refcount_bits =3D refcount_bits, - }, - }; - ret =3D qcow2_create2(&create_options, errp); + ret =3D qcow2_create2(create_options, errp); if (ret < 0) { goto finish; } =20 + ret =3D 0; finish: + QDECREF(qdict); bdrv_unref(bs); - - qapi_free_QCryptoBlockCreateOptions(cryptoopts); - g_free(backing_file); - g_free(backing_fmt); - g_free(encryptfmt); - g_free(buf); + qapi_free_BlockdevCreateOptions(create_options); return ret; } =20 diff --git a/tests/qemu-iotests/049.out b/tests/qemu-iotests/049.out index 003247023e..1115c27ccf 100644 --- a/tests/qemu-iotests/049.out +++ b/tests/qemu-iotests/049.out @@ -106,7 +106,7 @@ qemu-img: Value '-1k' is out of range for parameter 'si= ze' qemu-img: TEST_DIR/t.qcow2: Invalid options for file format 'qcow2' =20 qemu-img create -f qcow2 TEST_DIR/t.qcow2 -- 1kilobyte -qemu-img: Invalid image size specified! You may use k, M, G, T, P or E suf= fixes for +qemu-img: Invalid image size specified! You may use k, M, G, T, P or E suf= fixes for=20 qemu-img: kilobytes, megabytes, gigabytes, terabytes, petabytes and exabyt= es. =20 qemu-img create -f qcow2 -o size=3D1kilobyte TEST_DIR/t.qcow2 @@ -116,7 +116,7 @@ and exabytes, respectively. qemu-img: TEST_DIR/t.qcow2: Invalid options for file format 'qcow2' =20 qemu-img create -f qcow2 TEST_DIR/t.qcow2 -- foobar -qemu-img: Invalid image size specified! You may use k, M, G, T, P or E suf= fixes for +qemu-img: Invalid image size specified! You may use k, M, G, T, P or E suf= fixes for=20 qemu-img: kilobytes, megabytes, gigabytes, terabytes, petabytes and exabyt= es. =20 qemu-img create -f qcow2 -o size=3Dfoobar TEST_DIR/t.qcow2 @@ -166,11 +166,11 @@ qemu-img create -f qcow2 -o compat=3D1.1 TEST_DIR/t.q= cow2 64M Formatting 'TEST_DIR/t.qcow2', fmt=3Dqcow2 size=3D67108864 compat=3D1.1 cl= uster_size=3D65536 lazy_refcounts=3Doff refcount_bits=3D16 =20 qemu-img create -f qcow2 -o compat=3D0.42 TEST_DIR/t.qcow2 64M -qemu-img: TEST_DIR/t.qcow2: Invalid compatibility level: '0.42' +qemu-img: TEST_DIR/t.qcow2: Invalid parameter '0.42' Formatting 'TEST_DIR/t.qcow2', fmt=3Dqcow2 size=3D67108864 compat=3D0.42 c= luster_size=3D65536 lazy_refcounts=3Doff refcount_bits=3D16 =20 qemu-img create -f qcow2 -o compat=3Dfoobar TEST_DIR/t.qcow2 64M -qemu-img: TEST_DIR/t.qcow2: Invalid compatibility level: 'foobar' +qemu-img: TEST_DIR/t.qcow2: Invalid parameter 'foobar' Formatting 'TEST_DIR/t.qcow2', fmt=3Dqcow2 size=3D67108864 compat=3Dfoobar= cluster_size=3D65536 lazy_refcounts=3Doff refcount_bits=3D16 =20 =3D=3D Check preallocation option =3D=3D @@ -182,7 +182,7 @@ qemu-img create -f qcow2 -o preallocation=3Dmetadata TE= ST_DIR/t.qcow2 64M Formatting 'TEST_DIR/t.qcow2', fmt=3Dqcow2 size=3D67108864 cluster_size=3D= 65536 preallocation=3Dmetadata lazy_refcounts=3Doff refcount_bits=3D16 =20 qemu-img create -f qcow2 -o preallocation=3D1234 TEST_DIR/t.qcow2 64M -qemu-img: TEST_DIR/t.qcow2: invalid parameter value: 1234 +qemu-img: TEST_DIR/t.qcow2: Invalid parameter '1234' Formatting 'TEST_DIR/t.qcow2', fmt=3Dqcow2 size=3D67108864 cluster_size=3D= 65536 preallocation=3D1234 lazy_refcounts=3Doff refcount_bits=3D16 =20 =3D=3D Check encryption option =3D=3D --=20 2.13.6 From nobody Thu Apr 25 17:51:58 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 151570108086667.6266750211463; Thu, 11 Jan 2018 12:04:40 -0800 (PST) Received: from localhost ([::1]:38176 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eZj5b-0007P5-3h for importer@patchew.org; Thu, 11 Jan 2018 15:04:39 -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+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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 @@ } } =20 ## +# @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 inser= ted 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); =20 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 *o= pts, Error **errp) return ret; } =20 +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 =3D opaque; + cco->ret =3D cco->drv->bdrv_co_create(cco->opts, cco->errp); +} + +void qmp_x_blockdev_create(BlockdevCreateOptions *options, Error **errp) +{ + const char *fmt =3D BlockdevDriver_str(options->driver); + BlockDriver* drv =3D 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 =3D (BlockdevCreateCo) { + .drv =3D drv, + .opts =3D options, + .ret =3D NOT_DONE, + .errp =3D errp, + }; + + co =3D qemu_coroutine_create(bdrv_co_create_co_entry, &cco); + qemu_coroutine_enter(co); + while (cco.ret =3D=3D 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 =3D { .bdrv_reopen_abort =3D qcow2_reopen_abort, .bdrv_join_options =3D qcow2_join_options, .bdrv_child_perm =3D bdrv_format_default_perms, - .bdrv_create =3D qcow2_create, + .bdrv_create =3D qcow2_create, + .bdrv_co_create =3D qcow2_create2, .bdrv_has_zero_init =3D bdrv_has_zero_init_1, .bdrv_co_get_block_status =3D qcow2_co_get_block_status, =20 --=20 2.13.6