From nobody Sun May 5 02:11:01 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.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 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1547104791642563.8254128552214; Wed, 9 Jan 2019 23:19:51 -0800 (PST) Received: from localhost ([127.0.0.1]:59781 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghUd4-0004Zk-9g for importer@patchew.org; Thu, 10 Jan 2019 02:19:50 -0500 Received: from eggs.gnu.org ([209.51.188.92]:35146) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghUXE-0000ZN-Mi for qemu-devel@nongnu.org; Thu, 10 Jan 2019 02:13:49 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ghUXD-0001k8-8i for qemu-devel@nongnu.org; Thu, 10 Jan 2019 02:13:48 -0500 Received: from mx1.redhat.com ([209.132.183.28]:46500) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ghUXA-0001en-0S; Thu, 10 Jan 2019 02:13:44 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 0302B325B1; Thu, 10 Jan 2019 07:13:39 +0000 (UTC) Received: from blue.redhat.com (ovpn-116-216.phx2.redhat.com [10.3.116.216]) by smtp.corp.redhat.com (Postfix) with ESMTP id 398E31019626; Thu, 10 Jan 2019 07:13:38 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Date: Thu, 10 Jan 2019 01:13:25 -0600 Message-Id: <20190110071330.28136-2-eblake@redhat.com> In-Reply-To: <20190110071330.28136-1-eblake@redhat.com> References: <20190110071330.28136-1-eblake@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Thu, 10 Jan 2019 07:13:39 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v2 1/6] nbd: Only require disabled bitmap for read-only exports 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: Kevin Wolf , vsementsov@virtuozzo.com, jsnow@redhat.com, qemu-block@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Our initial implementation of x-nbd-server-add-bitmap put in a restriction because of incremental backups: in that usage, we are exporting one qcow2 file (the temporary overlay target of a blockdev-backup sync:none job) and a dirty bitmap owned by a second qcow2 file (the source of the blockdev-backup, which is the backing file of the temporary). While both qcow2 files are still writable (the target capture copy-on-write of old contents, the source to track live guest writes in the meantime), the NBD client expects to see constant data, including the dirty bitmap. An enabled bitmap in the source would be modified by guest writes, which is at odds with the NBD export being a read-only constant view, hence the initial code choice of enforcing a disabled bitmap (the intent is that the exposed bitmap was disabled in the same transaction that started the blockdev-backup job, although we don't want to actually track enough state to actually enforce that). However, in the case of image migration, where we WANT a writable export, it makes total sense that the NBD client could expect writes to change the status visible through the exposed dirty bitmap, and thus permitting an enabled bitmap for an export that is not read-only makes sense; although the current restriction prevents that usage. Alternatively, consider the case when the active layer does not contain the bitmap but the backing layer does. If the backing layer is read-only (which is different from the backing layer of a blockdev-backup job being writable), we know the backing layer cannot be modified, and thus the bitmap will not change contents even if it is still marked enabled (for that matter, since the backing file is read-only, we couldn't change the bitmap to be disabled in the first place). Again, the current restriction prevents this usage. Solve both issues by gating the restriction against a disabled bitmap to only happen when the caller has requested a read-only export, and where the BDS that owns the bitmap (which might be a backing file of the BDS handed to nbd_export_new) is still writable. Update iotest 223 to add some tests of the error paths. Signed-off-by: Eric Blake Reviewed-by: Vladimir Sementsov-Ogievskiy --- v2: new patch --- nbd/server.c | 7 +++++-- tests/qemu-iotests/223 | 14 ++++++++++++-- tests/qemu-iotests/223.out | 4 ++++ 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/nbd/server.c b/nbd/server.c index 7af0ddffb20..98327088cb4 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -2456,8 +2456,11 @@ void nbd_export_bitmap(NBDExport *exp, const char *b= itmap, return; } - if (bdrv_dirty_bitmap_enabled(bm)) { - error_setg(errp, "Bitmap '%s' is enabled", bitmap); + if ((exp->nbdflags & NBD_FLAG_READ_ONLY) && bdrv_is_writable(bs) && + bdrv_dirty_bitmap_enabled(bm)) { + error_setg(errp, + "Enabled bitmap '%s' incompatible with readonly export", + bitmap); return; } diff --git a/tests/qemu-iotests/223 b/tests/qemu-iotests/223 index 5513dc62159..f1fbb9bc1c6 100755 --- a/tests/qemu-iotests/223 +++ b/tests/qemu-iotests/223 @@ -61,6 +61,8 @@ echo "=3D=3D=3D Create partially sparse image, then add d= irty bitmaps =3D=3D=3D" echo # Two bitmaps, to contrast granularity issues +# Also note that b will be disabled, while b2 is left enabled, to +# check for read-only interactions _make_test_img -o cluster_size=3D4k 4M $QEMU_IO -c 'w -P 0x11 1M 2M' "$TEST_IMG" | _filter_qemu_io run_qemu < Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1547104755290206.48099217036554; Wed, 9 Jan 2019 23:19:15 -0800 (PST) Received: from localhost ([127.0.0.1]:59635 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghUcU-0003xr-27 for importer@patchew.org; Thu, 10 Jan 2019 02:19:14 -0500 Received: from eggs.gnu.org ([209.51.188.92]:35152) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghUXF-0000aL-1D for qemu-devel@nongnu.org; Thu, 10 Jan 2019 02:13:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ghUXD-0001lL-Rn for qemu-devel@nongnu.org; Thu, 10 Jan 2019 02:13:49 -0500 Received: from mx1.redhat.com ([209.132.183.28]:55424) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ghUXA-0001f2-A0; Thu, 10 Jan 2019 02:13:44 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id C7B413D95C; Thu, 10 Jan 2019 07:13:39 +0000 (UTC) Received: from blue.redhat.com (ovpn-116-216.phx2.redhat.com [10.3.116.216]) by smtp.corp.redhat.com (Postfix) with ESMTP id 294661019626; Thu, 10 Jan 2019 07:13:39 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Date: Thu, 10 Jan 2019 01:13:26 -0600 Message-Id: <20190110071330.28136-3-eblake@redhat.com> In-Reply-To: <20190110071330.28136-1-eblake@redhat.com> References: <20190110071330.28136-1-eblake@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Thu, 10 Jan 2019 07:13:39 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v2 2/6] nbd: Merge nbd_export_set_name into nbd_export_new 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: Kevin Wolf , vsementsov@virtuozzo.com, jsnow@redhat.com, qemu-block@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" The existing NBD code had a weird split where nbd_export_new() created an export but did not add it to the list of exported names until a later nbd_export_set_name() came along and grabbed a second reference on the object; later, nbd_export_close() drops the second reference. But since we never change the name of an NBD export while it is exposed, it is easier to just inline the process of setting the name as part of creating the export. Inline the contents of nbd_export_set_name() and nbd_export_set_description() into the two points in an export lifecycle where they matter, then adjust both callers to pass the name up front. Note that all callers pass a non-NULL name, (passing NULL at creation was for old style servers, but we removed support for that in commit 7f7dfe2a). Signed-off-by: Eric Blake Reviewed-by: Vladimir Sementsov-Ogievskiy --- include/block/nbd.h | 3 +-- blockdev-nbd.c | 5 ++--- nbd/server.c | 45 ++++++++++++++++----------------------------- qemu-nbd.c | 5 ++--- 4 files changed, 21 insertions(+), 37 deletions(-) diff --git a/include/block/nbd.h b/include/block/nbd.h index 65402d33964..2f9a2aeb73c 100644 --- a/include/block/nbd.h +++ b/include/block/nbd.h @@ -295,6 +295,7 @@ typedef struct NBDExport NBDExport; typedef struct NBDClient NBDClient; NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset, off_t si= ze, + const char *name, const char *description, uint16_t nbdflags, void (*close)(NBDExport *), bool writethrough, BlockBackend *on_eject_blk, Error **errp); @@ -306,8 +307,6 @@ void nbd_export_put(NBDExport *exp); BlockBackend *nbd_export_get_blockdev(NBDExport *exp); NBDExport *nbd_export_find(const char *name); -void nbd_export_set_name(NBDExport *exp, const char *name); -void nbd_export_set_description(NBDExport *exp, const char *description); void nbd_export_close_all(void); void nbd_client_new(QIOChannelSocket *sioc, diff --git a/blockdev-nbd.c b/blockdev-nbd.c index 1d170c80b82..f5edbc27d88 100644 --- a/blockdev-nbd.c +++ b/blockdev-nbd.c @@ -174,14 +174,13 @@ void qmp_nbd_server_add(const char *device, bool has_= name, const char *name, writable =3D false; } - exp =3D nbd_export_new(bs, 0, -1, writable ? 0 : NBD_FLAG_READ_ONLY, + exp =3D nbd_export_new(bs, 0, -1, name, NULL, + writable ? 0 : NBD_FLAG_READ_ONLY, NULL, false, on_eject_blk, errp); if (!exp) { return; } - nbd_export_set_name(exp, name); - /* The list of named exports has a strong reference to this export now= and * our only way of accessing it is through nbd_export_find(), so we ca= n drop * the strong reference that is @exp. */ diff --git a/nbd/server.c b/nbd/server.c index 98327088cb4..676fb4886d0 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -1456,6 +1456,7 @@ static void nbd_eject_notifier(Notifier *n, void *dat= a) } NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset, off_t si= ze, + const char *name, const char *description, uint16_t nbdflags, void (*close)(NBDExport *), bool writethrough, BlockBackend *on_eject_blk, Error **errp) @@ -1471,6 +1472,7 @@ NBDExport *nbd_export_new(BlockDriverState *bs, off_t= dev_offset, off_t size, * that BDRV_O_INACTIVE is cleared and the image is ready for write * access since the export could be available before migration handove= r. */ + assert(name); ctx =3D bdrv_get_aio_context(bs); aio_context_acquire(ctx); bdrv_invalidate_cache(bs, NULL); @@ -1494,6 +1496,8 @@ NBDExport *nbd_export_new(BlockDriverState *bs, off_t= dev_offset, off_t size, QTAILQ_INIT(&exp->clients); exp->blk =3D blk; exp->dev_offset =3D dev_offset; + exp->name =3D g_strdup(name); + exp->description =3D g_strdup(description); exp->nbdflags =3D nbdflags; exp->size =3D size < 0 ? blk_getlength(blk) : size; if (exp->size < 0) { @@ -1513,10 +1517,14 @@ NBDExport *nbd_export_new(BlockDriverState *bs, off= _t dev_offset, off_t size, exp->eject_notifier.notify =3D nbd_eject_notifier; blk_add_remove_bs_notifier(on_eject_blk, &exp->eject_notifier); } + QTAILQ_INSERT_TAIL(&exports, exp, next); + nbd_export_get(exp); return exp; fail: blk_unref(blk); + g_free(exp->name); + g_free(exp->description); g_free(exp); return NULL; } @@ -1533,33 +1541,6 @@ NBDExport *nbd_export_find(const char *name) return NULL; } -void nbd_export_set_name(NBDExport *exp, const char *name) -{ - if (exp->name =3D=3D name) { - return; - } - - nbd_export_get(exp); - if (exp->name !=3D NULL) { - g_free(exp->name); - exp->name =3D NULL; - QTAILQ_REMOVE(&exports, exp, next); - nbd_export_put(exp); - } - if (name !=3D NULL) { - nbd_export_get(exp); - exp->name =3D g_strdup(name); - QTAILQ_INSERT_TAIL(&exports, exp, next); - } - nbd_export_put(exp); -} - -void nbd_export_set_description(NBDExport *exp, const char *description) -{ - g_free(exp->description); - exp->description =3D g_strdup(description); -} - void nbd_export_close(NBDExport *exp) { NBDClient *client, *next; @@ -1568,8 +1549,14 @@ void nbd_export_close(NBDExport *exp) QTAILQ_FOREACH_SAFE(client, &exp->clients, next, next) { client_close(client, true); } - nbd_export_set_name(exp, NULL); - nbd_export_set_description(exp, NULL); + if (exp->name) { + nbd_export_put(exp); + g_free(exp->name); + exp->name =3D NULL; + QTAILQ_REMOVE(&exports, exp, next); + } + g_free(exp->description); + exp->description =3D NULL; nbd_export_put(exp); } diff --git a/qemu-nbd.c b/qemu-nbd.c index 2807e132396..696bd78a2e2 100644 --- a/qemu-nbd.c +++ b/qemu-nbd.c @@ -1015,10 +1015,9 @@ int main(int argc, char **argv) } } - exp =3D nbd_export_new(bs, dev_offset, fd_size, nbdflags, nbd_export_c= losed, + exp =3D nbd_export_new(bs, dev_offset, fd_size, export_name, + export_description, nbdflags, nbd_export_closed, writethrough, NULL, &error_fatal); - nbd_export_set_name(exp, export_name); - nbd_export_set_description(exp, export_description); if (device) { #if HAVE_NBD_DEVICE --=20 2.20.1 From nobody Sun May 5 02:11:02 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.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 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1547104908046576.4816532119473; Wed, 9 Jan 2019 23:21:48 -0800 (PST) Received: from localhost ([127.0.0.1]:60252 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghUef-0005t4-PI for importer@patchew.org; Thu, 10 Jan 2019 02:21:29 -0500 Received: from eggs.gnu.org ([209.51.188.92]:35151) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghUXF-0000aI-5b for qemu-devel@nongnu.org; Thu, 10 Jan 2019 02:13:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ghUXD-0001kb-Ji for qemu-devel@nongnu.org; Thu, 10 Jan 2019 02:13:48 -0500 Received: from mx1.redhat.com ([209.132.183.28]:42120) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ghUXA-0001fe-1d; Thu, 10 Jan 2019 02:13:44 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A64A17FDE7; Thu, 10 Jan 2019 07:13:40 +0000 (UTC) Received: from blue.redhat.com (ovpn-116-216.phx2.redhat.com [10.3.116.216]) by smtp.corp.redhat.com (Postfix) with ESMTP id EDC671059582; Thu, 10 Jan 2019 07:13:39 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Date: Thu, 10 Jan 2019 01:13:27 -0600 Message-Id: <20190110071330.28136-4-eblake@redhat.com> In-Reply-To: <20190110071330.28136-1-eblake@redhat.com> References: <20190110071330.28136-1-eblake@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Thu, 10 Jan 2019 07:13:40 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v2 3/6] nbd: Allow bitmap export during QMP nbd-server-add 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: Kevin Wolf , vsementsov@virtuozzo.com, qemu-block@nongnu.org, Markus Armbruster , "Dr. David Alan Gilbert" , Max Reitz , jsnow@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" With the experimental x-nbd-server-add-bitmap command, there was a window of time where an NBD client could see the export but not the associated dirty bitmap, which can cause a client that planned on using the dirty bitmap to be forced to treat the entire image as dirty as a safety fallback. Furthermore, if the QMP client successfully exports a disk but then fails to add the bitmap, it has to take on the burden of removing the export. Since we don't allow changing the exposed dirty bitmap (whether to a different bitmap, or removing advertisement of the bitmap), it is nicer to make the bitmap tied to the export at the time the export is created, with automatic failure to export if the bitmap is not available. The experimental command included an optional 'bitmap-export-name' field for remapping the name exposed over NBD to be different from the bitmap name stored on disk. However, my libvirt demo code for implementing differential backups on top of persistent bitmaps did not need to take advantage of that feature (it is instead possible to create a new temporary bitmap with the desired name, use block-dirty-bitmap-merge to merge one or more persistent bitmaps into the temporary, then associate the temporary with the NBD export, if control is needed over the exported bitmap name). Hence, I'm not copying that part of the experiment over to the stable addition. For more details on the libvirt demo, see https://www.redhat.com/archives/libvir-list/2018-October/msg01254.html, https://kvmforum2018.sched.com/event/FzuB/facilitating-incremental-backup-e= ric-blake-red-hat This patch focuses on the user interface, and reduces (but does not completely eliminate) the window where an NBD client can see the export but not the dirty bitmap. Later patches will add further cleanups now that this interface is declared stable via a single QMP command, including removing the race window. Update test 223 to use the new interface, including a demonstration that it is now easier to handle failures. Signed-off-by: Eric Blake Reviewed-by: Vladimir Sementsov-Ogievskiy --- qapi/block.json | 7 ++++++- blockdev-nbd.c | 12 +++++++++++- hmp.c | 5 +++-- tests/qemu-iotests/223 | 17 ++++++----------- tests/qemu-iotests/223.out | 5 +---- 5 files changed, 27 insertions(+), 19 deletions(-) diff --git a/qapi/block.json b/qapi/block.json index 11f01f28efe..3d70420f763 100644 --- a/qapi/block.json +++ b/qapi/block.json @@ -246,6 +246,10 @@ # # @writable: Whether clients should be able to write to the device via the # NBD connection (default false). + +# @bitmap: Also export the dirty bitmap reachable from @device, so the +# NBD client can use NBD_OPT_SET_META_CONTEXT with +# "qemu:dirty-bitmap:NAME" to inspect the bitmap. (since 4.0) # # Returns: error if the server is not running, or export with the same name # already exists. @@ -253,7 +257,8 @@ # Since: 1.3.0 ## { 'command': 'nbd-server-add', - 'data': {'device': 'str', '*name': 'str', '*writable': 'bool'} } + 'data': {'device': 'str', '*name': 'str', '*writable': 'bool', + '*bitmap': 'str' } } ## # @NbdServerRemoveMode: diff --git a/blockdev-nbd.c b/blockdev-nbd.c index f5edbc27d88..ac7e993c35f 100644 --- a/blockdev-nbd.c +++ b/blockdev-nbd.c @@ -140,7 +140,8 @@ void qmp_nbd_server_start(SocketAddressLegacy *addr, } void qmp_nbd_server_add(const char *device, bool has_name, const char *nam= e, - bool has_writable, bool writable, Error **errp) + bool has_writable, bool writable, + bool has_bitmap, const char *bitmap, Error **errp) { BlockDriverState *bs =3D NULL; BlockBackend *on_eject_blk; @@ -185,6 +186,15 @@ void qmp_nbd_server_add(const char *device, bool has_n= ame, const char *name, * our only way of accessing it is through nbd_export_find(), so we ca= n drop * the strong reference that is @exp. */ nbd_export_put(exp); + + if (has_bitmap) { + Error *err =3D NULL; + nbd_export_bitmap(exp, bitmap, bitmap, &err); + if (err) { + error_propagate(errp, err); + nbd_export_remove(exp, NBD_SERVER_REMOVE_MODE_HARD, NULL); + } + } } void qmp_nbd_server_remove(const char *name, diff --git a/hmp.c b/hmp.c index 80aa5ab504b..8da5fd8760a 100644 --- a/hmp.c +++ b/hmp.c @@ -2326,7 +2326,7 @@ void hmp_nbd_server_start(Monitor *mon, const QDict *= qdict) } qmp_nbd_server_add(info->value->device, false, NULL, - true, writable, &local_err); + true, writable, false, NULL, &local_err); if (local_err !=3D NULL) { qmp_nbd_server_stop(NULL); @@ -2347,7 +2347,8 @@ void hmp_nbd_server_add(Monitor *mon, const QDict *qd= ict) bool writable =3D qdict_get_try_bool(qdict, "writable", false); Error *local_err =3D NULL; - qmp_nbd_server_add(device, !!name, name, true, writable, &local_err); + qmp_nbd_server_add(device, !!name, name, true, writable, + false, NULL, &local_err); hmp_handle_error(mon, &local_err); } diff --git a/tests/qemu-iotests/223 b/tests/qemu-iotests/223 index f1fbb9bc1c6..1f6822f9489 100755 --- a/tests/qemu-iotests/223 +++ b/tests/qemu-iotests/223 @@ -120,21 +120,16 @@ _send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-s= tart", "arguments":{"addr":{"type":"unix", "data":{"path":"'"$TEST_DIR/nbd"'"}}}}' "return" _send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-add", - "arguments":{"device":"n"}}' "return" + "arguments":{"device":"n", "bitmap":"b"}}' "return" _send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-add", "arguments":{"device":"n"}}' "error" -_send_qemu_cmd $QEMU_HANDLE '{"execute":"x-nbd-server-add-bitmap", - "arguments":{"name":"n", "bitmap":"b"}}' "return" _send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-add", - "arguments":{"device":"n", "name":"n2"}}' "return" -_send_qemu_cmd $QEMU_HANDLE '{"execute":"x-nbd-server-add-bitmap", - "arguments":{"name":"n2", "bitmap":"b2"}}' "error" -_send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-remove", - "arguments":{"name":"n2"}}' "return" + "arguments":{"device":"n", "name":"n2", "bitmap":"b2"}}' "error" _send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-add", - "arguments":{"device":"n", "name":"n2", "writable":true}}' "return" -_send_qemu_cmd $QEMU_HANDLE '{"execute":"x-nbd-server-add-bitmap", - "arguments":{"name":"n2", "bitmap":"b2"}}' "return" + "arguments":{"device":"n", "name":"n2", "bitmap":"b3"}}' "error" +_send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-add", + "arguments":{"device":"n", "name":"n2", "writable":true, + "bitmap":"b2"}}' "return" echo echo "=3D=3D=3D Contrast normal status to large granularity dirty-bitmap = =3D=3D=3D" diff --git a/tests/qemu-iotests/223.out b/tests/qemu-iotests/223.out index 5ed2e322e19..7135bf59bb8 100644 --- a/tests/qemu-iotests/223.out +++ b/tests/qemu-iotests/223.out @@ -30,11 +30,8 @@ wrote 2097152/2097152 bytes at offset 2097152 {"return": {}} {"return": {}} {"error": {"class": "GenericError", "desc": "NBD server already has export= named 'n'"}} -{"return": {}} -{"return": {}} {"error": {"class": "GenericError", "desc": "Enabled bitmap 'b2' incompati= ble with readonly export"}} -{"return": {}} -{"return": {}} +{"error": {"class": "GenericError", "desc": "Bitmap 'b3' is not found"}} {"return": {}} =3D=3D=3D Contrast normal status to large granularity dirty-bitmap =3D=3D= =3D --=20 2.20.1 From nobody Sun May 5 02:11:02 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.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 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1547104759781707.3009026062842; Wed, 9 Jan 2019 23:19:19 -0800 (PST) Received: from localhost ([127.0.0.1]:59642 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghUcV-0003zY-C1 for importer@patchew.org; Thu, 10 Jan 2019 02:19:15 -0500 Received: from eggs.gnu.org ([209.51.188.92]:35096) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghUXC-0000TR-Ug for qemu-devel@nongnu.org; Thu, 10 Jan 2019 02:13:47 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ghUXC-0001j8-6g for qemu-devel@nongnu.org; Thu, 10 Jan 2019 02:13:46 -0500 Received: from mx1.redhat.com ([209.132.183.28]:42122) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ghUXA-0001fr-0z; Thu, 10 Jan 2019 02:13:44 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6D97B7FDF2; Thu, 10 Jan 2019 07:13:41 +0000 (UTC) Received: from blue.redhat.com (ovpn-116-216.phx2.redhat.com [10.3.116.216]) by smtp.corp.redhat.com (Postfix) with ESMTP id C98551059580; Thu, 10 Jan 2019 07:13:40 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Date: Thu, 10 Jan 2019 01:13:28 -0600 Message-Id: <20190110071330.28136-5-eblake@redhat.com> In-Reply-To: <20190110071330.28136-1-eblake@redhat.com> References: <20190110071330.28136-1-eblake@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Thu, 10 Jan 2019 07:13:41 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v2 4/6] nbd: Remove x-nbd-server-add-bitmap 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: Kevin Wolf , vsementsov@virtuozzo.com, qemu-block@nongnu.org, Markus Armbruster , Max Reitz , jsnow@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Now that nbd-server-add can do the same functionality, we no longer need the experimental separate command. Signed-off-by: Eric Blake Reviewed-by: Vladimir Sementsov-Ogievskiy --- qapi/block.json | 23 ----------------------- blockdev-nbd.c | 23 ----------------------- 2 files changed, 46 deletions(-) diff --git a/qapi/block.json b/qapi/block.json index 3d70420f763..5a79d639e8c 100644 --- a/qapi/block.json +++ b/qapi/block.json @@ -301,29 +301,6 @@ { 'command': 'nbd-server-remove', 'data': {'name': 'str', '*mode': 'NbdServerRemoveMode'} } -## -# @x-nbd-server-add-bitmap: -# -# Expose a dirty bitmap associated with the selected export. The bitmap se= arch -# starts at the device attached to the export, and includes all backing fi= les. -# The exported bitmap is then locked until the NBD export is removed. -# -# @name: Export name. -# -# @bitmap: Bitmap name to search for. -# -# @bitmap-export-name: How the bitmap will be seen by nbd clients -# (default @bitmap) -# -# Note: the client must use NBD_OPT_SET_META_CONTEXT with a query of -# "qemu:dirty-bitmap:NAME" (where NAME matches @bitmap-export-name) to acc= ess -# the exposed bitmap. -# -# Since: 3.0 -## - { 'command': 'x-nbd-server-add-bitmap', - 'data': {'name': 'str', 'bitmap': 'str', '*bitmap-export-name': 'str'}= } - ## # @nbd-server-stop: # diff --git a/blockdev-nbd.c b/blockdev-nbd.c index ac7e993c35f..003ba7d7180 100644 --- a/blockdev-nbd.c +++ b/blockdev-nbd.c @@ -228,26 +228,3 @@ void qmp_nbd_server_stop(Error **errp) nbd_server_free(nbd_server); nbd_server =3D NULL; } - -void qmp_x_nbd_server_add_bitmap(const char *name, const char *bitmap, - bool has_bitmap_export_name, - const char *bitmap_export_name, - Error **errp) -{ - NBDExport *exp; - - if (!nbd_server) { - error_setg(errp, "NBD server not running"); - return; - } - - exp =3D nbd_export_find(name); - if (exp =3D=3D NULL) { - error_setg(errp, "Export '%s' is not found", name); - return; - } - - nbd_export_bitmap(exp, bitmap, - has_bitmap_export_name ? bitmap_export_name : bitmap, - errp); -} --=20 2.20.1 From nobody Sun May 5 02:11:02 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.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 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1547104591065529.5789884737776; Wed, 9 Jan 2019 23:16:31 -0800 (PST) Received: from localhost ([127.0.0.1]:59040 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghUZp-00029g-No for importer@patchew.org; Thu, 10 Jan 2019 02:16:29 -0500 Received: from eggs.gnu.org ([209.51.188.92]:35133) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghUXE-0000YH-DH for qemu-devel@nongnu.org; Thu, 10 Jan 2019 02:13:49 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ghUXD-0001kK-9w for qemu-devel@nongnu.org; Thu, 10 Jan 2019 02:13:48 -0500 Received: from mx1.redhat.com ([209.132.183.28]:46522) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ghUXA-0001g3-22; Thu, 10 Jan 2019 02:13:44 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 3326881104; Thu, 10 Jan 2019 07:13:42 +0000 (UTC) Received: from blue.redhat.com (ovpn-116-216.phx2.redhat.com [10.3.116.216]) by smtp.corp.redhat.com (Postfix) with ESMTP id 97C0510A185B; Thu, 10 Jan 2019 07:13:41 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Date: Thu, 10 Jan 2019 01:13:29 -0600 Message-Id: <20190110071330.28136-6-eblake@redhat.com> In-Reply-To: <20190110071330.28136-1-eblake@redhat.com> References: <20190110071330.28136-1-eblake@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Thu, 10 Jan 2019 07:13:42 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v2 5/6] nbd: Merge nbd_export_bitmap into nbd_export_new 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: Kevin Wolf , vsementsov@virtuozzo.com, jsnow@redhat.com, qemu-block@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" We only have one caller that wants to export a bitmap name, which it does right after creation of the export. But there is still a brief window of time where an NBD client could see the export but not the dirty bitmap, which a robust client would have to interpret as meaning the entire image should be treated as dirty. Better is to eliminate the window entirely, by inlining nbd_export_bitmap() into nbd_export_new(), and refusing to create the bitmap in the first place if the requested bitmap can't be located. We also no longer need logic for setting a different bitmap name compared to the bitmap being exported. Signed-off-by: Eric Blake Reviewed-by: Vladimir Sementsov-Ogievskiy --- include/block/nbd.h | 9 ++--- blockdev-nbd.c | 11 +----- nbd/server.c | 87 +++++++++++++++++++++------------------------ qemu-nbd.c | 4 +-- 4 files changed, 46 insertions(+), 65 deletions(-) diff --git a/include/block/nbd.h b/include/block/nbd.h index 2f9a2aeb73c..1971b557896 100644 --- a/include/block/nbd.h +++ b/include/block/nbd.h @@ -296,9 +296,9 @@ typedef struct NBDClient NBDClient; NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset, off_t si= ze, const char *name, const char *description, - uint16_t nbdflags, void (*close)(NBDExport *), - bool writethrough, BlockBackend *on_eject_blk, - Error **errp); + const char *bitmap, uint16_t nbdflags, + void (*close)(NBDExport *), bool writethrough, + BlockBackend *on_eject_blk, Error **errp); void nbd_export_close(NBDExport *exp); void nbd_export_remove(NBDExport *exp, NbdServerRemoveMode mode, Error **e= rrp); void nbd_export_get(NBDExport *exp); @@ -319,9 +319,6 @@ void nbd_client_put(NBDClient *client); void nbd_server_start(SocketAddress *addr, const char *tls_creds, Error **errp); -void nbd_export_bitmap(NBDExport *exp, const char *bitmap, - const char *bitmap_export_name, Error **errp); - /* nbd_read * Reads @size bytes from @ioc. Returns 0 on success. */ diff --git a/blockdev-nbd.c b/blockdev-nbd.c index 003ba7d7180..0df6307be2d 100644 --- a/blockdev-nbd.c +++ b/blockdev-nbd.c @@ -175,7 +175,7 @@ void qmp_nbd_server_add(const char *device, bool has_na= me, const char *name, writable =3D false; } - exp =3D nbd_export_new(bs, 0, -1, name, NULL, + exp =3D nbd_export_new(bs, 0, -1, name, NULL, bitmap, writable ? 0 : NBD_FLAG_READ_ONLY, NULL, false, on_eject_blk, errp); if (!exp) { @@ -186,15 +186,6 @@ void qmp_nbd_server_add(const char *device, bool has_n= ame, const char *name, * our only way of accessing it is through nbd_export_find(), so we ca= n drop * the strong reference that is @exp. */ nbd_export_put(exp); - - if (has_bitmap) { - Error *err =3D NULL; - nbd_export_bitmap(exp, bitmap, bitmap, &err); - if (err) { - error_propagate(errp, err); - nbd_export_remove(exp, NBD_SERVER_REMOVE_MODE_HARD, NULL); - } - } } void qmp_nbd_server_remove(const char *name, diff --git a/nbd/server.c b/nbd/server.c index 676fb4886d0..e613594fde0 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -1457,9 +1457,9 @@ static void nbd_eject_notifier(Notifier *n, void *dat= a) NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset, off_t si= ze, const char *name, const char *description, - uint16_t nbdflags, void (*close)(NBDExport *), - bool writethrough, BlockBackend *on_eject_blk, - Error **errp) + const char *bitmap, uint16_t nbdflags, + void (*close)(NBDExport *), bool writethrough, + BlockBackend *on_eject_blk, Error **errp) { AioContext *ctx; BlockBackend *blk; @@ -1507,6 +1507,43 @@ NBDExport *nbd_export_new(BlockDriverState *bs, off_= t dev_offset, off_t size, } exp->size -=3D exp->size % BDRV_SECTOR_SIZE; + if (bitmap) { + BdrvDirtyBitmap *bm =3D NULL; + BlockDriverState *bs =3D blk_bs(blk); + + while (true) { + bm =3D bdrv_find_dirty_bitmap(bs, bitmap); + if (bm !=3D NULL || bs->backing =3D=3D NULL) { + break; + } + + bs =3D bs->backing->bs; + } + + if (bm =3D=3D NULL) { + error_setg(errp, "Bitmap '%s' is not found", bitmap); + goto fail; + } + + if ((nbdflags & NBD_FLAG_READ_ONLY) && bdrv_is_writable(bs) && + bdrv_dirty_bitmap_enabled(bm)) { + error_setg(errp, + "Enabled bitmap '%s' incompatible with readonly exp= ort", + bitmap); + goto fail; + } + + if (bdrv_dirty_bitmap_user_locked(bm)) { + error_setg(errp, "Bitmap '%s' is in use", bitmap); + goto fail; + } + + bdrv_dirty_bitmap_set_qmp_locked(bm, true); + exp->export_bitmap =3D bm; + exp->export_bitmap_context =3D g_strdup_printf("qemu:dirty-bitmap:= %s", + bitmap); + } + exp->close =3D close; exp->ctx =3D blk_get_aio_context(blk); blk_add_aio_context_notifier(blk, blk_aio_attached, blk_aio_detach, ex= p); @@ -2417,47 +2454,3 @@ void nbd_client_new(QIOChannelSocket *sioc, co =3D qemu_coroutine_create(nbd_co_client_start, client); qemu_coroutine_enter(co); } - -void nbd_export_bitmap(NBDExport *exp, const char *bitmap, - const char *bitmap_export_name, Error **errp) -{ - BdrvDirtyBitmap *bm =3D NULL; - BlockDriverState *bs =3D blk_bs(exp->blk); - - if (exp->export_bitmap) { - error_setg(errp, "Export bitmap is already set"); - return; - } - - while (true) { - bm =3D bdrv_find_dirty_bitmap(bs, bitmap); - if (bm !=3D NULL || bs->backing =3D=3D NULL) { - break; - } - - bs =3D bs->backing->bs; - } - - if (bm =3D=3D NULL) { - error_setg(errp, "Bitmap '%s' is not found", bitmap); - return; - } - - if ((exp->nbdflags & NBD_FLAG_READ_ONLY) && bdrv_is_writable(bs) && - bdrv_dirty_bitmap_enabled(bm)) { - error_setg(errp, - "Enabled bitmap '%s' incompatible with readonly export", - bitmap); - return; - } - - if (bdrv_dirty_bitmap_user_locked(bm)) { - error_setg(errp, "Bitmap '%s' is in use", bitmap); - return; - } - - bdrv_dirty_bitmap_set_qmp_locked(bm, true); - exp->export_bitmap =3D bm; - exp->export_bitmap_context =3D - g_strdup_printf("qemu:dirty-bitmap:%s", bitmap_export_name); -} diff --git a/qemu-nbd.c b/qemu-nbd.c index 696bd78a2e2..03813187846 100644 --- a/qemu-nbd.c +++ b/qemu-nbd.c @@ -1016,8 +1016,8 @@ int main(int argc, char **argv) } exp =3D nbd_export_new(bs, dev_offset, fd_size, export_name, - export_description, nbdflags, nbd_export_closed, - writethrough, NULL, &error_fatal); + export_description, NULL, nbdflags, + nbd_export_closed, writethrough, NULL, &error_fat= al); if (device) { #if HAVE_NBD_DEVICE --=20 2.20.1 From nobody Sun May 5 02:11:02 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.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 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1547104559293256.5222009889402; Wed, 9 Jan 2019 23:15:59 -0800 (PST) Received: from localhost ([127.0.0.1]:58913 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghUZ6-0001jE-10 for importer@patchew.org; Thu, 10 Jan 2019 02:15:44 -0500 Received: from eggs.gnu.org ([209.51.188.92]:35123) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ghUXD-0000WT-Rf for qemu-devel@nongnu.org; Thu, 10 Jan 2019 02:13:49 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ghUXC-0001jP-KC for qemu-devel@nongnu.org; Thu, 10 Jan 2019 02:13:47 -0500 Received: from mx1.redhat.com ([209.132.183.28]:55444) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ghUX9-0001gK-JR; Thu, 10 Jan 2019 02:13:43 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E33F73F1FF; Thu, 10 Jan 2019 07:13:42 +0000 (UTC) Received: from blue.redhat.com (ovpn-116-216.phx2.redhat.com [10.3.116.216]) by smtp.corp.redhat.com (Postfix) with ESMTP id 569F210A185B; Thu, 10 Jan 2019 07:13:42 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Date: Thu, 10 Jan 2019 01:13:30 -0600 Message-Id: <20190110071330.28136-7-eblake@redhat.com> In-Reply-To: <20190110071330.28136-1-eblake@redhat.com> References: <20190110071330.28136-1-eblake@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Thu, 10 Jan 2019 07:13:42 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v2 6/6] qemu-nbd: Add --bitmap=NAME option 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: Kevin Wolf , vsementsov@virtuozzo.com, jsnow@redhat.com, qemu-block@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Having to fire up qemu, then use QMP commands for nbd-server-start and nbd-server-add, just to expose a persistent dirty bitmap, is rather tedious. Make it possible to expose a dirty bitmap using just qemu-nbd (of course, for now this only works when qemu-nbd is visiting a BDS formatted as qcow2). Of course, any good feature also needs unit testing, so expand iotest 223 to cover it. Signed-off-by: Eric Blake --- qemu-nbd.texi | 4 ++++ qemu-nbd.c | 10 ++++++++-- tests/qemu-iotests/223 | 18 +++++++++++++++++- tests/qemu-iotests/223.out | 12 +++++++++++- 4 files changed, 40 insertions(+), 4 deletions(-) diff --git a/qemu-nbd.texi b/qemu-nbd.texi index 9a84e81eed9..96b1546006a 100644 --- a/qemu-nbd.texi +++ b/qemu-nbd.texi @@ -45,6 +45,10 @@ auto-detecting Export the disk as read-only @item -P, --partition=3D@var{num} Only expose partition @var{num} +@item -B, --bitmap=3D@var{name} +If @var{filename} has a qcow2 persistent bitmap @var{name}, expose +that bitmap via the ``qemu:dirty-bitmap:@var{name}'' context +accessible through NBD_OPT_SET_META_CONTEXT. @item -s, --snapshot Use @var{filename} as an external snapshot, create a temporary file with backing_file=3D@var{filename}, redirect the write to diff --git a/qemu-nbd.c b/qemu-nbd.c index 03813187846..26f5c08821d 100644 --- a/qemu-nbd.c +++ b/qemu-nbd.c @@ -95,6 +95,7 @@ static void usage(const char *name) "Exposing part of the image:\n" " -o, --offset=3DOFFSET offset into the image\n" " -P, --partition=3DNUM only expose partition NUM\n" +" -B, --bitmap=3DNAME expose a persistent dirty bitmap\n" "\n" "General purpose options:\n" " --object type,id=3DID,... define an object such as 'secret' for provi= ding\n" @@ -509,7 +510,7 @@ int main(int argc, char **argv) off_t fd_size; QemuOpts *sn_opts =3D NULL; const char *sn_id_or_name =3D NULL; - const char *sopt =3D "hVb:o:p:rsnP:c:dvk:e:f:tl:x:T:D:"; + const char *sopt =3D "hVb:o:p:rsnP:c:dvk:e:f:tl:x:T:D:B:"; struct option lopt[] =3D { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'V' }, @@ -519,6 +520,7 @@ int main(int argc, char **argv) { "offset", required_argument, NULL, 'o' }, { "read-only", no_argument, NULL, 'r' }, { "partition", required_argument, NULL, 'P' }, + { "bitmap", required_argument, NULL, 'B' }, { "connect", required_argument, NULL, 'c' }, { "disconnect", no_argument, NULL, 'd' }, { "snapshot", no_argument, NULL, 's' }, @@ -558,6 +560,7 @@ int main(int argc, char **argv) QDict *options =3D NULL; const char *export_name =3D ""; /* Default export name */ const char *export_description =3D NULL; + const char *bitmap =3D NULL; const char *tlscredsid =3D NULL; bool imageOpts =3D false; bool writethrough =3D true; @@ -695,6 +698,9 @@ int main(int argc, char **argv) exit(EXIT_FAILURE); } break; + case 'B': + bitmap =3D optarg; + break; case 'k': sockpath =3D optarg; if (sockpath[0] !=3D '/') { @@ -1016,7 +1022,7 @@ int main(int argc, char **argv) } exp =3D nbd_export_new(bs, dev_offset, fd_size, export_name, - export_description, NULL, nbdflags, + export_description, bitmap, nbdflags, nbd_export_closed, writethrough, NULL, &error_fat= al); if (device) { diff --git a/tests/qemu-iotests/223 b/tests/qemu-iotests/223 index 1f6822f9489..d7c4a31a181 100755 --- a/tests/qemu-iotests/223 +++ b/tests/qemu-iotests/223 @@ -25,6 +25,7 @@ status=3D1 # failure is the default! _cleanup() { + nbd_server_stop _cleanup_test_img _cleanup_qemu rm -f "$TEST_DIR/nbd" @@ -35,6 +36,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 . ./common.rc . ./common.filter . ./common.qemu +. ./common.nbd _supported_fmt qcow2 _supported_proto file # uses NBD as well @@ -153,7 +155,7 @@ $QEMU_IMG map --output=3Djson --image-opts \ "$IMG,x-dirty-bitmap=3Dqemu:dirty-bitmap:b2" | _filter_qemu_img_map echo -echo "=3D=3D=3D End NBD server =3D=3D=3D" +echo "=3D=3D=3D End qemu NBD server =3D=3D=3D" echo _send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-remove", @@ -165,6 +167,20 @@ _send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-re= move", _send_qemu_cmd $QEMU_HANDLE '{"execute":"nbd-server-stop"}' "return" _send_qemu_cmd $QEMU_HANDLE '{"execute":"quit"}' "return" +echo +echo "=3D=3D=3D Use qemu-nbd as server =3D=3D=3D" +echo + +nbd_server_start_unix_socket -r -f $IMGFMT -B b "$TEST_IMG" +IMG=3D"driver=3Dnbd,server.type=3Dunix,server.path=3D$nbd_unix_socket" +$QEMU_IMG map --output=3Djson --image-opts \ + "$IMG,x-dirty-bitmap=3Dqemu:dirty-bitmap:b" | _filter_qemu_img_map + +nbd_server_start_unix_socket -f $IMGFMT -B b2 "$TEST_IMG" +IMG=3D"driver=3Dnbd,server.type=3Dunix,server.path=3D$nbd_unix_socket" +$QEMU_IMG map --output=3Djson --image-opts \ + "$IMG,x-dirty-bitmap=3Dqemu:dirty-bitmap:b2" | _filter_qemu_img_map + # success, all done echo '*** done' rm -f $seq.full diff --git a/tests/qemu-iotests/223.out b/tests/qemu-iotests/223.out index 7135bf59bb8..ad3b2727ba8 100644 --- a/tests/qemu-iotests/223.out +++ b/tests/qemu-iotests/223.out @@ -58,11 +58,21 @@ read 2097152/2097152 bytes at offset 2097152 { "start": 1024, "length": 2096128, "depth": 0, "zero": false, "data": tru= e}, { "start": 2097152, "length": 2097152, "depth": 0, "zero": false, "data": = false}] -=3D=3D=3D End NBD server =3D=3D=3D +=3D=3D=3D End qemu NBD server =3D=3D=3D {"return": {}} {"return": {}} {"error": {"class": "GenericError", "desc": "Export 'n2' is not found"}} {"return": {}} {"return": {}} + +=3D=3D=3D Use qemu-nbd as server =3D=3D=3D + +[{ "start": 0, "length": 65536, "depth": 0, "zero": false, "data": false}, +{ "start": 65536, "length": 2031616, "depth": 0, "zero": false, "data": tr= ue}, +{ "start": 2097152, "length": 2097152, "depth": 0, "zero": false, "data": = false}] +[{ "start": 0, "length": 512, "depth": 0, "zero": false, "data": true}, +{ "start": 512, "length": 512, "depth": 0, "zero": false, "data": false}, +{ "start": 1024, "length": 2096128, "depth": 0, "zero": false, "data": tru= e}, +{ "start": 2097152, "length": 2097152, "depth": 0, "zero": false, "data": = false}] *** done --=20 2.20.1