From nobody Sun Oct 5 19:25:50 2025 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 1547007608477972.5635457262257; Tue, 8 Jan 2019 20:20:08 -0800 (PST) Received: from localhost ([127.0.0.1]:51925 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gh5Lb-0000xr-D7 for importer@patchew.org; Tue, 08 Jan 2019 23:20:07 -0500 Received: from eggs.gnu.org ([209.51.188.92]:38913) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gh5Go-0006LE-SE for qemu-devel@nongnu.org; Tue, 08 Jan 2019 23:15:13 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gh5Gm-0005gO-PH for qemu-devel@nongnu.org; Tue, 08 Jan 2019 23:15:10 -0500 Received: from mx1.redhat.com ([209.132.183.28]:39464) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gh5Gd-0005ZU-LJ; Tue, 08 Jan 2019 23:14:59 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 9912C8830F; Wed, 9 Jan 2019 04:14:58 +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 D78587D937; Wed, 9 Jan 2019 04:14:57 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Date: Tue, 8 Jan 2019 22:14:49 -0600 Message-Id: <20190109041452.31240-3-eblake@redhat.com> In-Reply-To: <20190109041452.31240-1-eblake@redhat.com> References: <20190109041452.31240-1-eblake@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Wed, 09 Jan 2019 04:14:58 +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 2/5] 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 a 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 a dirty bitmap once it is exported (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, and automatically failing to export if the bitmap is not available. Since there is working libvirt demo code that uses both the bitmap export and the ability to specify an alternative name (rather than exposing the private-use bitmap that libvirt created to merge in several persistent bitmaps when doing a differential backup), the two new parameters do not need to be marked experimental. 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 available. Update test 223 to use the new interface. Signed-off-by: Eric Blake --- qapi/block.json | 12 +++++++++++- blockdev-nbd.c | 27 ++++++++++++++++++++++++++- hmp.c | 6 ++++-- tests/qemu-iotests/223 | 11 ++++------- tests/qemu-iotests/223.out | 2 -- 5 files changed, 45 insertions(+), 13 deletions(-) diff --git a/qapi/block.json b/qapi/block.json index 11f01f28efe..4b336303d21 100644 --- a/qapi/block.json +++ b/qapi/block.json @@ -246,6 +246,15 @@ # # @writable: Whether clients should be able to write to the device via the # NBD connection (default false). + +# @bitmap: Dirty bitmap to associate with the selected export. The export +# must be read-only, and the given bitmap is locked until the +# export is removed. (since 4.0) +# +# @bitmap-export-name: How the bitmap will be seen by nbd clients +# (default @bitmap). The NBD client must use +# NBD_OPT_SET_META_CONTEXT with "qemu:dirty-bitmap:NA= ME" +# to access the exposed bitmap. (since 4.0) # # Returns: error if the server is not running, or export with the same name # already exists. @@ -253,7 +262,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', '*bitmap-export-name': 'str' } } ## # @NbdServerRemoveMode: diff --git a/blockdev-nbd.c b/blockdev-nbd.c index f5edbc27d88..cae9e802d48 100644 --- a/blockdev-nbd.c +++ b/blockdev-nbd.c @@ -140,7 +140,10 @@ 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, + bool has_bitmap_export_name, + const char *bitmap_export_name, Error **errp) { BlockDriverState *bs =3D NULL; BlockBackend *on_eject_blk; @@ -160,6 +163,17 @@ void qmp_nbd_server_add(const char *device, bool has_n= ame, const char *name, return; } + if (has_bitmap_export_name && !has_bitmap) { + error_setg(errp, "Choosing bitmap export name '%s' requires a bitm= ap", + bitmap_export_name); + return; + } + if (has_bitmap && writable) { + error_setg(errp, "Cannot export bitmap '%s' on writable export", + bitmap); + return; + } + on_eject_blk =3D blk_by_name(device); bs =3D bdrv_lookup_bs(device, device, errp); @@ -185,6 +199,17 @@ 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, + has_bitmap_export_name ? bitmap_export_name : bi= tmap, + &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..484a0000de1 100644 --- a/hmp.c +++ b/hmp.c @@ -2326,7 +2326,8 @@ 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, false, NULL, + &local_err); if (local_err !=3D NULL) { qmp_nbd_server_stop(NULL); @@ -2347,7 +2348,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, false, NULL, &local_err); hmp_handle_error(mon, &local_err); } diff --git a/tests/qemu-iotests/223 b/tests/qemu-iotests/223 index 5513dc62159..7a92c3018e2 100755 --- a/tests/qemu-iotests/223 +++ b/tests/qemu-iotests/223 @@ -120,13 +120,10 @@ _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" -_send_qemu_cmd $QEMU_HANDLE '{"execute":"x-nbd-server-add-bitmap", - "arguments":{"name":"n", "bitmap":"b"}}' "return" + "arguments":{"device":"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"}}' "return" + "arguments":{"device":"n", "name":"n2", "bitmap":"b2", + "bitmap-export-name":"b3"}}' "return" echo echo "=3D=3D=3D Contrast normal status to large granularity dirty-bitmap = =3D=3D=3D" @@ -147,7 +144,7 @@ echo IMG=3D"driver=3Dnbd,export=3Dn2,server.type=3Dunix,server.path=3D$TEST_DIR= /nbd" $QEMU_IMG map --output=3Djson --image-opts \ - "$IMG,x-dirty-bitmap=3Dqemu:dirty-bitmap:b2" | _filter_qemu_img_map + "$IMG,x-dirty-bitmap=3Dqemu:dirty-bitmap:b3" | _filter_qemu_img_map echo echo "=3D=3D=3D End NBD server =3D=3D=3D" diff --git a/tests/qemu-iotests/223.out b/tests/qemu-iotests/223.out index 99ca172fbb8..0e467981bb8 100644 --- a/tests/qemu-iotests/223.out +++ b/tests/qemu-iotests/223.out @@ -31,8 +31,6 @@ wrote 2097152/2097152 bytes at offset 2097152 {"return": {}} {"return": {}} {"return": {}} -{"return": {}} -{"return": {}} =3D=3D=3D Contrast normal status to large granularity dirty-bitmap =3D=3D= =3D --=20 2.20.1